构建树时PHP致命错误内存不足
Posted
技术标签:
【中文标题】构建树时PHP致命错误内存不足【英文标题】:PHP Fatal error out of memory while building tree 【发布时间】:2016-09-16 08:35:52 【问题描述】:我在 php 中构建类别树时遇到了麻烦。 它构建了很长时间的树,之后我得到了错误:
致命错误:内存不足(已分配 637796352)(试图分配 208666926 字节)在 D:\OpenServer\domains\site.local\Core\Widgets.php 在第 488 行
这是我构建树的函数。
首先我做了一个类别数组:
public function makeCategoriesArray()
// $row = DB::select()
// ->from('catalog_tree')
// ->where('parent_id', '=', $this->post['parent_id'])
// ->union(DB::select()
// ->from('catalog_tree')
// ->where('id', 'in', DB::expr("(SELECT catalog_tree_id FROM catalog_tree_parents WHERE parent_id = '".$this->post['parent_id']."')")))
// ->find_all();
$row = DB::select()
->from('catalog_tree')
->where('status', '=', '1')
->find_all();
$categories_arr = array();
foreach ($row as $cat)
$categories_arr[$cat->parent_id][] = $cat;
unset($cat);
unset($row);
foreach($categories_arr as $key=>$value)
$row = DB::select()
->from('catalog_tree')
->where('id', 'in', DB::expr("(SELECT catalog_tree_id FROM catalog_tree_parents WHERE parent_id = '".$key."')"))
->find_all();
foreach($row as $cat)
$categories_arr[$key][] = $cat;
unset($cat);
unset($row);
return $categories_arr;
然后我开始用这个数组构建树:
public function BuildMainTree($array, $pid)
global $MainMenu;
if (isset($array[$pid])) // If category with $pid exist
$MainMenu.= "<ul class=\"dropdown-menu\" role=\"menu\">";
foreach ($array[$pid] as $value)
if ($pid!='0' && !isset($array[$value->id]))
$MainMenu.= '<li class="divider"></li>
<li class="dropdown">
<a href="/catalog/' . $value->alias . '">
'. $value->name .'
</a>
</li>';
else
$MainMenu.= '<li class="divider"></li>
<li class="dropdown">
<a href="/catalog/' . $value->alias . '">
'. $value->name .'
<span class="caret"></span>
</a>
</li>';
$this->BuildMainTree($array, $value->id);
if ($pid=='0')
$MainMenu .= "</ul>";
else
$MainMenu .= "</ul></li>";
这个过程的初始化都在这个函数里:
public function Header()
$contentMenu = Common::factory('sitemenu')->getRows(1, 'sort');
$array['contentMenu'] = $contentMenu;
$array['user'] = User::info();
$array['countItemsInTheCart'] = Cart::factory()->_count_goods;
$categories_arr = $this->makeCategoriesArray();
$this->BuildMainTree($categories_arr, 0);
$array['mainMenu'] = $MainMenu;
return $array;
另外,如果我只是用 makeCategoriesArray() 制作数组,它工作正常,但 BuildMainTree($array, $pid) 函数会导致错误...
最有趣的是,这段代码在其他网站上也能完美运行。
也许我只是在这里遗漏了一些细节......花了两天时间试图运行这段代码,但一无所获。
这里是数组 var_dump:
array(156)
[0]=>
array(21)
[0]=>
object(stdClass)#17 (18)
["id"]=>
string(4) "2075"
["created_at"]=>
string(10) "1470080793"
["updated_at"]=>
string(10) "1473775697"
["status"]=>
string(1) "1"
["sort"]=>
string(1) "0"
["name"]=>
string(27) "Садовая мебель"
["alias"]=>
string(14) "sadovaja-mebel"
["ikea_alias"]=>
string(7) "outdoor"
["parent_id"]=>
string(1) "0"
["image"]=>
string(36) "dc30302d5e76ddf7d3be9cb0f8b4d711.jpg"
["h1"]=>
NULL
["title"]=>
NULL
["keywords"]=>
NULL
["description"]=>
NULL
["text"]=>
NULL
["views"]=>
string(3) "129"
["course"]=>
string(4) "9.50"
["discount_percent"]=>
string(1) "0"
[1]=>
object(stdClass)#19 (18)
["id"]=>
string(4) "2076"
["created_at"]=>
string(10) "1470080793"
["updated_at"]=>
string(10) "1473950659"
["status"]=>
string(1) "1"
["sort"]=>
string(1) "0"
["name"]=>
string(39) "Оформление интерьера"
["alias"]=>
string(19) "oformlenie-interera"
["ikea_alias"]=>
string(10) "decoration"
["parent_id"]=>
string(1) "0"
["image"]=>
string(36) "91b3786d06e22081abbb945b9e4e02d8.jpg"
["h1"]=>
NULL
["title"]=>
NULL
["keywords"]=>
NULL
["description"]=>
NULL
["text"]=>
NULL
["views"]=>
string(3) "287"
["course"]=>
string(4) "9.50"
["discount_percent"]=>
string(1) "0"
[2]=>
object(stdClass)#20 (18)
["id"]=>
string(4) "2077"
["created_at"]=>
string(10) "1470080793"
["updated_at"]=>
string(10) "1472474523"
["status"]=>
string(1) "1"
["sort"]=>
string(1) "0"
["name"]=>
string(27) "Офисная мебель"
["alias"]=>
string(14) "ofisnaja-mebel"
["ikea_alias"]=>
string(10) "workspaces"
["parent_id"]=>
string(1) "0"
["image"]=>
string(36) "6884cb6cf5defdf8ec7fe467bad542ca.jpg"
["h1"]=>
NULL
["title"]=>
NULL
["keywords"]=>
NULL
["description"]=>
NULL
["text"]=>
NULL
["views"]=>
string(3) "247"
["course"]=>
string(4) "9.50"
["discount_percent"]=>
string(1) "0"
[3]=>
object(stdClass)#21 (18)
["id"]=>
string(4) "2078"
["created_at"]=>
string(10) "1470080793"
["updated_at"]=>
string(10) "1472409476"
["status"]=>
string(1) "1"
["sort"]=>
string(1) "0"
["name"]=>
string(34) "Посуда для готовки"
["alias"]=>
string(19) "posuda-dlja-gotovki"
["ikea_alias"]=>
string(7) "cooking"
["parent_id"]=>
string(1) "0"
["image"]=>
string(36) "ca3e4a8eb9d0d7ea22f9a7fc3c300ef9.jpg"
["h1"]=>
NULL
["title"]=>
NULL
["keywords"]=>
NULL
["description"]=>
NULL
["text"]=>
NULL
["views"]=>
string(3) "514"
["course"]=>
string(4) "9.50"
["discount_percent"]=>
string(1) "0"
[4]=>
object(stdClass)#22 (18)
["id"]=>
string(4) "2079"
["created_at"]=>
string(10) "1470080793"
["updated_at"]=>
string(10) "1472547042"
["status"]=>
string(1) "1"
["sort"]=>
string(1) "0"
["name"]=>
string(16) "Столовая"
["alias"]=>
string(9) "stolovaja"
["ikea_alias"]=>
string(6) "dining"
["parent_id"]=>
string(1) "0"
["image"]=>
string(36) "d5704ec3e70a3415b181c7c4f9005c1a.jpg"
["h1"]=>
NULL
["title"]=>
NULL
["keywords"]=>
NULL
["description"]=>
NULL
["text"]=>
NULL
["views"]=>
string(3) "147"
["course"]=>
string(4) "9.50"
["discount_percent"]=>
string(1) "0"
[5]=>
object(stdClass)#23 (18)
["id"]=>
string(4) "2080"
["created_at"]=>
string(10) "1470080793"
["updated_at"]=>
string(10) "1472547236"
["status"]=>
string(1) "1"
["sort"]=>
string(1) "0"
["name"]=>
string(31) "Сервировка стола"
["alias"]=>
string(16) "servirovka-stola"
["ikea_alias"]=>
string(6) "eating"
["parent_id"]=>
string(1) "0"
["image"]=>
string(36) "2d2142a8edd5fc3ce1ffa01fbe6655c9.jpg"
["h1"]=>
NULL
["title"]=>
NULL
["keywords"]=>
NULL
["description"]=>
NULL
["text"]=>
NULL
["views"]=>
string(3) "338"
["course"]=>
string(4) "9.50"
["discount_percent"]=>
string(1) "0"
[6]=>
object(stdClass)#24 (18)
["id"]=>
string(4) "2081"
["created_at"]=>
string(10) "1470080793"
["updated_at"]=>
string(10) "1472540142"
["status"]=>
string(1) "1"
["sort"]=>
string(1) "0"
["name"]=>
string(21) "Кухни МЕТОД"
["alias"]=>
string(11) "kuhni-metod"
["ikea_alias"]=>
string(7) "kitchen"
["parent_id"]=>
string(1) "0"
["image"]=>
string(36) "decf1d321c63aed673d949b34c452a37.jpg"
["h1"]=>
NULL
["title"]=>
NULL
["keywords"]=>
NULL
["description"]=>
NULL
["text"]=>
NULL
["views"]=>
string(3) "304"
["course"]=>
string(4) "9.50"
["discount_percent"]=>
string(1) "0"
[7]=>
object(stdClass)#25 (18)
["id"]=>
string(4) "2082"
["created_at"]=>
string(10) "1470080793"
["updated_at"]=>
string(10) "1472466401"
["status"]=>
string(1) "1"
["sort"]=>
string(1) "0"
["name"]=>
string(18) "Освещение"
["alias"]=>
string(11) "osveschenie"
["ikea_alias"]=>
string(8) "lighting"
["parent_id"]=>
string(1) "0"
["image"]=>
string(36) "3ac3d00a4734040cf346f2a63a09a7f9.jpg"
["h1"]=>
NULL
["title"]=>
NULL
["keywords"]=>
NULL
["description"]=>
NULL
["text"]=>
NULL
["views"]=>
string(3) "243"
["course"]=>
string(4) "9.50"
["discount_percent"]=>
string(1) "0"
[8]=>
object(stdClass)#26 (18)
["id"]=>
string(4) "2083"
["created_at"]=>
string(10) "1470080793"
["updated_at"]=>
string(10) "1472547518"
["status"]=>
string(1) "1"
["sort"]=>
string(1) "0"
["name"]=>
string(14) "Детская"
["alias"]=>
string(8) "detskaja"
["ikea_alias"]=>
string(14) "childrens_ikea"
["parent_id"]=>
string(1) "0"
["image"]=>
string(36) "8d78781b99b8ee7a1abc0f9cbfdc7e01.jpg"
["h1"]=>
NULL
["title"]=>
NULL
["keywords"]=>
NULL
["description"]=>
NULL
["text"]=>
NULL
["views"]=>
string(3) "321"
["course"]=>
string(4) "9.50"
["discount_percent"]=>
string(1) "0"
[9]=>
object(stdClass)#27 (18)
["id"]=>
string(4) "2084"
["created_at"]=>
string(10) "1470080793"
["updated_at"]=>
string(10) "1472411322"
["status"]=>
string(1) "1"
["sort"]=>
string(1) "0"
["name"]=>
string(16) "Гостиная"
["alias"]=>
string(9) "gostinaja"
["ikea_alias"]=>
string(11) "living_room"
["parent_id"]=>
string(1) "0"
["image"]=>
string(36) "c9c933ae12652bca96eb2ef66c832a82.jpg"
["h1"]=>
NULL
["title"]=>
NULL
["keywords"]=>
NULL
["description"]=>
NULL
["text"]=>
NULL
["views"]=>
string(3) "181"
["course"]=>
string(4) "9.50"
["discount_percent"]=>
string(1) "0"
[10]=>
object(stdClass)#28 (18)
["id"]=>
string(4) "2085"
["created_at"]=>
string(10) "1470080793"
["updated_at"]=>
string(10) "1472388754"
["status"]=>
string(1) "1"
["sort"]=>
string(1) "0"
["name"]=>
string(35) "Домашняя прачечная"
["alias"]=>
string(24) "domashnjaja-prachechnaja"
["ikea_alias"]=>
string(7) "laundry"
["parent_id"]=>
string(1) "0"
["image"]=>
string(36) "08c9713d828235679b861c095784af0e.jpg"
["h1"]=>
NULL
["title"]=>
NULL
["keywords"]=>
NULL
["description"]=>
NULL
["text"]=>
NULL
["views"]=>
string(3) "106"
["course"]=>
string(4) "9.50"
["discount_percent"]=>
string(1) "0"
[11]=>
object(stdClass)#29 (18)
["id"]=>
string(4) "2086"
["created_at"]=>
string(10) "1470080793"
["updated_at"]=>
string(10) "1472481068"
["status"]=>
string(1) "1"
["sort"]=>
string(1) "0"
["name"]=>
string(45) "Дополнительное хранение"
["alias"]=>
string(22) "dopolnitelnoe-hranenie"
["ikea_alias"]=>
string(17) "secondary_storage"
["parent_id"]=>
string(1) "0"
["image"]=>
string(36) "bb180b85cc1e34ab9b6185f4cf71fbf0.jpg"
["h1"]=>
NULL
["title"]=>
NULL
["keywords"]=>
NULL
["description"]=>
NULL
["text"]=>
NULL
["views"]=>
string(3) "158"
["course"]=>
string(4) "9.50"
["discount_percent"]=>
string(1) "0"
[12]=>
object(stdClass)#31 (18)
["id"]=>
string(4) "2088"
["created_at"]=>
string(10) "1470080793"
["updated_at"]=>
string(10) "1472136224"
["status"]=>
string(1) "1"
["sort"]=>
string(1) "0"
["name"]=>
string(16) "Прихожая"
["alias"]=>
string(10) "prihozhaja"
["ikea_alias"]=>
string(7) "hallway"
["parent_id"]=>
string(1) "0"
["image"]=>
string(36) "985600d075b4080f57488b87e0e898ff.jpg"
["h1"]=>
NULL
["title"]=>
NULL
["keywords"]=>
NULL
["description"]=>
NULL
["text"]=>
NULL
["views"]=>
string(2) "64"
["course"]=>
string(4) "9.50"
["discount_percent"]=>
string(1) "0"
[13]=>
object(stdClass)#32 (18)
["id"]=>
string(4) "2089"
["created_at"]=>
string(10) "1470080793"
["updated_at"]=>
string(10) "1472556911"
["status"]=>
string(1) "1"
["sort"]=>
string(1) "0"
["name"]=>
string(14) "Спальня"
["alias"]=>
string(7) "spalnja"
["ikea_alias"]=>
string(7) "bedroom"
["parent_id"]=>
string(1) "0"
["image"]=>
string(36) "439a1f90391568bffabcfbc5a8b22559.jpg"
["h1"]=>
NULL
["title"]=>
NULL
["keywords"]=>
NULL
["description"]=>
NULL
["text"]=>
NULL
["views"]=>
string(3) "172"
["course"]=>
string(4) "9.50"
["discount_percent"]=>
string(1) "0"
[14]=>
object(stdClass)#33 (18)
["id"]=>
string(4) "2090"
["created_at"]=>
string(10) "1470080793"
["updated_at"]=>
string(10) "1472481070"
["status"]=>
string(1) "1"
["sort"]=>
string(1) "0"
["name"]=>
string(18) "Еда в ИКЕА"
["alias"]=>
string(10) "eda-v-ikea"
["ikea_alias"]=>
string(4) "food"
["parent_id"]=>
string(1) "0"
["image"]=>
string(36) "1886868c925ed2f22a10fe7e51a6050c.JPG"
["h1"]=>
NULL
["title"]=>
NULL
["keywords"]=>
NULL
["description"]=>
NULL
["text"]=>
NULL
["views"]=>
string(2) "24"
["course"]=>
string(4) "9.50"
["discount_percent"]=>
string(1) "0"
[15]=>
object(stdClass)#34 (18)
["id"]=>
string(4) "2091"
["created_at"]=>
string(10) "1470080793"
["updated_at"]=>
string(10) "1472554267"
["status"]=>
string(1) "1"
["sort"]=>
string(1) "0"
["name"]=>
string(16) "Текстиль"
["alias"]=>
string(7) "tekstil"
["ikea_alias"]=>
string(8) "Textiles"
["parent_id"]=>
string(1) "0"
["image"]=>
string(36) "1ed5b13bc1abab2d5966b6ab074b7174.jpg"
["h1"]=>
NULL
["title"]=>
NULL
["keywords"]=>
NULL
["description"]=>
NULL
["text"]=>
NULL
["views"]=>
string(3) "194"
["course"]=>
string(4) "9.50"
["discount_percent"]=>
string(1) "0"
[16]=>
object(stdClass)#35 (18)
["id"]=>
string(4) "2092"
["created_at"]=>
string(10) "1470080793"
["updated_at"]=>
string(10) "1473774214"
["status"]=>
string(1) "1"
["sort"]=>
string(1) "0"
["name"]=>
string(33) "Домашние растения"
["alias"]=>
string(19) "domashnie-rastenija"
["ikea_alias"]=>
string(16) "indoor_gardening"
["parent_id"]=>
string(1) "0"
["image"]=>
string(36) "a42bf2728494d635bc16b0f12db5855d.jpg"
["h1"]=>
NULL
["title"]=>
NULL
["keywords"]=>
NULL
["description"]=>
NULL
["text"]=>
string(0) ""
["views"]=>
string(2) "55"
["course"]=>
string(4) "9.50"
["discount_percent"]=>
string(1) "0"
[17]=>
object(stdClass)#36 (18)
["id"]=>
string(4) "2093"
["created_at"]=>
string(10) "1470080793"
["updated_at"]=>
string(10) "1472481066"
["status"]=>
string(1) "1"
["sort"]=>
string(1) "0"
["name"]=>
string(39) "Беспроводная зарядка"
["alias"]=>
string(22) "besprovodnaja-zarjadka"
["ikea_alias"]=>
string(17) "wireless_charging"
["parent_id"]=>
string(1) "0"
["image"]=>
string(36) "6ee6de2d3769d7f617b7e05fd81fbaa4.jpg"
["h1"]=>
NULL
["title"]=>
NULL
["keywords"]=>
NULL
["description"]=>
NULL
["text"]=>
NULL
["views"]=>
string(2) "95"
["course"]=>
string(4) "9.50"
["discount_percent"]=>
string(1) "0"
[18]=>
object(stdClass)#37 (18)
["id"]=>
string(4) "2094"
["created_at"]=>
string(10) "1470080793"
["updated_at"]=>
string(10) "1472517463"
["status"]=>
string(1) "1"
["sort"]=>
string(1) "0"
["name"]=>
string(12) "Ванная"
["alias"]=>
string(7) "vannaja"
["ikea_alias"]=>
string(8) "bathroom"
["parent_id"]=>
string(1) "0"
["image"]=>
string(36) "f69159cedca764bc7d44ff7d6a13b52a.jpg"
["h1"]=>
NULL
["title"]=>
NULL
["keywords"]=>
NULL
["description"]=>
NULL
["text"]=>
NULL
["views"]=>
string(3) "157"
["course"]=>
string(4) "9.50"
["discount_percent"]=>
string(1) "0"
[19]=>
object(stdClass)#38 (18)
["id"]=>
string(4) "2095"
["created_at"]=>
string(10) "1470080793"
["updated_at"]=>
string(10) "1472379447"
["status"]=>
string(1) "1"
["sort"]=>
string(1) "0"
["name"]=>
string(24) "Товары IKEA FAMILY"
["alias"]=>
string(18) "tovary-ikea-family"
["ikea_alias"]=>
string(20) "ikea_family_products"
["parent_id"]=>
string(1) "0"
["image"]=>
string(36) "9e0c8d67fd4189ebed7b821e1c6b9df8.jpg"
["h1"]=>
NULL
["title"]=>
NULL
["keywords"]=>
NULL
["description"]=>
NULL
["text"]=>
NULL
["views"]=>
string(2) "78"
["course"]=>
string(4) "9.50"
["discount_percent"]=>
string(1) "0"
[20]=>
object(stdClass)#39 (18)
["id"]=>
string(4) "2096"
["created_at"]=>
string(10) "1470080793"
["updated_at"]=>
string(10) "1472482584"
["status"]=>
string(1) "1"
["sort"]=>
string(1) "0"
["name"]=>
string(34) "Для вашего бизнеса"
["alias"]=>
string(20) "dlja-vashego-biznesa"
["ikea_alias"]=>
string(8) "business"
["parent_id"]=>
string(1) "0"
["image"]=>
string(36) "3b9d8f1d77703f38d3d043fb95dd2b5e.jpg"
["h1"]=>
NULL
["title"]=>
NULL
["keywords"]=>
NULL
["description"]=>
NULL
["text"]=>
NULL
["views"]=>
string(3) "118"
["course"]=>
string(4) "9.50"
["discount_percent"]=>
string(1) "0"
【问题讨论】:
请添加一个最小示例数组的 var_dump,看起来这行是问题:$this->BuildMainTree($array, $value->id);如果 $value->id 保持为 0,那么您将获得无限递归 这不会抛出错误$categories_arr[$cat->parent_id][] = $cat
吗?您正在向$categories_arr[$cat->parent_id]
添加一个新的数组项,而没有先将其放入数组中。
@DoktorOSwaldo,添加了 $array 的 var_dump
@MagnusEriksson,这部分代码没有错误。仅在构建树时...
@ViacheslavZhabonos 谢谢,我真的建议研究这种情况: ($pid!='0' && !isset($array[$value->id])) 也许在那里或回声一些东西,看看这是否发生过。在您的转储中,它看起来像 $value->id 始终设置,因此您的递归将永远进行。我打赌它应该是 parent_id 而不是 id ^^
【参考方案1】:
这不是代码问题。将 php.ini 文件中的 memory_limit 设置为 128m 以上, 您还应该将帖子元数据增加到 10000
【讨论】:
【参考方案2】:用这个函数解决的问题:
public static function BuildTree($pid)
global $MainMenu;
$row = DB::select()
->from('catalog_tree')
->where('parent_id', '=', $pid)
->and_where('status', '=', '1')
->union(DB::select()
->from('catalog_tree')
->where('id', 'in', DB::expr("(SELECT catalog_tree_id FROM catalog_tree_parents WHERE parent_id = '".$pid."')"))
->and_where('status', '=', '1'))
->find_all();
if ($row->count() > 0)
$MainMenu .= "<ul class=\"dropdown-menu\" role=\"menu\">";
foreach ($row as $value)
$MainMenu .= '
<li class="divider"></li>
<li class="dropdown">
<a href="/catalog/' . $value->alias . '">
'. $value->name .'
</a> ';
Widgets::BuildTree($value->id);
if ($pid=='0')
$MainMenu .= " <li class=\"divider\"></li></ul>";
return $MainMenu;
else
$MainMenu .= " <li class=\"divider\"></li></ul></li>";
此功能完美运行 :) 我认为@DoktorOSwaldo 是对的,之前的递归是无止境的。
【讨论】:
以上是关于构建树时PHP致命错误内存不足的主要内容,如果未能解决你的问题,请参考以下文章
PHP致命错误:内存不足(分配80740352)(试图分配12352字节)
Composer 要求内存不足。 PHP致命错误:允许的内存大小为1610612736字节已用尽
WordPress PHP致命错误:内存不足(分配2097152)(试图分配4096字节)
如何修复“致命错误:堆限制附近的无效标记压缩分配失败 - JavaScript 堆内存不足”错误