在 ThinkPHP 中实现一个 POST 请求,通过异步执行命令来启动一个命令行脚本,并让该脚本执行一个 cURL 请求,同时设置执行时间无限制,可以按照以下步骤进行。
1. 通过 POST 请求接收数据
假设你已经有了一个处理 POST 请求的接口。可以使用 ThinkPHP 的 Request
类来接收数据:
php
// 控制器方法,接收 POST 请求
public function executeCurl()
{
// 接收 POST 数据
$url = input('post.url'); // 获取传递的 URL 参数
$cmd = 'php ' . ROOT_PATH . 'public/command/curl_script.php ' . escapeshellarg($url);
// 异步执行命令
$this->executeAsyncCommand($cmd);
return json(['status' => 'success', 'message' => 'Command started']);
}
2. 创建命令行脚本(curl_script.php)
在项目的 public/command
目录下创建一个 PHP 脚本(curl_script.php
),该脚本负责执行 cURL 请求,并设置无限制执行时间。
php
<?php
// 获取命令行传递的参数(URL)
if ($argc < 2) {
echo "Usage: php curl_script.php <url>\n";
exit(1);
}
$url = $argv[1];
// 初始化 cURL 请求
$ch = curl_init();
// 设置 cURL 选项
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 0); // 设置超时时间为 0,表示不超时
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 如果有跳转,跟随跳转
// 执行 cURL 请求
$response = curl_exec($ch);
// 检查是否出错
if ($response === false) {
echo 'Curl error: ' . curl_error($ch);
} else {
echo 'Response: ' . $response;
}
// 关闭 cURL 资源
curl_close($ch);
3. 异步执行命令
在 ThinkPHP 控制器中,使用异步命令执行。你可以通过 shell_exec()
或 exec()
来启动命令。为了确保命令不会阻塞主线程,可以加上 &
来让它在后台执行。
php
// 执行异步命令的方法
private function executeAsyncCommand($cmd)
{
// Windows 系统异步执行
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
pclose(popen('start /B ' . $cmd, 'r'));
} else {
// Linux/Unix/Mac 系统异步执行
exec($cmd . " > /dev/null 2>&1 &");
}
}
4. 启动异步命令
当 POST 请求发送到 executeCurl
方法时,会启动一个新的进程来执行 cURL 请求,且该命令会在后台执行。这样就避免了阻塞当前请求。
5. 设置执行时间无限制
在上面的 curl_script.php
脚本中,curl_setopt($ch, CURLOPT_TIMEOUT, 0);
设置了请求超时时间为 0,表示不限制执行时间。这样可以确保 cURL 请求会一直执行,直到它自己完成或被外部终止。
6. 完整示例
控制器:
php
<?php
namespace app\index\controller;
use think\Request;
class CommandController
{
// 执行 curl 请求并返回异步处理
public function executeCurl(Request $request)
{
// 获取 POST 请求中的 URL
$url = $request->post('url');
// 命令行脚本的路径
$cmd = 'php ' . ROOT_PATH . 'public/command/curl_script.php ' . escapeshellarg($url);
// 异步执行命令
$this->executeAsyncCommand($cmd);
// 返回响应
return json(['status' => 'success', 'message' => 'Command started']);
}
// 异步执行命令
private function executeAsyncCommand($cmd)
{
// Windows 系统异步执行
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
pclose(popen('start /B ' . $cmd, 'r'));
} else {
// Linux/Unix/Mac 系统异步执行
exec($cmd . " > /dev/null 2>&1 &");
}
}
}
curl_script.php:
php
<?php
// 获取命令行传递的 URL 参数
if ($argc < 2) {
echo "Usage: php curl_script.php <url>\n";
exit(1);
}
$url = $argv[1];
// 初始化 cURL 请求
$ch = curl_init();
// 设置 cURL 选项
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 0); // 设置超时时间为 0,表示不超时
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 如果有跳转,跟随跳转
// 执行 cURL 请求
$response = curl_exec($ch);
// 检查是否出错
if ($response === false) {
echo 'Curl error: ' . curl_error($ch);
} else {
echo 'Response: ' . $response;
}
// 关闭 cURL 资源
curl_close($ch);
总结
- 使用 ThinkPHP 控制器接收 POST 请求中的 URL。
- 创建一个 PHP 脚本来执行 cURL 请求,并设置超时时间为无限制。
- 使用
exec()
或popen()
来异步执行 PHP 命令,确保请求不阻塞。
通过这种方式,你可以在 ThinkPHP 中实现一个异步执行 cURL 请求的功能,并且设置执行时间为无限制。