加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

php – ‘safe’json_decode(,,,)以防止耗尽内存

发布时间:2020-12-13 22:25:16 所属栏目:PHP教程 来源:网络整理
导读:在我的应用程序中,我经常调用一个返回json字符串的外部api. $url = 'api.example.com/xyz';$blah = json_decode( file_get_contents( $url ) ); 但在某些情况下,我得到了 PHP Fatal error: Allowed memory size of xxx bytes exhausted (tried to allocate 3
在我的应用程序中,我经常调用一个返回json字符串的外部api.

$url = 'api.example.com/xyz';
$blah = json_decode( file_get_contents( $url ) );

但在某些情况下,我得到了

PHP Fatal error: Allowed memory size of xxx bytes exhausted (tried to allocate 32 bytes) in …

我无法控制外部API,当然我可以增加php的内存,但这有一些缺点.

1-无论我设定的尺寸如何,仍然可能太少.
2-如果我将内存大小设置为“无限”,那么我可能会冒着杀死我的服务器的风险.

理想情况下,我想在调用json_decode(…)之前“检查”该字符串会导致内存耗尽.

那可能吗?

解决方法

如果他们设法耗尽服务器的内存,你必须得到一些大规模的JSON响应.以下是一些包含多维关联数组的1 MB文件的度量标准(包含为进入具有不同数据类型的三个MySQL表而准备的数据).

当我包含并且文件作为数组加载到内存中时,我的内存使用量变为9 MB.如果我使用file_get_contents()获取原始数据,则需要1 MB内存.然后,PHP数组与数据的strlen()的比率大约为1:9(最初使用var_export()输出).

当我运行json_encode()时,峰值内存使用量不会增加. (PHP以块的形式分配内存,因此通常会有一些开销,在这种情况下足以包含JSON的字符串数据;但它可能会使您更多地阻塞一个块.)生成的JSON数据作为字符串需要670 KB.

当我将带有file_get_contents的JSON数据加载到字符串中时,它需要0.75 MB的内存.当我在其上运行json_decode()时,它需要7 MB的内存.然后,我会将JSON数据字节大小的最小比率1:10分解为本机PHP数组或对象的RAM要求.

要在解码之前对JSON数据运行测试,您可以执行以下操作:

if (strlen($my_json) * 10 > ($my_mb_memory * 1024 * 1024)) {
    die ('Decoding this would exhaust the server memory. Sorry!');
}

…其中$my_json是原始JSON响应,$my_mb_memory是您分配的RAM,它被转换为字节以与传入数据进行比较. (您当然也可以使用intval(ini_get(‘memory_limit’))将内存限制作为整数.)

如下所述,RAM的使用还取决于您的数据结构.相比之下,一些更快的测试用例因为我很好奇自己:

>
>如果我使用整数1-60000创建一个单维数组,则保存的PHP数组大小为1 MB,但峰值RAM使用量介于10.5和12.5 MB(奇怪的振荡)之间,或者比例为1:12-ish.

>
>如果我将1 MB文件的数据作为12000个随机字符串创建为基本关联数组,则加载时内存使用量仅为5 MB;比例为1:5.

>
>如果我创建一个1 MB的文件值得作为类似的关联数组,其中一半的条目是数组作为带有数字索引的字符串,内存使用量为7 MB,比例为1:7.

所以你的实际内存里程可能会有很大差异.另外要注意的是,如果你在圈子中传递大量数据并做一些这样的事情,你的内存使用量可能会比json_decode()单独引起的更多(或指数级,取决于你的代码经济性).

要调试内存使用情况,可以在代码中以主要间隔使用memory_get_usage()和/或memory_get_peak_usage()来记录或输出代码不同部分中使用的内存.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读