本文目录导读:

在PHP项目中调用外部脚本并传参执行,主要有以下几种常用方法:
使用 exec() 函数
<?php
// 传参给外部脚本
$script = '/path/to/script.sh';
$param1 = 'hello';
$param2 = 'world';
// 方式1:直接拼接参数
exec("$script $param1 $param2", $output, $return_var);
// 方式2:使用 escapeshellarg() 防止注入
$safe_param1 = escapeshellarg($param1);
$safe_param2 = escapeshellarg($param2);
exec("$script $safe_param1 $safe_param2", $output, $return_var);
// 查看输出
print_r($output);
echo "返回状态:$return_var";
?>
使用 shell_exec()
<?php
$script = '/path/to/script.py';
$arg1 = '参数1';
$arg2 = '参数2';
// 获取全部输出作为字符串
$result = shell_exec("$script " . escapeshellarg($arg1) . " " . escapeshellarg($arg2));
echo $result;
?>
使用 system()
<?php
$script = '/path/to/node_script.js';
$params = ['data1', 'data2'];
// 直接输出结果
system("node $script " . implode(' ', array_map('escapeshellarg', $params)), $status);
if ($status !== 0) {
echo "脚本执行失败";
}
?>
使用 proc_open()(高级用法)
<?php
$script = '/path/to/script.php';
$args = ['--name', '张三', '--age', '25'];
// 构建命令
$cmd = "php $script " . implode(' ', array_map('escapeshellarg', $args));
$descriptorspec = [
0 => ["pipe", "r"], // 标准输入
1 => ["pipe", "w"], // 标准输出
2 => ["pipe", "w"] // 错误输出
];
$process = proc_open($cmd, $descriptorspec, $pipes);
if (is_resource($process)) {
// 关闭标准输入
fclose($pipes[0]);
// 读取输出
$output = stream_get_contents($pipes[1]);
fclose($pipes[1]);
// 读取错误
$error = stream_get_contents($pipes[2]);
fclose($pipes[2]);
// 关闭进程
$return_value = proc_close($process);
echo "输出:$output\n";
echo "错误:$error\n";
echo "返回值:$return_value\n";
}
?>
实际示例:调用不同脚本类型
调用 Shell 脚本
<?php
// shell_script.sh
// #!/bin/bash
// echo "参数1: $1, 参数2: $2"
$output = shell_exec('/path/to/shell_script.sh ' . escapeshellarg('值1') . ' ' . escapeshellarg('值2'));
echo $output;
?>
调用 Python 脚本
<?php
// python_script.py
// import sys
// print(f"参数: {sys.argv[1]}, {sys.argv[2]}")
exec("python3 /path/to/python_script.py " .
escapeshellarg('数据1') . " " .
escapeshellarg('数据2'),
$output,
$return);
echo implode("\n", $output);
?>
调用 Node.js 脚本
<?php
// node_script.js
// const args = process.argv.slice(2);
// console.log(`参数: ${args[0]}, ${args[1]}`);
$cmd = "node /path/to/node_script.js --input " . escapeshellarg('测试数据');
$result = shell_exec($cmd);
echo $result;
?>
安全最佳实践
<?php
function safeExecuteScript($scriptPath, $params = []) {
// 1. 验证脚本路径
if (!file_exists($scriptPath) || !is_executable($scriptPath)) {
throw new Exception("脚本不存在或不可执行");
}
// 2. 转义所有参数
$escapedParams = array_map('escapeshellarg', $params);
// 3. 构建命令
$cmd = $scriptPath . ' ' . implode(' ', $escapedParams);
// 4. 执行并返回结果
$output = [];
$return = 0;
exec($cmd, $output, $return);
return [
'output' => $output,
'status' => $return,
'success' => ($return === 0)
];
}
// 使用示例
try {
$result = safeExecuteScript('/path/to/script.sh', ['参数1', '参数2']);
if ($result['success']) {
echo "执行成功:" . implode("\n", $result['output']);
} else {
echo "执行失败,错误码:" . $result['status'];
}
} catch (Exception $e) {
echo "错误:" . $e->getMessage();
}
?>
注意事项
- 安全性:始终使用
escapeshellarg()或escapeshellcmd()转义参数 - 路径:使用绝对路径,或在安全的环境中设置正确的相对路径
- 权限:确保 Web 服务器用户有执行权限
- 超时:对长时间执行的脚本考虑设置超时机制
- 错误处理:始终检查返回值,处理错误输出
选择合适的函数取决于你的具体需求:
exec():需要处理输出数组时shell_exec():只需要返回字符串时system():需要直接输出结果时proc_open():需要更多控制(如环境变量、管道)时