简体   繁体   English

在后台执行 Laravel/Symfony/Artisan 命令

[英]Execute Laravel/Symfony/Artisan Command in Background

I need to execute a Laravel long running process in the background for consuming the Twitter Streaming API. Effectively the php artisan CLI command I need to run is我需要在后台执行一个 Laravel 长时间运行的进程以使用 Twitter Streaming API。实际上,我需要运行的 php artisan CLI 命令是

nohup php artisan startStreaming > /dev/null 2>&1 &

If I run that myself in the command line it works perfectly.如果我自己在命令行中运行它,它会完美运行。

The idea is that I can click a button on the website which kicks off the stream by executing the long running artisan command which starts streaming (needs to run in the background because the Twitter Streaming connection is never ending).我的想法是,我可以单击网站上的一个按钮,通过执行开始流式传输的长时间运行的 artisan 命令来启动 stream(需要在后台运行,因为 Twitter 流式传输连接永无止境)。 Going via the command line works fine.通过命令行工作正常。

Calling the command programatically however doesn't work.但是,以编程方式调用命令不起作用。 I've tried calling it silently via callSilent() from another command as well as trying to use Symfony\Component\Process\Process to run the artisan command or run a shell script which runs the above command but I can't figure it out.我尝试通过另一个命令的 callSilent() 静默调用它,并尝试使用 Symfony\Component\Process\Process 运行 artisan 命令或运行运行上述命令的 shell 脚本,但我无法弄清楚.

Update If I queue the command which opens the stream connection, it results in a Process Timeout for the queue worker更新如果我对打开 stream 连接的命令进行排队,它会导致队列工作者的进程超时

I effectively need a way to run the above command from a PHP class/script but where the PHP script does not wait for the completion/output of that command.我实际上需要一种方法来从 PHP 类/脚本运行上述命令,但 PHP 脚本不等待该命令的完成/输出。

Help much appreciated非常感谢帮助

The Symfony Process Component by default will execute the supplied command within the current working directory, getcwd() .默认情况下,Symfony 进程组件将在当前工作目录getcwd()执行提供的命令。

The value returned by getcwd() will not be the Laravel install directory (the directory that contains artisan), so the command will most likely returning a artisan: command not found message. getcwd()返回的值将不是 Laravel 安装目录(包含 artisan 的目录),因此该命令很可能会返回artisan: command not found消息。

It isn't mentioned in the Process Component documentation but if you take a look at theclass file , we can see that the construct allows us to provide a directory as the second parameter. Process Component 文档中没有提到它,但是如果您查看类文件,我们可以看到该构造允许我们提供一个目录作为第二个参数。

public function __construct(
    $commandline, 
    $cwd = null, 
    array $env = null, 
    $input = null, 
    $timeout = 60, array 
    $options = array())

You could execute your desired command asynchronously by supplying the second parameter when you initialise the class:您可以通过在初始化类时提供第二个参数来异步执行所需的命令:

use Symfony\Component\Process\Process;

$process = new Process('php artisan startStreaming > /dev/null 2>&1 &', 'path/to/artisan'); 
$process->start();

I had a same problem and I solved this with pure php and use proc_open function.我遇到了同样的问题,我用纯 php 解决了这个问题,并使用 proc_open function。

My code:我的代码:

$descriptionProcOpen = [
    ["pipe", "r"],
    ["pipe", "r"],
    ["pipe", "r"]
];

proc_open("php " . base_path() . "/artisan your:command {$argument}", $descriptionProcOpen, $pipes);

如何通过 Laravel 内置队列对命令的执行进行排队?

$this->callSilently('mail:send', [
    'user' => 1, '--queue' => 'default'
]);

https://laravel.com/docs/9.x/artisan#calling-commands-from-other-commands https://laravel.com/docs/9.x/artisan#calling-commands-from-other-commands

simple:)简单的:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM