PHP执行shell_exec先javac后运行java无输出,调换顺序正常如何解决
问题解决方法
问题根源
- 你的
/var/www/the-file/java/目录下已经提前存在编译好的the-file.class文件,所以直接执行java the-file命令可以正常输出Hello World。 - Web服务运行PHP的用户(通常为
www-data、apache等)对目标目录没有写入权限:javac编译命令执行时需要生成新的the-file.class文件,没有写入权限会直接执行失败,错误信息默认输出到标准错误流(stderr),而PHP的shell_exec函数仅捕获标准输出流(stdout)的内容。同时&&逻辑符要求前序命令执行成功才会运行后续命令,因此javac失败后java命令根本不会触发,最终没有任何输出。 - 调换命令顺序先执行
java再执行javac时,前序java命令会调用已存在的旧class文件运行成功,输出内容到stdout,后续javac执行失败不影响已经生成的输出内容,所以能拿到正常返回结果。
解决步骤
- 给目标目录配置正确的权限,确保Web运行用户可以写入编译生成的
class文件,执行以下服务器命令即可:chown -R www-data:www-data /var/www/the-file/java/
如果权限配置后仍有问题,可以临时执行chmod 766 /var/www/the-file/java/验证是否是权限导致的问题,验证完成后建议恢复为更安全的权限配置。 - 修改PHP代码,将标准错误流重定向到标准输出,方便后续排查编译阶段的报错,修改后的代码如下:
<?php $dir = "cd '/var/www/the-file/java/'"; // 2>&1 作用是把标准错误输出合并到标准输出,方便捕获报错信息 echo shell_exec("$dir && javac the-file.java 2>&1 && java the-file"); ?>
优化建议
如果你的Java代码不会频繁改动,不需要每次请求都重新编译,建议提前手动编译好the-file.class文件,PHP代码直接调用java the-file运行即可,减少不必要的编译性能开销。如果确实需要动态编译,也可以增加判断逻辑:当.class文件存在且修改时间晚于.java文件时,跳过编译步骤直接运行。
内容的提问来源于stack exchange,提问作者michelle
相关产品推荐
相关产品推荐

