php exec中的重定向在apache + windows 7中被破坏,正在使用Windows XP

时间:2013-08-09 12:26:21

标签: php windows apache io-redirection

我一直在使用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政策禁止?

2 个答案:

答案 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)

好的,我得到了(也许至少是我的)解决方案:

  1. 使用proc_open作为Charles建议
  2. 回到io_redirection的原始原则
  3. 将东西直接转储到STDERR并通过管道从那里检索它显然不能在(我的)windows7 + PHP下用我的代码工作。简单的例子可以工作,但那对我而言。

    所以当使用2>&1打破了我的exec() - 最初的问题 - 它与proc_open()完美配合。问题解决了。

    我想知道我现在是否会在运行新代码的Linux服务器上发现一些问题。

    小警告:如果您不希望您的代码打印到STDERR并且您使用redirect-to-null,例如用于生产,在Windows中2>nul