我一直在使用PHP在Apache服务器上执行遗留脚本。遗留脚本将调试数据写入STDERR,我根据调试设置将其重定向到黑洞或STDOUT。
PHP看起来有点像这样:exec('perl -e "print 10; print STDERR 20" 2>&1', $output);
在XP中可靠地运行。我有新的硬件,现在运行Windows7并回到这个代码,它已经破碎。零输出。返回码255.不知道为什么。
我能够再次获得它的唯一方法是删除重定向。哦,重定向仍然可以在终端盒中完美运行。
现在我必须从apache-error-log(默认情况下每个STDERR输出都是这样)检索我的调试数据,这不方便但不是问题。
我只是想了解为什么重定向突然停止工作(并且可能帮助其他人遇到同样的问题)。 apache是一样的,事实上我只是从旧盒子里复制了XAMPP目录。一个bug?系统的限制? OS政策禁止?
答案 0 :(得分:1)
不使用exec
并使用文件句柄重定向,而是使用proc_open
并实际捕获stdout和stderr的输出。与某些与流程相关的函数不同,proc_
系列内置于所有版本的PHP中,并且在Windows上运行良好。
他们完整性示例的c& p:
$descriptorspec = array(
0 => array("pipe", "r"), // stdin is a pipe that the child will read from
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
2 => array("file", "/tmp/error-output.txt", "a") // stderr is a file to write to
);
$cwd = '/tmp';
$env = array('some_option' => 'aeiou');
$process = proc_open('php', $descriptorspec, $pipes, $cwd, $env);
if (is_resource($process)) {
// $pipes now looks like this:
// 0 => writeable handle connected to child stdin
// 1 => readable handle connected to child stdout
// Any error output will be appended to /tmp/error-output.txt
fwrite($pipes[0], '<?php print_r($_ENV); ?>');
fclose($pipes[0]);
echo stream_get_contents($pipes[1]);
fclose($pipes[1]);
// It is important that you close any pipes before calling
// proc_close in order to avoid a deadlock
$return_value = proc_close($process);
echo "command returned $return_value\n";
}
请务必浏览文档页面上的 upvoted 用户提供的说明,以了解可能的警告。
答案 1 :(得分:0)
好的,我得到了(也许至少是我的)解决方案:
将东西直接转储到STDERR并通过管道从那里检索它显然不能在(我的)windows7 + PHP下用我的代码工作。简单的例子可以工作,但那对我而言。
所以当使用2>&1
打破了我的exec() - 最初的问题 - 它与proc_open()完美配合。问题解决了。
我想知道我现在是否会在运行新代码的Linux服务器上发现一些问题。
小警告:如果您不希望您的代码打印到STDERR并且您使用redirect-to-null,例如用于生产,在Windows中2>nul