Допустимый размер памяти 134217728 байт исчерпан (пытался выделить 4294967296 байт)

Мой проект использует библиотеку PHP с открытым исходным кодом https://github.com/ajillion/PHP-MySQL-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; } 

Solutions Collecting From Web of "Допустимый размер памяти 134217728 байт исчерпан (пытался выделить 4294967296 байт)"

Я прочитал этот отчет об ошибке здесь: https://bugs.php.net/bug.php?id=51386

longblob ваша проблема возникает из-за longblob или longtext в столбцах таблицы.

longtext / longblob имеют максимальную длину 4294967295 [4 ГБ], поэтому mysqli пытается выделить эту память для буфера, чтобы быть уверенным, что ничего не потеряно. Я бы предположил, что вы используете mediumtext (16777215 [16MB] max length), этого должно быть достаточно для всего, как обычно.

Обновление: поскольку этот ответ видел некоторую активность, я добавляю это решение из Phil_1984 (см. Комментарии)

Я использую mysqli и после прочтения этой цитаты из php dev, добавляя $ stmt-> store_result (); между execute и bind_result, кажется, исправляет проблемы для меня

=> Если вы используете $stmt->store_result() вы можете использовать mysqli с longblob / longtext без получения ошибки.

Старый ответ: Я предлагаю вам либо изменить столбец на другой тип (средний текст), либо использовать PDO (я думаю, что у него нет этой проблемы). но если вы хотите сохранить столбец длинным текстом, вам нужно переключить свою библиотеку mysql

Цитата из PHP Dev:

Это известное ограничение ext / mysqli при использовании libmysql (всегда в 5.2 и предыдущем) и когда libmysql включен с 5.3. Причина в том, что сервер отправляет не слишком конкретные метаданные о столбце. Этот длинный текст имеет максимальную длину 4G, а ext / mysqli пытается связать с максимальной длиной, чтобы не было потери данных (данные не помещаются в буфере привязки на уровне C). Однако это означает 4G для столбца longtext / longblob. ext / mysqli был изменен, чтобы иметь возможность обойти это. Вам нужно вызвать mysqli_stmt_store_result (), который будет хранить данные локально, что означает, конечно, более высокое использование памяти для PHP. Однако, поскольку вы используете libmysql, это наверняка не повлияет на ограничение памяти PHP. Во время store_result будет вычисляться max_length каждого столбца, а затем, когда bind_result выполняется, будет выделен только буфер с размером max_length, который будет определенно ниже 4G. Короче говоря, подготовьте execute store_result bind_result fetch … fetch … fetch

Если вы пытаетесь прочитать за всю таблицу за один раз, и в этой таблице много строк и столбцов, то нехватка памяти неизбежна. Вы можете отключить его, увеличив предел памяти в php.ini, но проблема будет повторяться только при добавлении нескольких тысяч строк.

Вы должны переписать свой сценарий, чтобы быть более разумным о том, что он получает. Если вам нужны только конкретные записи, то вытащить всю таблицу и искать строки, которые вы хотите в результирующем наборе, ужасно неэффективны. Используйте предложение WHERE, чтобы указать, что вы действительно хотите получить. Эмпирическое правило с PHP / SQL-приложениями: «Используйте SQL везде, где это возможно, чтобы указать, что вы хотите, а затем сделайте то, что вам нужно сделать с ним в PHP».

Конечно, возможно, что существует вполне законная причина, по которой вам нужно обработать всю таблицу в PHP. В этом случае вы должны получать данные в кусках (например, по 100 строк за раз) с помощью LIMIT и OFFSET, обрабатывать эти строки, получать следующий фрагмент, обрабатывать эти и так далее, пока не пройдете всю таблицу. Это будет гораздо меньше памяти, чем попытка сразу загрузить всю таблицу

Кажется, не огромный стол! Кажется, бесконечный цикл! Он пытается выделить около 4 ГБ, я не думаю, что у вас такая большая таблица ….

убедитесь, что вы не создаете цикл здесь:

 call_user_func_array (array ($ stmt, 'bind_result'), $ parameters); 

возможно, вы должны опубликовать код, который находится вокруг этой строки.

Вы превысили максимально доступную память. У Yow есть два варианта:

  • Увеличьте максимально допустимую память для каждого скрипта PHP либо по конфигурации (директива memory_limit в php.ini ), либо во время выполнения с помощью ini_set('memory_limit', '200M')

  • Улучшите код, чтобы обрабатывать только необходимую информацию.