在Laravel应用里,通过PHP调用并管理外部进程是常见需求,例如执行系统命令、调用脚本或对接命令行工具。Laravel提供了Process门面来简化这类操作,但实际业务中我们通常希望有一层辅助函数,统一处理超时、错误处理和结果解析。

Laravel Process基础
Laravel的Process门面位于IlluminateSupportFacadesProcess,它能以流畅的接口启动外部进程并获取输出。最基本的使用方式如下:
<?php
use IlluminateSupportFacadesProcess;
$result = Process::run('ls -la');
if ($result->successful()) {
// 进程成功,输出在 $result->output()
echo $result->output();
} else {
// 失败信息在 $result->errorOutput()
echo $result->errorOutput();
}
为什么需要进程辅助函数
直接在业务代码里写Process::run会有几个问题:超时设置分散、失败重试逻辑重复、输出解析不统一。我们可以封装辅助函数,让调用方只关心命令和参数。
辅助函数设计目标
- 支持命令数组,避免shell注入
- 统一设置超时时间
- 可选失败重试
- 返回结构化结果
实现Process进程辅助函数
下面给出一个简单的辅助函数示例,放在app/Support/process_helper.php中,并在composer.json里自动加载。
<?php
use IlluminateSupportFacadesProcess;
if (!function_exists('run_process')) {
/**
* 运行外部进程并返回结果数组
*
* @param array $command 命令及参数
* @param int $timeout 超时秒数
* @param int $retry 失败重试次数
* @return array
*/
function run_process(array $command, int $timeout = 60, int $retry = 0): array
{
$attempt = 0;
$lastError = '';
do {
$result = Process::timeout($timeout)->run($command);
if ($result->successful()) {
return [
'success' => true,
'output' => $result->output(),
'error' => '',
];
}
$lastError = $result->errorOutput();
$attempt++;
} while ($attempt <= $retry);
return [
'success' => false,
'output' => '',
'error' => $lastError,
];
}
}
在Laravel中使用辅助函数
注册自动加载后,在控制器或服务里直接调用即可:
<?php
$resp = run_process(['php', 'artisan', 'queue:work', '--once'], 30, 2);
if ($resp['success']) {
// 处理标准输出
logger()->info($resp['output']);
} else {
// 记录错误
logger()->error($resp['error']);
}
注意事项
使用Process管理外部进程时,应注意以下点:
| 项目 | 说明 |
|---|---|
| 命令格式 | 用数组传命令,不要拼字符串,防止shell注入 |
| 超时 | 默认无超时,必须显式设置timeout |
| 权限 | Web进程用户要有执行命令的权限 |
小结
通过PHP封装Process辅助函数,可以让Laravel的外部进程管理更一致、可维护。把超时、重试和输出处理收口到辅助层,业务代码更干净,也更容易测试。