在Laravel框架之外的Artisan :: call()

Phi*_*arc 5 php cron laravel artisan

我想为Laravel 5.2创建一个cron作业

我的共享主机(在OVH上)只允许我指向文件的完整路径,而且我无法使用Laravel文档中推荐的Cron条目,即:

* * * * * php /path/to/artisan schedule:run >> /dev/null 2>&1
Run Code Online (Sandbox Code Playgroud)

因此,我必须从Laravel框架之外的.php文件中调用Artisan命令.

这是我的public/cron.php文件到目前为止的样子:

<?php

require __DIR__.'/../bootstrap/autoload.php';

use Illuminate\Support\Facades\Artisan;

Artisan::call('refresh');
Run Code Online (Sandbox Code Playgroud)

refresh 是我在我的应用程序内重新生成缩略图的命令.

通过我的浏览器访问cron.php(在本地XAMPP上测试)时,会发生以下错误:

Fatal error: Uncaught RuntimeException: A facade root has not been set. in 
C:\xampp\htdocs\site\vendor\laravel\framework\src\Illuminate\Support\Facades\Facade.php:210

Stack trace: 
#0 C:\xampp\htdocs\site\public\cron.php(7): Illuminate\Support\Facades\Facade::__callStatic('call', Array) 
#1 {main} thrown in C:\xampp\htdocs\site\vendor\laravel\framework\src\Illuminate\Support\Facades\Facade.php on line 210
Run Code Online (Sandbox Code Playgroud)

我也尝试启动应用程序,但它没有任何区别

$app = require_once __DIR__.'/../bootstrap/app.php';
$app->boot();
Run Code Online (Sandbox Code Playgroud)

为了避免使用Artisan Facade,我尝试直接调用底层内核类:

use Illuminate\Contracts\Console\Kernel;

$kernel = new Kernel;
$kernel->call('refresh');
Run Code Online (Sandbox Code Playgroud)

但这回归:

Uncaught Error: Cannot instantiate interface Illuminate\Contracts\Console\Kernel
Run Code Online (Sandbox Code Playgroud)

编辑:这是OVH cron界面的截图.cron任务由OVH定制,只允许指向文件的完整路径uri - 哪个文件将执行我的artisan命令.我的问题是,我应该在这个文件中放什么,它应该是PHP文件还是CMD?

OVH cron接口

Arc*_*las 9

您要做的是从脚本中运行特定的Artisan命令.

您可以通过复制artisan.php并强制输入到您想要的内容来实现此目的:

#!/usr/bin/env php
<?php

require __DIR__.'/bootstrap/autoload.php';

$app = require_once __DIR__.'/bootstrap/app.php';

$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);

$status = $kernel->handle(
    $input = new Symfony\Component\Console\Input\ArrayInput(['command' => 'refresh']),
    new Symfony\Component\Console\Output\ConsoleOutput
);

$kernel->terminate($input, $status);

exit($status);
Run Code Online (Sandbox Code Playgroud)

如果你将这个脚本与artisan.php进行比较,你会看到我只是强制传递给$kernel->handle()方法的输入.它不再从CLI读取输入,它将这些参数作为数组.有关更多详细信息,请参阅Symfony控制台组件文档.

如果需要将参数传递给脚本,只需相应地设置输入:

$input = new Symfony\Component\Console\Input\ArrayInput([
    'command' => 'refresh',
    'arg_foo' => 'foo',
    '--option_bar' => 42
]);

$status = $kernel->handle(
    $input,
    new Symfony\Component\Console\Output\ConsoleOutput
);
Run Code Online (Sandbox Code Playgroud)

现在,您可以将此脚本放在您想要的位置,不需要通过浏览器通过Web访问(顺便说一句,它不应该).

如果你把它放在OVH主机的根目录上,我的意思是不在www中,你只需要填写表格非常简单:

OVH共享主机Cronjob  - 第1步

如果你希望你的脚本是通过网络(这并不建议用一个明显的安全原因,但仍然)访问,把它放在你的www目录,改变路径bootstrap/autoload.php,并bootstrap/app.php给你的脚本的名称是不容易猜到.

在OVH管理器的表单中,不要忘记www/在脚本路径的开头添加.

php script_name当您选择PHP版本时,无需指定,因为管理器会为您处理它.只需键入PHP将执行的脚本的路径.