3

我正在使用 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 能够像这样限制子进程的内存吗?在某个地方还有其他设置吗?

帮助!

4

3 回答 3

1

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

于 2010-09-18T01:16:10.300 回答
0

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

于 2010-09-17T23:50:21.783 回答
0

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

[2010 年 9 月 17 日星期五 20:00:57] [错误] 未处理的 Java 异常:[2010 年 9 月 17 日星期五 20:00:57] [错误] java.lang.OutOfMemoryError [2010 年 9 月 17 日星期五 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)。

于 2010-09-18T01:46:29.817 回答