You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP中shell_exec执行命令时如何正确传递带换行的字符串参数?

问题场景

需要通过PHP执行node.js文件,预期命令行执行效果如下:

C:\proj> node main.js text="This is some text.
>> some more text in next line"

当前编写的PHP脚本:

shell_exec('node C:\proj\main.js text="This is some text. \n some more text in next line"');

实际运行时main.js仅能接收到text = this is some text.的内容,换行后的剩余字符串全部被截断丢失。已尝试以下写法均未生效:

  • \n
  • `n
  • >>
  • PHP_EOL
  • ^
  • ^\n
问题原因

Windows cmd的双引号参数解析规则和类Unix shell存在差异:手动拼接的转义换行不会被cmd识别为有效续行标记,未正确转义的特殊字符会导致参数解析提前终止,最终出现内容截断。

解决方案

方案1:使用原生转义函数(推荐)

不要手动拼接命令参数字符串,直接调用PHP原生escapeshellarg函数自动适配当前运行环境的shell转义规则,自动处理换行、引号、特殊字符问题,代码示例:

// 定义完整参数值,直接保留真实换行
$paramValue = "text=This is some text.
some more text in next line";
// 转义脚本路径和参数,避免路径/参数含特殊字符时解析异常
$scriptPath = escapeshellarg('C:\proj\main.js');
$escapedParam = escapeshellarg($paramValue);
// 拼接执行命令
$output = shell_exec("node {$scriptPath} {$escapedParam}");

注意:不要手动给参数加嵌套双引号,escapeshellarg会自动根据当前系统规则添加正确的包裹符号和转义符。

方案2:Windows环境手动适配转义

如果仅需要在Windows环境运行,可以手动适配cmd的续行转义规则:换行前加^标记,且^后必须紧跟真实换行,不能有其他空格或字符,示例:

$paramContent = 'text="This is some text. ^
some more text in next line"';
$cmd = 'node C:\proj\main.js ' . $paramContent;
$output = shell_exec($cmd);

该写法兼容性差,不推荐跨环境使用。

方案3:通过标准输入传参(无转义风险,最稳定)

如果可以修改node.js侧的接收逻辑,优先通过标准输入传递多行文本,完全绕开shell参数转义的所有坑:

PHP侧代码

// 待传递的多行内容
$sendContent = "text=This is some text.
some more text in next line";
// 配置进程管道
$desc = [
    0 => ['pipe', 'r'],
    1 => ['pipe', 'w'],
    2 => ['pipe', 'w']
];
$process = proc_open('node C:\proj\main.js', $desc, $pipes);
if (is_resource($process)) {
    // 向子进程标准输入写入内容
    fwrite($pipes[0], $sendContent);
    fclose($pipes[0]);
    // 读取执行结果和错误信息
    $result = stream_get_contents($pipes[1]);
    $error = stream_get_contents($pipes[2]);
    fclose($pipes[1]);
    fclose($pipes[2]);
    proc_close($process);
}

Node.js侧(main.js)读取标准输入代码

let rawInput = '';
process.stdin.on('data', chunk => rawInput += chunk);
process.stdin.on('end', () => {
    // rawInput即为PHP传递的完整内容,保留所有换行
    const [paramKey, ...paramValParts] = rawInput.split('=');
    const textValue = paramValParts.join('=');
    // 后续业务逻辑
    console.log('接收内容:', textValue);
});

内容的提问来源于stack exchange,提问作者MeetuU

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 14:33:28