PHP脚本在添加到数组时总是超过内存限制


PHP Script always exceeds memory limit when adding to an array?

我一直在思考这个问题。我确信它以前从来没有这样做过,但我一定改变了什么,所以它做到了。

这是有问题的php脚本:

<?php
echo <<<START
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Spotify Community Staff Tracker</title>
<link rel="stylesheet" type="text/css" href="styles.css" />
<meta http-equiv="Content-Type" content="text/xhtml; charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<script type='text/javascript' src='scripts/respond.min.js'></script>
</head>
<body>
START;
error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING);
require_once('config.php');
$posts = array();
$db = new mysqli($config['host'], $config['user'], $config['password'], $config['database']);
if ( ($result = $db->query('SELECT * FROM `posts`')) != false)
{
    while ( ($obj = mysqli_fetch_object($result)) !== false)
    {
        if (@$_GET['idfilter'] && @$_GET['idfilter'] != $obj->board)
        {
            continue;
        }
        $posts[] = array('datetime' => $obj->datetime, 'subject' => $obj->subject, 'post_url' => $obj->post_link, 'user_url' => $obj->author_link, 'user' => $obj->author_name);
    }
    if (sizeof($posts) == 0)
    {
        if ($_GET['idfilter'])
            die("Filter caused zero result, or cron hasn't run.");
        die("Cron hasn't been run.");
    }
}
else
{
    die("An error occured.");
}
$lupdate = mysqli_fetch_object($db->query("SELECT * FROM `last_update`"));
echo <<<BOTTOM
<div id="right" class="fixed">
    <p id="lastupdate">Last Updated: {$lupdate->timestamp}</p>
    <p><form id="filter" action="" method="get">
            <input type="text" placeholder="Enter a forum id to filter..." name="idfilter" />
            <input type="submit" value="Filter" id="submit" />
    </form>
            </p>
</div>
BOTTOM;
echo("'n<div id='"posts'">");
foreach (array_reverse($posts) as $post)
{
    echo("'n<p><a class='"postlink'" target='"_blank'" href='"{$post['post_url']}'">{$post['subject']}</a> - by <a class='"suser'" target='"_blank'" href='"{$post['user_url']}'"><img src='"http://spotify.i.lithium.com/html/rank_icons/spotify_icon_new.png'" alt='"Spotify Staff'" />{$post['user']}</a> <span class='"datetime'">on {$post['datetime']}</span>'n</p>");
}
echo("'n</div>");
echo <<<END
'n</body>
</html>
END;
?>

每当我运行它时,我都会得到以下错误:

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 44 bytes) in <filepath>'index.php on line 36

总是同样的错误,同样的分配,同样的行。我试过移动东西,我试过用数组代替对象,没有用。

关于为什么要使用如此大量的内存,有什么想法吗?

(数据库中大约有400行)

正是这一行导致了问题:

while ( ($obj = mysqli_fetch_object($result)) !== false)

如果您查看文档:http://www.php.net/manual/en/mysqli-result.fetch-object.php

mysqli_fetch_object返回下一行(如果有);如果没有,则为null。因此,因为你正在进行严格的比较,所以你的循环永远不会结束。要解决这个问题,你可以简单地做:

while ($obj = mysqli_fetch_object($result))

让PHP的类型杂耍将记录集末尾的null转换为布尔false。

尝试在php.ini中增加内存限制或在该脚本中使用:

ini_set('memory_limit','256M');

您正在将工作复制到PHP。

查询完成后,您将执行同时对结果进行迭代,并将存储在PHP数组中。在脚本结束时,您将迭代您的数组,并将其放入HTML输出中。

我认为,您可以通过一次迭代完成所有操作,将foreach帖子替换为:

while ( ($obj = mysqli_fetch_object($result)) !== false)
{
    if (@$_GET['idfilter'] && @$_GET['idfilter'] != $obj->board)
    {
        continue;
    }
    echo("'n<p><a class='"postlink'" target='"_blank'" href='"{$post['post_url']}'">{$post['subject']}</a> - by <a class='"suser'" target='"_blank'" href='"{$post['user_url']}'"><img src='"http://spotify.i.lithium.com/html/rank_icons/spotify_icon_new.png'" alt='"Spotify Staff'" />{$post['user']}</a> <span class='"datetime'">on {$post['datetime']}</span>'n</p>");
}