解决PHP里大量数据循环时内存耗尽问题的方法-php教程

资源魔 90 0

相干学习保举:php编程(视频)

比来正在开发一个PHP顺序时遇到了上面的谬误:

PHP Fatal error: Allowed memory size of 268 435 456 bytes exhausted

谬误信息显示容许的最年夜内存曾经耗尽。遇到这样的谬误后来让我很惊讶,但转瞬一想,也没有希奇,由于我在开发的这个顺序是要用一个foreach轮回语句正在一个有4万笔记录的内外全表搜寻具备特定特色的数据,也就是说,一主要把4万条数据掏出,而后逐条反省天天数据。可想而知,4万条数据全副加载到内存中,内存没有爆才怪。

究竟结果编程这么多年,我隐隐记患上PHP里提供有非一次全副加载数据的API,是像解决流媒体那样,随用随取随丢、数据其实不会积攒正在内存的查问办法。通过简略的搜寻,果真正在民间网站上找到的正确的用法。

这个成绩正在PHP的民间网站上叫缓冲查问以及非缓冲查问(Buffered and Unbuffered queries)。PHP的查问缺省模式是缓冲模式。也就是说,查问数据后果会一次全副提取到内存里供PHP顺序解决。这样给了PHP顺序额定的性能,比方说,较量争论行数,将指针指向某一行等。更首要的是顺序能够对数据集重复进行二次查问以及过滤等操作。但这类缓冲查问模式的缺点就是耗费内存,也就是用空间换速率。

绝对的,另一种PHP查问模式长短缓冲查问,数据库效劳器会一条一条的前往数据,而没有是一次全副前往,这样的后果就是PHP顺序耗费较少的内存,但却添加了数据库效劳器的压力,由于数据库会不断期待PHP来取数据,不断到数据全副取完。

很显然,缓冲查问模式实用于小数据量查问,而非缓冲查问顺应于年夜数据量查问。

关于PHP的缓冲模式查问各人都晓得,上面罗列的例子是若何执行非缓冲查问API。

非缓冲查问办法一: mysqli

<?php
$mysqli  = new mysqli("localhost", "my_user", "my_password", "world");
$uresult = $mysqli->query("SELECT Name FROM City", MYSQLI_USE_RESULT);

if ($uresult) {
   while ($row = $uresult->fetch_assoc()) {
       echo $row['Name'] . PHP_EOL;
   }
}
$uresult->close();
?>

非缓冲查问办法二: pdo_mysql

<?php
$pdo = new PDO("mysql:host=localhost;dbname=world", 'my_user', 'my_pass');
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);

$uresult = $pdo->query("SELECT Name FROM City");
if ($uresult) {
   while ($row = $uresult->fetch(PDO::FETCH_ASSOC)) {
       echo $row['Name'] . PHP_EOL;
   }
}
?>

非缓冲查问办法三: mysql

<?php
$conn = mysql_connect("localhost", "my_user", "my_pass");
$db   = mysql_select_db("world");

$uresult = mysql_unbuffered_query("SELECT Name FROM City");
if ($uresult) {
   while ($row = mysql_fetch_assoc($uresult)) {
       echo $row['Name'] . PHP_EOL;
   }
}
?>

资源魔网友吐槽:

这个货色应该用天生器

这类写法 能够间接开掉了

解决年夜数据不成能依照那种写法写的

PHP中文网网友小陈给出了一个正确的形式

<?php

if (!function_exists('getYieldBigData')) {
    /**
     * 应用天生器前往天生器工具
     * @param array $data
     * @return Generator
     */
    function getYieldBigData($data = [])
    {
        foreach ($data as $tmp_data) {
            yield $tmp_data;
        }
        unset($tmp_data);
    }
}


if (!function_exists('foreachBigData')) {
    /**
     * 轮回年夜量数据应用天生器来制作值
     * @param array $data
     * @return array|false
     */
    function foreachBigData($data = [])
    {
        if (0 == count($data)) {
            return false;
        }
        $tmp = [];
        foreach (getYieldBigData($data) as $v) {
            $tmp[] = $v;
        }
        unset($v);
        return $tmp;
    }
}

//挪用办法
/**
 * @var $data array
 */
$data = [];
/**
 * @var $ret array
 */
$ret = foreachBigData($data);

return $ret;

小白也能看患上懂哈!

如上,此种形式能够达到100万/次!

本文来自资源魔php图文教程频道,原作者: 战神悟空 ,资源魔二次编纂。

以上就是处理PHP里年夜量数据轮回时内存耗尽成绩的办法的具体内容,更多请存眷资源魔其它相干文章!

标签: php php开发教程 php开发资料 php开发自学 内存耗尽

抱歉,评论功能暂时关闭!