Laravel 10 Stub类名大小写转换失效及命名重复问题解决
Laravel 10 Stub模板问题解决方案
一、Stub中类名格式转换(Str::ucfirst未生效)
Laravel默认Stub替换逻辑不会直接解析Str::ucfirst这类方法,需要通过自定义替换规则提前处理格式:
- (可选)发布默认Stub文件到项目目录,方便修改:
php artisan stub:publish
- 在
App\Providers\AppServiceProvider的boot方法中注册自定义替换器,以控制器生成命令为例:
use Illuminate\Console\GeneratorCommand; use Illuminate\Support\Str; public function boot() { $this->app->afterResolving(GeneratorCommand::class, function ($command) { $className = $command->argument('name'); $command->addReplacements([ '{{ classUcfirst }}' => Str::ucfirst($className), '{{ classLower }}' => Str::lower($className), '{{ classUpper }}' => Str::upper($className), ]); }); }
- 修改对应的Stub文件(如
stubs/controller.plain.stub),使用自定义占位符:
<?php namespace {{ namespace }}; use Illuminate\Routing\Controller; class {{ class }} extends Controller { protected $modelClass = '{{ classUcfirst }}'; protected $modelLower = '{{ classLower }}'; protected $modelUpper = '{{ classUpper }}'; }
执行生成命令时,替换器会自动处理这些占位符,无需在Stub内直接调用Str方法。
二、生成控制器时重复命名(ProductControllerController)
问题根源是--type=plain对应的Stub文件与make:controller命令的自动后缀逻辑冲突:命令会给传入名称自动添加Controller,而Stub内的类名占位符也默认包含该后缀,导致重复。
解决方法1:修改Stub与替换规则(推荐)
- 打开发布后的
stubs/controller.plain.stub,将类名占位符改为自定义标识:
class {{ baseClass }} extends Controller
- 在
App\Providers\AppServiceProvider中添加替换规则,修正重复后缀:
use Illuminate\Console\Commands\MakeControllerCommand; use Illuminate\Support\Str; public function boot() { $this->app->afterResolving(MakeControllerCommand::class, function ($command) { $inputName = $command->argument('name'); // 去除命令自动添加的重复后缀,保留正确命名 $baseName = Str::replaceLast('Controller', '', $inputName); $command->addReplacements([ '{{ baseClass }}' => $baseName . 'Controller', ]); }); }
解决方法2:简化命令输入(最快捷)
执行生成命令时,传入不带Controller后缀的名称:
php artisan make:controller --type=plain Product
命令会自动添加后缀,最终生成ProductController。
解决方法3:自定义命令(适合复杂场景)
创建自定义控制器生成命令,重写命名逻辑:
<?php namespace App\Console\Commands; use Illuminate\Routing\Console\ControllerMakeCommand; use Illuminate\Support\Str; class CustomControllerMakeCommand extends ControllerMakeCommand { protected function getNameInput() { $name = trim($this->argument('name')); // 若输入已包含Controller后缀,不再重复添加 return Str::endsWith($name, 'Controller') ? $name : $name . 'Controller'; } }
在App\Console\Kernel.php中注册该命令,替换默认控制器生成命令:
protected $commands = [ \App\Console\Commands\CustomControllerMakeCommand::class, ];
内容的提问来源于stack exchange,提问作者mstdmstd
相关产品推荐
相关产品推荐

