从 CLI 和代码内调用时如何捕获 Artisan 命令名称?

How to capture an Artisan command name when calling from both CLI and within code?

目标:执行特定命令时 - 通过我手动 运行 通过应用程序服务器的 CLI and/or 通过应用程序代码本身 - 登录到 MySQL Db Artisan命令的名称,运行花费的时间等

我的方法:创建一个抽象 LogCommandClass 扩展 Command 并实现一个 LogCommandInterface,其中包含一个方法 LogCommandToDb()。然后,让 'desired-to-be-logged' Artisan 命令 类 扩展 LogCommandClass.

问题:只有当我在我们的服务器上通过 CLI 实际输入命令时(例如 php artisan some-command),命令才会记录到 Db。通过 Artisan::call('some-command') 在代码中调用的命令 不会 被记录,但它们也需要被记录!

我唯一剩下的方法是在代码中将 Artisan::call('some-command') 的所有实例替换为

$string ="cd ".base_path(). " && php artisan some-command";
shell_exec($string);

但这似乎并不理想...


LogCommandClass.php

abstract class LogCommandClass extends Command implements LogCommandInterface {

    protected $commName, $startTime, $endTime;

    /**
    * @return void
    */
    public function __construct()
    {
        parent::__construct();
        $this->startTime = (new DateTime())->getTimestamp();
    }

    /**
    * @return void
    */
    public function __destruct()
    {
        if (Arr::get(request()->server(), 'argv.1')  == $this->getName()) {
            $this->LogCommandToDb();
        }
    }

    public function LogCommandToDb() {
        
        $this->endTime = (new DateTime())->getTimestamp();
        $diff = $this->endTime - $this->startTime;

        $comm = new CommandLog;
        $comm->LogCommand($this->getName(), $diff);
    }
}

LogCommandInterface.php

interface LogCommandInterface 
{
    public function LogCommandToDb();
}

SomeCommandClass.php

class SomeCommandClass extends LogCommandClass {

/**
 * The console command name.
 *
 * @var string
 */
protected $name = 'some-command';

/**
 * The console command description.
 *
 * @var string
 */
protected $description = 'A command that should be logged to Db.';

/**
 * Create a new command instance.
 *
 * @return void
 */
public function __construct() {
    parent::__construct();
}

/**
 * Execute the console command.
 *
 * @return mixed
 */
public function handle() {
    //do something
}

CommandLog.php

class CommandLog extends Model {

    protected $table = 'CommandLog';
    public $timestamps = true;

    public function LogCommand($name, $time)
    {
        $this->commandName = $name;
        $this->timeElapsed = $time;
        $this->save();
    }
}

每次命令 运行 laravel dispatch Artisan events,

记录事件,我只是试一试,我都得到了。

在命令的不同阶段 运行ning 三种类型之一的 event 是分派。您可以设置一个监听器等待一个。

首先,创建监听器

php artisan make:listener CommandStartingLoggin --event=CommandStarting

这将在 app/Listeners 中创建一个 class CommandStartingLoggin,在这种情况下命令开始时将调用 class。 但首先,为此您需要让 laravel 知道这一点,在提供商的文件夹中,您将在 listen 数组中看到 EventServiceProvider 添加条目:

\Illuminate\Console\Events\CommandStarting::class => [
    \App\Listeners\CommandStartingLoggin::class,
],

最后在app/Listeners/CommandStartingLoggin你会看到一个handle方法,你可以在那里登录。