Php 已耗尽134217728字节的允许内存大小(尝试分配4294967296字节)
我的项目使用一个开源PHP MySQL库 但该项目年中报告:“致命错误:第422行/home1/flipalbu/public_html/kvisofttest/login admin/Lib/class.MysqliDb.php中允许的内存大小为134217728字节(试图分配4294967296字节)”此错误 我的服务器是:linux x86_64 PHP版本5.4.17 Mysql版本:5.5.32 内存限制=128M 第422行:Php 已耗尽134217728字节的允许内存大小(尝试分配4294967296字节),php,mysql,Php,Mysql,我的项目使用一个开源PHP MySQL库 但该项目年中报告:“致命错误:第422行/home1/flipalbu/public_html/kvisofttest/login admin/Lib/class.MysqliDb.php中允许的内存大小为134217728字节(试图分配4294967296字节)”此错误 我的服务器是:linux x86_64 PHP版本5.4.17 Mysql版本:5.5.32 内存限制=128M 第422行:call_user_func_数组(数组($stmt,'b
call_user_func_数组(数组($stmt,'bind_result'),$parameters)代码>
查询部分代码:
$ db = new MysqliDb ('LocalHost', 'root', 'PASSWD', 'DB');
$ wqdb = $ db-> query ("SELECT * FROM db_table");
foreach ($ wqdb as $ row) {
$ con. = $ row ['ID'];
}
echo $ con;
有办法解决吗
/**错误代码**/
protected function _dynamicBindResults(mysqli_stmt $stmt)
{
$parameters = array();
$results = array();
$meta = $stmt->result_metadata();
$row = array();
while ($field = $meta->fetch_field()) {
$row[$field->name] = null;
$parameters[] = & $row[$field->name];
}
call_user_func_array(array($stmt, 'bind_result'), $parameters);
while ($stmt->fetch()) {
$x = array();
foreach ($row as $key => $val) {
$x[$key] = $val;
}
array_push($results, $x);
}
return $results;
}
如果您试图一次性读取整个表,而该表有很多行和列,那么内存将不可避免地耗尽。您可以通过增加php.ini中的内存限制来推迟,但问题只会在您再添加几千行时再次出现
您需要重写脚本,以便更清楚地了解它所获取的内容。如果您只需要特定的记录,那么下拉整个表并在结果集中查找所需的行是非常低效的。使用WHERE子句指定您真正想要的内容。PHP/SQL应用程序的经验法则是“尽可能使用SQL来指定您想要的内容,然后在PHP中使用它做您需要做的事情”
当然,您需要用PHP处理整个表可能有一个完全合理的原因。在这种情况下,您应该使用LIMIT和OFFSET以块的形式(比如一次100行)获取数据,处理这些行,获取下一个块,处理这些数据,以此类推,直到看完整个表。这比一次加载整个表的内存要少得多看起来不像一个大表!好像是一个无止境的循环!它试图分配大约4gb,我认为你没有这么大的桌子
检查此处是否未创建循环:
call_user_func_array (array ($ stmt, 'bind_result'), $ parameters);
也许你应该发布这行代码。你超出了最大可用内存。你有两个选择:
- 通过配置(
PHP.ini
中的memory\u limit
指令)或使用ini\u set('memory\u limit',200M')在执行时增加每个PHP脚本允许的最大内存。
- 改进代码以仅处理所需的信息
我在这里读到了这个bug报告:
您的问题似乎发生了,因为表的列中有一个longblob
或longtext
longtext
/longblob
的最大长度为4294967295
[4GB],这就是为什么mysqli尝试为缓冲区分配内存以确保不会丢失任何内容的原因。我建议您使用mediumtext
(最大长度为16777215[16MB]),这对于通常的一切都足够了
更新:
因为这个答案已经看到了一些活动,所以我添加了Phil_1984的这个解决方案(见注释)
我使用mysqli,在阅读了phpdev的那句话之后,添加了一个
$stmt->store_result();在execute和bind之间,结果似乎是固定的
我的问题
=>如果使用$stmt->store_result()
则可以将mysqli与longblob
/longtext
一起使用,而不会出现错误
-
旧答案:
我建议您要么将列更改为另一种类型(mediumtext),要么使用PDO(我认为它没有这个问题)。但是,如果您想将该列保持为长文本,则必须切换mysql库
引自PHP开发人员:
这是使用libmysql时ext/mysqli的已知限制(始终
在5.2和之前版本中)以及在5.3中启用libmysql时。这个
原因是服务器发送的元数据不太具体
专栏。此长文本的最大长度为4G,ext/mysqli尝试
使用最大长度绑定,以确保不会发生数据丢失(数据不会丢失)
适合C级绑定缓冲区)。然而,这意味着4G对于一个
longtext/longblob列。ext/mysqli已被更改为
解决这个问题。您需要调用mysqli\u stmt\u store\u result(),它
将数据存储在本地,这当然意味着更高的内存
PHP的用法。但是,由于您使用libmysql,这不会影响
当然,PHP的内存限制。在存储结果期间,最大长度为
将计算每一列,然后在执行bind_结果时
将只分配一个大小为max_length的缓冲区,该缓冲区将
绝对低于4G。简而言之,准备执行存储结果
绑定结果获取…获取…获取
您正在耗尽PHP可用的内存。可能是因为您的数据库表非常庞大,您只是选择了所有没有条件或limit子句的记录。您要获取多少行?有-不要从数据库中选择所有内容。通过ini_set('memory_limit','-1')将内存限制增加到最大值代码>@User016,否;这可能是命令行上的解决方案(即使如此,也很少)。然而,这看起来是一个web应用程序,您不希望实例占用大量内存。需要优化查询。本地虚拟机中的工作可以完全运行本地虚拟机的内存为128MB,请使用命令“top”控件,而不是因为查询使用了太多内存。但是,一进服务器就会产生这个问题,我需要重新修改整个项目的所有查询吗?还提供了这个代码示例:SELECT*FROM db_table ORDER BY page_modified DESC,ID DESC LIMIT$startItem,$itemsPerPage$STARTITETEM=0$itemsPerPage=10 live上的表可能远远大于您拥有的测试表。您的脚本正在尝试分配4G字节。您应该仔细看看我的答案,这是一个已知的问题,甚至不是一个bug,它的mysqli+longtext或longblobMy表只有几百个数据。@x4rf41