PHP:内存优化入站邮件

时间:2013-10-18 20:28:30

标签: php json base64 inbound

在我的PHP应用程序中,我使用Postmarks's入站挂钩接收邮件。此服务接收邮件并将其JSON编码发送到我的服务器上的URL,这可以正常工作。

我遇到的问题是,邮件的附件超过10MB。

结果是

  

PHP致命错误:允许的内存大小为104857600字节   (试图分配1821693字节)

我在这一行中所做的是:

$in = json_decode(file_get_contents("php://input"));

我有两个问题:

  1. 有没有办法提高内存效率?
  2. 为什么10MB邮件失败,内存限制实际为100MB? Base64 + JSON编码产生的开销是原始大小的10倍吗?
  3. 使用memory_get_usage()

    进行调试后编辑
    Script start
    47MB memory usage.
    $in = file_get_contents("php://input");
    63MB memory usage.
    json_decode($in);
    PHP terminates, due to memory size exhausted.
    

    有趣的是,脚本已经以47MB的内存使用率开始,而不发出任何命令。我想这是由于输入数据量大?也许是因为PHP将它存储在$ HTTP_RAW_POST_DATA?

    我可以使用任何php.ini指令,让PHP创建更少的变量吗?

1 个答案:

答案 0 :(得分:2)

电子邮件附件存储为base64,因此实际的电子邮件正文将大约2倍,所以我们有20mb

json_encode(在发件人方面)也可以添加base64开销,所以我们可以为单个file_get_contents调用大约40mb,然后json_decode将需要大约20mb,添加一些局部变量,并且至少有1个循环 - 并且100mb已经耗尽

我建议你阅读:memory_get_usage - 用它来追踪php分配内存的位置

然后使用unsetgc_collect_cycles

<强>更新 我不知道为什么json_decode需要这么多内存(也许是一些bug,更新php?),无论如何在php.ini中

register_globals = off
register_long_arrays = Off
register_argc_argv = Off
auto_globals_jit = On
always_populate_raw_post_data = Off

你的第二个问题:base64

  

因此,符合MIME的Base64编码二进制数据的实际长度通常约为原始数据长度的137%

JSON不应该增加很大的开销,但邮件主体到json的额外编码可能会再次使用base64