Laravel - 调用Artisan命令并等待结果

时间:2017-02-17 12:57:53

标签: laravel artisan

我试图在控制器中调用一个非常耗时的Artisan命令(它在20-90秒执行),但我有两个问题。首先,似乎命令根本不执行(如果我返回输出它只返回" 0")。

其次,另一部分(返回文件)不等待命令执行(但它可以与第一部分相关)。这是我的代码:

public function returnZip()
{
    // just a failsafe, in case if scheduled command did not created the file yet
    if( ! file_exists( storage_path( '/app/exports/' . date('Y_m_d') . '.zip' ) ) ){
        Artisan::call('maximus:export');
    }

    return response()->file( storage_path( '/app/exports/' . date('Y_m_d') . '.zip' ) );
}

如何从路由/控制器正确执行Artisan命令并等待它完成它的任务?

编辑

我尝试再调试一下这个问题,发现从路由/控制器调用时根本没有执行该命令。

试过这个:

Route::get('/test', function(){
    Artisan::call('maximus:export');
    return ['ok'];
});

我的命令应该创建一个文件:

public function handle()
{
    exec('touch /some/path/storage/app/exports/test');
 }

当我在终端中运行此命令时,正在创建文件,但是当我点击路径时,它不是。有任何想法吗?

3 个答案:

答案 0 :(得分:0)

我很确定artisan命令是异步处理的,所以它不会等待命令完成。因此,您的回答可能是空的/不正确的。

您可能需要查看EventsListeners以确保您的操作顺序正确(https://laravel.com/docs/5.4/events)。

例如,在maximus:export命令中,您可以在创建文件后立即触发事件。

实施例

创建一个名为ZipCreated的事件和一个名为SendZip的侦听器。然后在你的工匠命令处理程序中调用事件:

event(new ZipCreated($file));

然后将其链接到EventServiceProvider.php

中的听众
protected $listen = [
    Events\Repository\ZipCreated::class => [
        Listeners\Repository\SendZip::class,
    ],
];

这种方式ZipCreated将为SendZip提供压缩文件(或文件路径,如果需要),SendZip可以处理将文件返回给用户。

现在无论何时运行该命令,文件的创建和响应的处理将始终按正确的顺序进行。

答案 1 :(得分:0)

  

如果我返回输出,它只返回" 0"

让我指出,以防call方法没有返回命令的输出,但是退出代码(" 0"意味着成功)。相反,Artisan::output()将返回输出。

我说检查日志以查看正在进行的操作,并检查您实际上是use Artisan门面。否则,尝试调试器或者插入信息性dd()语句;)(入口点为Illuminate\Foundation\Console\Kernel::call)。

答案 2 :(得分:-1)

尝试: dd(Artisan :: output());