我试图在控制器中调用一个非常耗时的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');
}
当我在终端中运行此命令时,正在创建文件,但是当我点击路径时,它不是。有任何想法吗?
答案 0 :(得分:0)
我很确定artisan命令是异步处理的,所以它不会等待命令完成。因此,您的回答可能是空的/不正确的。
您可能需要查看Events
和Listeners
以确保您的操作顺序正确(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());