How to Use Stub Customisation in Laravel

Bhushan Gaikwad
3 min readOct 15, 2021

Laravel 7 came with a new feature, stub customisation. Stub customisation gives the ability to modify the stub files that are used when creating classes such as controllers and tests with the artisan make command. In this guide I will try to give an overview of the stubs that can be customised, and describe two use cases.

Let’s see what happens when we execute the command to enable customisation:

php artisan stub:publish

You will see the “Stubs published successfully.” message, and a new folder stubs becomes visible in the root of your project, containing files that are customisable.

The following list shows all the stubs, with the accompanying command:

controller.api.stub         
php artisan make:controller {ControllerName} --api
controller.invokable.stub
php artisan make:controller {ControllerName} --invokable
controller.model.api.stub
php artisan make:controller {ControllerName} --model={ModelName} --api
controller.model.stub
php artisan make:controller {ControllerName} --model={ModelName}
controller.nested.api.stub
php artisan make:controller {ControllerName} --parent={ParentModelName} --model={ModelName} --api
controller.nested.stub
php artisan make:controller {ControllerName} --parent={ParentModelName} --model={ModelName}
controller.plain.stub
php artisan make:controller {ControllerName}
controller.stub
php artisan make:controller {ControllerName} --resource
job.queued.stub
php artisan make:job {JobName}
job.stub
php artisan make:job {JobName} --sync
migration.create.stub
php artisan make:migration {migration_name} --create={table_name}
migration.stub
php artisan make:migration {migration_name}
migration.update.stub
php artisan make:migration {migration_name} --table={table_name}
model.pivot.stub
php artisan make:model {ModelName} --pivot
model.stub
php artisan make:model {ModelName}
test.stub
php artisan make:test {TestName}
test.unit.stub
php artisan make:test {TestName} --unit

All these stubs contain the basic content that is used to generate the files that are created with the artisan make command. After publishing these stubs, you have the ability to edit their content.

For this guide, we will add type hinting and declare strict type to API controllers by default, and a default property to models as well.

Add type hinting and declare strict type to API controllers

Type hinting (in combination with clear function names and git blame) can render doc blocks obsolete in many cases.

We can apply this code style to our controllers, by adding return type declarations and function argument types to each method in stubs/controller.api.stub.

After adding declare(strict_types=1);and use Illuminate\Http\Response;, the int type hint to the occurrences of $id, and Response as return type, the file will look like this:

NOTE: If you use int type hinting then route model binding feature wont be available.

<?phpdeclare(strict_types=1);namespace {{ namespace }};use {{ rootNamespace }}Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
class {{ class }} extends Controller
{
public function index(): Response
{
//
}
public function store(Request $request): Response
{
//
}
public function show(int $id): Response
{
//
}
public function update(Request $request, int $id): Response
{
//
}
public function destroy(int $id): Response
{
//
}
}

Now, after we run:

php artisan make:controller API/PostController --api

you will see the result of our customised controller in app/Http/Controllers/API/PostController.php, containing the type hints and strict types enabled.

Add a default property to models

In most models I create, I like to define the attributes that are mass assignable, by adding the $guarded property to the model.

Let’s add this by default by customising model.stub:

<?phpdeclare(strict_types=1);namespace {{ namespace }};use Illuminate\Database\Eloquent\Model;class {{ class }} extends Model
{
protected $guarded = [];
}

When we create a model, by running:

php artisan make:model Post

the model Post will contain the $guarded property.

NOTE: I personally, never use any user input without validation so I always opt for $guardedempty. If you don’t use user inputs without validation please use $fillableproperty instead.

I share lot of cool tips and tricks regarding PHP, Laravel, Javascript, Vuejs, Nuxtjs, Reactjs, databases, workflows, productivity etc etc.https://twitter.com/rckstrbhushanhttps://www.linkedin.com/in/rckstrbhushanhttps://github.com/bhushanTake care and stay safe. Cheers 🥂

--

--