如何在Laravel 5中注册包中的控制台命令


How to register console command from package in Laravel 5?

由于Laravel 5,我很感兴趣-如何在Laravel中注册和使用包中的控制台命令。

正如在laracast讨论https://laracasts.com/discuss/channels/tips/developing-your-packages-in-laravel-5,我创建了一个目录结构,将我的包添加到自动加载并创建一个服务提供商

<?php namespace Goodvin'EternalTree;
use Console'InstallCommand;
use Illuminate'Support'ServiceProvider;
class EternalTreeServiceProvider extends ServiceProvider
{
    public function boot()
    {
    }
    public function register()
    {
        $this->registerCommands();
    }
    protected function registerCommands()
    {
        $this->registerInstallCommand();
    }
    protected function registerInstallCommand()
    {
        $this->app->singleton('command.eternaltree.install', function($app) {
            return new InstallCommand();
        });
    }
    public function provides()
    {
        return [
            'command.eternaltree.install'
        ];
    }
}

我的InstallCommand.php脚本存储在/src/Console 中

<?php namespace Goodvin'EternalTree'Console;
use Illuminate'Console'Command;
use Symfony'Component'Console'Input'InputOption;
use Symfony'Component'Console'Input'InputArgument;
class InstallCommand extends Command {
    protected $name = 'install:eternaltree';
    protected $description = 'Command for EternalTree migration & model install.';
    public function __construct()
    {
        parent::__construct();
    }
    public function fire()
    {
        $this->info('Command eternaltree:install fire');
    }
}

我在app.php&执行转储自动加载。但是当我尝试执行时

php artisan eternaltree:install

它给我看

[InvalidArgumentException] There are no commands defined in the "eternaltree" namespace.

我认为我的命令并没有被服务提供商注册,因为php-artisan列表并没有显示我的命令。有人能向我解释一下,在Laravel 5中,在自己的包中注册命令的正确方法是什么吗?

不需要使用服务容器和单例。您可以简单地将命令类放入服务提供商的boot()部分的$this->commands([]);数组中。

比如:

$this->commands([
    Acme'MyCommand::class
]);

Laravel 5.6文档说:

/**
 * Bootstrap the application services.
 *
 * @return void
 */
public function boot()
{
    if ($this->app->runningInConsole()) {
        $this->commands([
            FooCommand::class,
            BarCommand::class,
        ]);
    }
}

将类似的If语句添加到服务提供商类中。

我找到了一个决定,很简单:

registerInstallCommand()中添加

$this->commands('command.eternaltree.install');

如果您想配置命令的调度,请在您的服务提供商中:

use Illuminate'Support'ServiceProvider;
use Illuminate'Console'Scheduling'Schedule;
class YourServiceProvider extends ServiceProvider
{
    public function boot()
    {
        $this->app->booted(function () {
            $schedule = $this->app->make(Schedule::class);
            $schedule->command('foo:bar')->everyMinute();
        });
    }
    public function register() { }
}

迟到总比不迟到好。

您试图调用eternaltree:install,但已将该命令注册为install:eternaltree

你的答案是正确的。。。但不需要CCD_ 7和CCD_。只需从register()方法中调用commands()方法,即可保持代码精简。