php Laravel)如何从控制器注册一个调度

q8l4jmvw  于 2023-09-29  发布在  PHP
关注(0)|答案(4)|浏览(133)

我想在HelloController中接收一个GET请求,并根据请求的内容执行一个预定的进程(HelloWorldCommand),但我在理解如何做到这一点时遇到了麻烦。
PHP 8.2.7 Laravel Framework 10.25.0
在以下情况下,GET请求工作并且没有输出错误,但是不执行调度。我该怎么办?
HelloController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Artisan;
use App\Console\Commands\HelloWorldCommand;

use Illuminate\Http\Request;

class HelloController extends Controller
{
    //
  public function index()
  {
    $output = '';
    $variableValue = 'SampleValue';
    Artisan::call('command:hello', ['variable' => $variableValue, '--quiet'=>true], $output);

    var_dump($output);

    return view('hello');
  }
}

HelloWorldCommand.php

class HelloWorldCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'command:hello {variable}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description';

    /**
     * Execute the console command.
     */
    public function handle()
    {
        $v = $this->argument('variable');
        //

        $schedule = app(Schedule::class);
        $schedule->call(function () {
             logger("log {$v}");
        })->everyMinute();

        logger('test');

        return 0;
    }
}

我期望每分钟都将它写入日志文件,但实现没有按计划进行处理。

eufgjt7s

eufgjt7s1#

为什么它不工作的根本问题是,运行调度程序的crontab永远不会知道您的请求上下文特定的调度添加,并且您的添加只是临时的,因为HelloWorldCommand::handle()中的处理行只存在于您的请求完成之前。
所以基本上,你想做的是不可能的。
您可能应该研究一下排队作业,这是您可以实现类似实现的方法。

zbdgwd5y

zbdgwd5y2#

看起来你想从GET请求中触发一个Laravel Artisan命令,并定期运行该命令。您面临的问题是计划的进程没有按预期运行。要解决这个问题,您需要在代码中进行一些调整。

public function handle()
{
    $v = $this->argument('variable');

    $schedule = app(Schedule::class);
    $schedule->call(function () use ($v) {
        logger("log {$v}");
    })->everyMinute();

    logger('test');
}

在您的HelloController.php中,您可以像已经在做的那样触发该命令。确保命令名与您在HelloWorldCommand的$signature属性中定义的名称相匹配。--quiet选项对于您的用例是不必要的。下面是更新后的index方法:

public function index(Request $request)
{
    $variableValue = $request->input('variable', 'SampleValue');
    Artisan::call('command:hello', ['variable' => $variableValue]);

    return view('hello');
}

然后运行命令

* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1

希望这对你有帮助

mnemlml8

mnemlml83#

无法从控制器调用调度,而是从App\Console\Kernel.php文件调用:

<?php

namespace App\Console;

use Illuminate\Console\Scheduling\Schedule;
use App\Console\Commands\HelloWorldCommand;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

class Kernel extends ConsoleKernel
{
    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
        $schedule->command('Your Command')->everyMinute();
    }

    /**
     * Register the commands for the application.
     *
     * @return void
     */
    protected function commands()
    {
        $this->load(__DIR__.'/Commands');

        require base_path('routes/console.php');
    }
}
7eumitmz

7eumitmz4#

创建一个函数来执行你想要的工作,并在你的控制器中递归地调用它。

function schedule($input,$delay_time = 60 ){
// Whatever you want to do with $input here.
sleep($delay_time);
schedule($delay_time);
}

schedule($_GET['request']);

此函数将每60秒运行一次。希望我已经得到了你想要的。英语是我的第二语言。

相关问题