环境说明:
操作系统:windows10
IDE:phpstorm
开发语言:php7.4
框架:thinkphp5.1
测试环境:linux+windows均测试通过。
初级方法:
function longRunningTask()
{
$root_path = Tools::get_root_path();
$scriptPath = $root_path . 'public/LongTaskRunner.php';
// 定义命令行指令,并以后台方式运行(Linux)
$command = 'php ' . escapeshellarg($scriptPath) . ' > /dev/null 2>&1 &';
// 使用 exec 执行命令并立即返回
$output = [];
$returnCode = 0;
exec($command, $output, $returnCode);
//执行结果
Tools::log_to_write_txt([$root_path . 'runtime/log/exec_debug.log', "Command: $command\nReturn Code: $returnCode\nOutput: " . print_r($output, true)]);
return json(Tools::set_ok('任务已启动,正在后台运行。'));
}
然后在目标文件夹新建LongTaskRunner.php文件即可。
这是原始方法,只能执行脚本文件。
如果要执行类则需要以下高阶方法。
进阶方法:
使用自定义命令。
步骤:
- 编写自定义命令类
- 到command.php类中注册
- 控制台测试
自定义命令类示例:
<?php
namespace app\command;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\console\input\Argument;
use think\console\input\Option;
class TestCommand extends Command
{
/**
* desc:这个方法用于定义命令的基本结构,包括名称、参数、选项以及描述。
*
*/
protected function configure()
{
//命令名
$this->setName('hello')
//位置参数,OPTIONAL可选 写法如:php think hello 1(类似name=1)
->addArgument('name', Argument::OPTIONAL, "your name")
//参数选项名,使用时使用--符号,VALUE_REQUIRED必填,
//选项支持更灵活的命名方式:
//短格式:一个字母,如 -c
//命名参数,写法如:php think hello --file_id=1(写明了参数名和值,参数名file_id不可省略)
//长格式:多个单词,用短横线或下划线分隔,如 --city-name 或 --city_name
->addOption('city', null, Option::VALUE_REQUIRED, 'city name')
->setDescription('Say Hello');
}
/**
* desc:这是命令的核心逻辑部分,当运行 hello 命令时,此方法会被调用。
*/
protected function execute(Input $input, Output $output)
{
$name = trim($input->getArgument('name'));
$name = $name ?: 'hello world';
//判断用户是否提供了 --city 选项。如果有,做什么;如果没有,做什么。
if ($input->hasOption('city')) {
$city = PHP_EOL . 'From ' . $input->getOption('city');
} else {
$city = '';
}
//向终端输出
$output->writeln("Hello," . $name . '!' . $city);
}
}
说明:
这是一个自定义命令类,继承了think\console\Command类。
名称空间:目录自定义,命名空间跟随目录即可。
在configure方法中编写命令。
在execute方法中编写命令要执行的业务逻辑。
$this->writeln()方法是向控制台输出信息。
日志可以自己另外加上。
END