为什么当我将PHP与Apache一起使用时,它无法识别Windows系统PATH中的程序



在我的本地开发环境中,我在Windows7上安装了Apache和PHP。我正在用exec从我的PHP程序中调用7-Zip。我刚开始尝试

exec('7z a example.zip example.pdf');

但它没有创建zip文件。在查看Apache错误日志后,我发现了

'7z'未被识别为内部或外部命令、可操作程序或批处理文件。

exec更改为包含7-Zip.exe的完整路径后,它就工作了。

exec('"C:\Program Files\7-Zip\7z" a example.zip example.pdf');

但是C:Program Files7-Zip包含在我的Windows系统PATH中。相同的PHP代码在不使用完整路径的情况下从命令行运行。

php -r "exec('7z a example.zip example.pdf');"

当我在Apache中使用它时,为什么它需要完整的路径?


当我最初发布这个问题时,我忽略了一个重要的点,那就是我已经能够使用exec()调用Windows系统PATH中包含的其他程序,而无需通过它们的完整路径来引用它们。

另一点我最初没有提到,因为我没有意识到它的相关性,那就是7-Zip最近才被添加到PATH中,并且我在添加它之后重新启动了Apache服务。

我在windows 8上安装了WAMP,在阅读了你的问题后,我决定测试一些东西。

运行echo exec('whoami');回显:

nt authoritysystem

这证实了@Barmar所说的,Apache不是在同一个用户下运行的,所以PATH是不同的。

我决定停止Apache并在管理员帐户下手动启动它。然后我尝试了:

echo exec('whoami');

输出:

computernameadministrator

我假设现在exec将与PATH一起工作,并尝试:

echo exec('adb');//android adb工具在我的PATH

令人惊讶的是,尽管Apache与我使用相同的用户运行,但PATH仍然无法工作。我不知道为什么会发生这种事,如果有人有线索,请在下面评论。

我设法使用了PATH(使用管理员帐户),代码如下:

https://stackoverflow.com/users/171318/hek2mgl$WshShell=新COM("WScript.Shell");$oExec=$WshShell->运行("cmd/C 7z a example.zip example.pdf",0);//0不可见/1可见


我没有测试下面的代码,但您可以尝试在Apache服务帐户(nt authoritysystem)下设置PATH,然后使用命令,即:

echo exec('set PATH=%PATH%;C:/path/to/7z');
echo exec('7z a example.zip example.pdf');

我相信path在重新启动之间仍然有效


更新:

这个答案可以帮助您为帐户nt authoritysystem设置PATH

指定本地系统用户的个人环境变量位于">HKEY_USERS.DEFAULT\Environment"。计算机范围的环境变量在">HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SessionManager\Environment"。从注册表之外的任何位置,但可以从">系统"选项卡上的">Advanced"对话框属性".


对于未来的用户,设置Apache PATH的正确方法是:

您可以在.htaccess中使用setEnv或在PHP代码中使用putenv来设置$PATH

信贷转到hek2mgl

我刚刚弄清楚是什么导致了这个问题。事实上,这与我最初的假设无关。

我记得在phpinfo()中看到了PATH信息,所以我查看了它。在"Apache环境"部分中,它确实显示了所有PATH,但7-Zip的路径除外,我最近刚刚将其添加到系统PATH中。很明显,它似乎可以访问该路径,但它没有使用当前版本。为什么不呢?

通常情况下,我会认为我只是在更新路径后忘记了重新启动Apache,但在试图弄清楚这一点时,我反复重新启动了它。但显然重新启动Apache不会刷新此值。我不得不停止,然后启动。然后,phpinfo中的PATH中显示了7-Zip路径,我可以将程序改回使用普通7z

最新更新