PHP程序能否获取php可执行文件接收的原始未解析完整命令行字符串?
PHP获取原始命令行字符串问题解答
核心结论
默认跨平台原生PHP没有提供直接获取未解析完整命令行字符串的内置能力,你现在用的implode(' ', $argv)已经是原生环境下能拿到的最接近的结果。如果接受依赖系统API或特定环境的方案,可以获取到进程层面的原始命令行,具体实现分系统说明:
Linux/Unix/macOS 实现方案
读取系统虚拟文件/proc/self/cmdline即可,该文件存储了当前进程启动时收到的完整命令行参数,参数之间以空字节\0分隔:
注意:该文件内容仍然是Shell解析后的结果,如果你需要的是用户在终端输入的、包含未展开通配符、原始引号、转义符的完全原始输入,该方案也无法实现——这类内容在Shell启动PHP进程前就已经被解析处理,PHP进程启动时本身就不会收到这部分内容。
示例代码:
// 读取进程命令行原始数据 $rawCmd = file_get_contents('/proc/self/cmdline'); // 替换空字节为空格,还原为易读的命令行格式 $formattedCmd = str_replace("\0", ' ', $rawCmd); echo $formattedCmd;
Windows 实现方案
通过FFI扩展调用Windows系统API GetCommandLineA 即可获取原始命令行,PHP 7.4及以上版本默认自带FFI扩展,只需在php.ini中开启即可使用:
示例代码:
$ffi = FFI::cdef(" char* GetCommandLineA(); ", "kernel32.dll"); $rawCmd = FFI::string($ffi->GetCommandLineA()); echo $rawCmd;
常见误区说明
不存在任何方案可以获取到Shell解析前的用户输入原始命令行:Shell(或进程启动器)在创建PHP进程时就已经完成了命令解析、变量替换、通配符展开、引号去除等操作,传递给PHP进程的只有解析后的参数列表,原始输入内容不会被传递到PHP进程的地址空间中。
内容的提问来源于stack exchange,提问作者Szczepan Hołyszewski
相关产品推荐
相关产品推荐

