【问题标题】:PHP exec() not working - exiting early? no error?PHP exec() 不工作 - 提前退出?没有错误?
【发布时间】:2011-04-13 23:18:45
【问题描述】:

我正在使用 PHP 在如下脚本上运行 exec():

exec("pdftk xx.pdf fill_form xx.fdf output xx.pdf flatten");

最奇怪的是,当我登录 ssh 并手动输入命令时——它工作正常!它输出 224k pdf。但是当我使用 exec() 命令时,只有脚本的前 36k 出来。 (我检查了 - 好文件的前 36k 与坏文件相同)

这不是奇怪的事情——这与 exec() 一起工作得很好,直到我向 fdf 文件添加了更多变量,使其更长。由于新数据,我认为这是 fdf 的问题 - 但为什么这个过程可以从 ssh 正常运行?

更新:我也尝试运行 php -f test.php (其中只有一个 exec 行)。正确输出整个文件。但即使我去http://mydomain.com/test.php 我也只能得到文件的一部分。

脚本没有超时,因为我让它在 exec() 命令之后回显一些东西,它工作正常。

这不可能是权限问题(ssh 以 root 身份登录),因为它仍然能够写入文件

另外 - 当我尝试从 exec 或 passthru 获取返回或退出值时,我什么也得不到。返回值始终为 0。

更新:在 apache 错误日志中,我得到了

[2010 年 9 月 17 日星期五 20:00:57] [错误] 未处理的 Java 异常: [2010 年 9 月 17 日星期五 20:00:57] [错误] java.lang.OutOfMemoryError [2010 年 9 月 17 日星期五 20:00:57] [错误]

我将 php_ini 从 32M 更改为 64M - 仍然得到它。考虑到这些都是小文件,我不认为就是这样。但是 PHP 能够像这样限制子进程的内存吗?还有其他设置吗?

帮助!

【问题讨论】:

  • 呵呵,你已经解决了问题,但我仍然认为你应该使用 redis,因为很多用户同时调用该脚本,你的内存使用量将超出图表,你的计算机性能将严重退化

标签: php timeout exec pdftk passthru


【解决方案1】:

事实证明,这毕竟是一个内存问题。 Apache 在主 conf 文件中设置了 RLimitMEM,我现在只是禁用了它。现在它就像一个魅力。虽然它被设置为大约 89MB,并且由于这些文件都在一个兆以下,但我看不出这个应用程序将如何使用这么多内存。

【讨论】:

    【解决方案2】:

    我假设您正在使用共享网络主机,在这种情况下您应该注意:许多主机使用自定义 php.ini 文件来限制 exec() 的作用(例如完全阻止它被使用) 或者可能有一些系统就地阻止从 exec 产生的进程运行时间超过几秒钟,这就是为什么它可以在 shell 中正常工作,但不是在 PHP 的上下文中。

    【讨论】:

    • 这是一个 VPS,所以我可以更改 php.ini 以解决问题。任何线索可能是什么?也可能是apache中的东西吗?因为 php -f 运行良好,但不能通过完全相同的脚本的 web url 运行?还是可以将它们设置为使用不同的 ini 文件?
    【解决方案3】:

    更新:在 apache 错误日志中,我是 得到

    [2010 年 9 月 17 日星期五 20:00:57] [错误] 未处理的 Java 异常:[9 月 17 日星期五 2010 年 20:00:57] [错误] java.lang.OutOfMemoryError [9 月 17 日星期五 2010 年 20:00:57] [错误]

    我不明白为什么 apache 会给出 java 错误?你能和我们详细说明一下吗?我觉得这很奇怪。

    我将 php_ini 从 32M 更改为 64M - 还是得到它。考虑到这些都是小文件,我不认为那是 它。但 PHP 是否能够限制 像这样的子进程的记忆? 还有其他设置吗 什么地方?

    我也有一种感觉,这可能与您的应用程序正在使用的内存有关,因为它正在调用 pdftk,这可能会让您超过内存限制? pdftk 调用在峰值时使用多少内存?也许您应该进一步提高内存?

    你做过这样的事情吗? http://www.wallpaperama.com/forums/how-to-change-memory-limit-php-apache-server-t53.html

    更新:我也试过运行 php -f test.php(只有一个 exec 行在里面)。输出整个 正确归档。但即使我去 http://mydomain.com/test.php我只有 获取文件的一部分。

    我为您提供了一个解决方案,它也不会在高负载时杀死您的网络服务器(VPS)。从站点(网络服务器端),您应该使用predis php 客户端库将其推送到阻止列表(redis),因为它支持所有必需的 redis 命令(BLPOP/LPUSH)。从始终运行的 PHP 守护程序(php -f)中,您应该从阻止列表中弹出并执行命令(pdftk)。

    【讨论】:

    • 我也觉得这很奇怪 - 但服务器没有其他任何事情发生,这是唯一可能发生的事情。我唯一的猜测是 pdftk 的核心有某种 java?
    猜你喜欢
    • 1970-01-01
    • 2018-08-26
    • 1970-01-01
    • 1970-01-01
    • 2011-10-12
    • 2018-05-16
    • 1970-01-01
    • 2014-09-25
    • 1970-01-01
    相关资源
    最近更新 更多