假设返回 $result == -1 的系统是基于 Unix 的(我不知道使用相同代码的 Windows 会如何表现)
PHP (5.2.9) exec() 函数不会调用 C exec() 原语(如果无法替换/执行进程,则返回 -1,但此处情况并非如此)。相反,它调用 popen() 创建管道,执行 fork() 并使用您的命令执行 shell。
return_value -1 不是 C 原语的直接结果,而是由 PHP 内部构建的,具体取决于命令的处理方式。换句话说,“ls”命令可能已经执行得很好,但例如 PHP 无法正确关闭管道。
查看 ext/standard/exec.c 中的 C 代码,返回码为 -1 的原因可能有两个,由错误触发;第二个发生在 popen() 调用之后
fp = VCWD_POPEN(cmd_p, "r");
if (!fp) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to fork [%s]", cmd);
goto err;
}
// ...
err:
pclose_return = -1;
goto done;
但是在这种情况下,您将看不到结果,并且日志将显示错误。
稍后,通过以下行设置 return_value
pclose_return = php_stream_close(stream);
查看 _php_stream_free() (php_stream_close() 是一个被 _php_stream_free() 替换的宏),最有可能返回 -1 的候选者是
ret = stream->ops->close(stream, preserve_handle ? 0 : 1 TSRMLS_CC);
它又间接调用 C 原语 pclose()。根据说明书
如果 wait4(2) 返回错误或检测到其他错误,则 pclose() 函数返回 -1。
关闭管道期间似乎检测到错误,但这并不妨碍设置结果数据。要严格查找原因,需要检查操作系统设置和日志、PHP配置和编译参数。
我会推荐
- 为您的操作系统应用补丁,并可能更新到更新的版本(如果适用),
- 将 PHP 更新到 5.3.3(目前最新),因为 PHP exec() 代码发生了显着变化。
请注意,版本 5.3 中存在与 PHP suhosin 模块相关的更改,默认情况下增强了运行 PHP 文件时的安全性。