我的项目使用开源PHP MySQL库https://github.com/ajillion/PHP-MySQLi-Database-Class
但该项目年中报告:“致命错误:允许内存大小为134217728字节耗尽(试图分配4294967296字节)在/ home1 / flipalbu / public_html / kvisofttest / login-admin / Lib / class.MysqliDb.php第422行“这个错误,
我的服务器是:linux x86_64
PHP版本5.4.17
Mysql版本:5.5.32
memory_limit = 128M
422行: call_user_func_array (array ($ 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;
}
4 回答
看起来不像是一张巨大的 table !好像无尽的循环!它试图分配大约4GB,我不认为你有这么大的表......
检查您是否在此处创建循环:
也许你应该发布围绕这一行的代码 .
你超过了最大可用内存 . 你有两个选择:
通过配置(
php.ini
中的memory_limit
指令)或执行时间(使用ini_set('memory_limit', '200M')
)增加每个PHP脚本的最大允许内存量改进代码以仅处理所需信息 .
我在这里阅读了这个错误报告:https://bugs.php.net/bug.php?id=51386
您的问题似乎发生了,因为表的列中有
longblob
或longtext
.longtext
/longblob
的最大长度为4294967295
[4GB],这就是mysqli尝试为缓冲区分配内存以确保没有丢失的原因 . 我建议你使用mediumtext
(16777215 [16MB]最大长度),这应该足够通常 .Update: 因为这个答案已经看到一些活动我从Phil_1984添加了这个解决方案(见评论)
=>如果你使用
$stmt->store_result()
,你可以使用mysqli和longblob
/longtext
而不会收到错误 .Old Answer: 我建议您将列更改为其他类型(mediumtext)或使用PDO(我认为它没有这个问题) . 但是如果你想把列保留为longtext,你必须切换你的mysql库
从PHP开发引用:
如果你试图一次性读取整个表,并且该表有很多行和列,那么内存不足是不可避免的 . 你可以通过增加php.ini中的内存限制来解决它,但问题只会在你添加几千行时重新出现 .
您需要重写脚本以更加明智地了解它所取得的内容 . 如果您只需要特定记录,那么下拉整个表并在结果集中查找所需的行是非常低效的 . 使用WHERE子句指定您真正想要获得的内容 . PHP / SQL应用程序的经验法则是“尽可能使用SQL来指定您想要的内容,然后在PHP中执行您需要执行的操作” .
当然可能有一个完全合理的理由,你需要在PHP中处理整个表 . 在这种情况下,您应该使用LIMIT和OFFSET以块(一次说100行)获取数据,处理这些行,获取下一个块,处理这些行等等,直到您完成整个表 . 这比尝试一次加载整个表的内存要少得多