【问题标题】:PHP exec(), shell_exec(), proc_open() & powershell working in CMD but not in browsersPHP exec()、shell_exec()、proc_open() 和 powershell 在 CMD 中工作,但不在浏览器中
【发布时间】:2017-10-06 21:45:29
【问题描述】:

以下脚本在 CMD 窗口中运行良好,但在浏览器中运行良好。下面的脚本在'front.php'中,win10的命令窗口命令'php front.php'做得很好,但http://localhost/blahblah/front.php没有触发'back.php'让我很吃惊。花了将近半夜的时间尝试所有可能的方法,包括shell_execproc_open,但都以上述问题告终。基本权限,php.ini相关问题都处理好了。

pclose(popen('powershell.exe "Start-Process php -ArgumentList \'back.php\' -WindowStyle Hidden"','r'));

echo exec('D:\Wamp\php\php.exe D:\Wamp\apache2\htdocs\MySite\admin\back.php > output.txt 2>&1 echo $!', $pid);

更新

只是为了缩小范围,我使用的是 Win 10 管理员用户,所有 WAMP 设置都仅在我的本地电脑中,使用 PHP 5.6.x。 front.php 和 back.php 都在同一个工作文件夹中,front 可以写入文件,但 back.php 不能从浏览器执行。在 CMD 中同样有效!

front.php:

<?php
ini_set("display_errors",1);
error_reporting(E_ALL);
file_put_contents('timelog.txt', date('Y-m-d/H:i:s.u')); 

echo exec('php back.php > output.txt 2>&1 echo $!');
// pclose(popen('powershell.exe "Start-Process php -ArgumentList \'back.php\' -WindowStyle Hidden"','r'));
?>

back.php:

<?php
sleep(5);   // some delay
file_put_contents('timelog.txt', date('Y-m-d/H:i:s.u'). "\n"); 
?>

【问题讨论】:

  • 显然,权限和 php.ini 设置的“常见问题”没有得到处理。
  • 第二行中的路径(D:\Wamp\php\php.exeD:\Wamp\apache2\htdocs\MySite\admin\back.php)是错误的,因为您没有将反斜杠加倍。在您的第一行中,您将它们用作转义字符,您也需要在第二行中这样做。您需要的序列是每个反斜杠。这可能不是您的问题,但值得解决。
  • 接下来,单独尝试echo exec('D:\\Wamp\\php\\php.exe -v'),看看是否有任何输出。如果这样做,请尝试下一位,等等。此外,您不需要执行 &gt; 重定向 - PHP 可以在 exec 命令本身中执行此操作。
  • 在元注释上,请阅读Under what circumstances may I add “urgent” or other similar phrases to my question, in order to obtain faster answers? - 总结是这不是解决志愿者的理想方式,并且可能会适得其反。请不要将此添加到您的问题中。
  • symscbean,我首先处理了通常的权限相关的东西,safe_mode,disabled_functions 等。正如我所说,我可以在 CMD 中运行它,我所有的东西都在本地的单个管理员用户中。另外,front.php 可以写入但 back.php 什么也不做,请注意我所有的东西都在同一个文件夹中,所以我看不到任何可以进一步处理权限的事情。

标签: php process exec shell-exec proc-open


【解决方案1】:

这有很多问题。

我注意到back.php 不会向stdoutstderr 发送任何内容(除非文件操作有错误)。

另外,您的两个脚本正在将时间戳写入一个文件,并且它们未处于附加模式,因此一个会覆盖另一个。尝试登录到不同的文件名,或者使用FILE_APPEND 作为file_put_contents() 中的第三个参数。

最后还不清楚echophp back.php &gt; output.txt 2&gt;&amp;1 echo $! 中应该做什么。对我来说,这看起来像是一个语法错误。

为了研究控制台与浏览器中重定向的本质,我编写了以下两个文件:

inner.php

<?php
// Writes something to stdout and stderr

echo "Stdout\n";
fwrite(STDERR, "Stderr\n");

outer.php

<?php
// Execs the inner file with and without redirection

exec('php inner.php', $output);
print_r($output);

exec('php inner.php 2>&1', $output2);
print_r($output2);

在控制台上我得到了这个:

Stderr
Array
(
    [0] => Stdout
)
Array
(
    [0] => Stdout
    [1] => Stderr
)

您可以看到,在第一种情况下,stderr 输出作为exec() 输出本身的一部分呈现到控制台,即除非我们执行2&gt;&amp;1 重定向,否则它不太容易捕获。

然后我搭建一个网络服务器:

php -S localhost:10000

并访问了地址:http://localhost:10000/outer.php

我在浏览器中收到了这个:

数组([0] => 标准输出)数组([0] => 标准输出 [1] => 标准错误)

并且控制台输出中出现杂散错误:

PHP 7.0.22-0ubuntu0.16.04.1 Development Server started at Sat Oct  7 11:01:43 2017
Listening on http://localhost:10000
Document root is /home/jon/Development/Personal/Missive
Press Ctrl-C to quit.
Stderr
[Sat Oct  7 11:01:56 2017] 127.0.0.1:54392 [200]: /outer.php
[Sat Oct  7 11:01:56 2017] 127.0.0.1:54394 [404]: /favicon.ico - No such file or directory

因此,我认为这里一切正常。

您可能希望创建一个简单的可重现测试用例 - 包含大量编辑和评论更新,您的问题变得过于复杂而无法回答。如果是X-Y problem,解释您想要实现的目标也可能很有价值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-15
    • 2010-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-30
    • 2014-03-27
    • 1970-01-01
    相关资源
    最近更新 更多