Mysql
 sql >> база данни >  >> RDS >> Mysql

PHP mysql_stmt::fetch() дава на PHP паметта за фатални грешки изчерпана

Ще откриете, че това се случва само когато @status е NULL или низ.

Проблемът е двоен:

  1. За разлика от локалните променливи , MySQL потребителски променливи поддържат много ограничен набор от типове данни:

    В документацията не се споменава, че действителните типове данни използвани са съответно BIGINT , DECIMAL(65,30) , DOUBLE , LONGBLOB , LONGTEXT и LONGBLOB . По отношение на последното ръководството поне обяснява:

    Съхранение от първите три от тези типове данни (т.е. за цели числа, десетични стойности и стойности с плаваща запетая) изискват съответно 8, 30 и 8 байта. Другите типове данни (т.е. за низ и NULL стойности) изискват (до) 4 гигабайта на съхранение.

  2. Тъй като използвате версия на PHP преди v5.4.0, драйверът за MySQL по подразбиране е libmysql , с който само метаданни от тип колона са достъпни от сървъра при обвързване на данни – така че MySQLi се опитва да разпредели достатъчно памет, за да задържи всяка възможна стойност (дори ако пълният буфер в крайна сметка не е необходим); така NULL - и потребителски променливи с низови стойности, които имат максимален възможен размер от 4GiB, карат PHP да надвиши лимита си за памет по подразбиране (от 128MiB от PHP v5.2.0).

Вашите опции включват:

  • Отмяна на типа данни на колоната в дефиницията на таблицата:

    DROP TEMPORARY TABLE IF EXISTS tmp_table;
    CREATE TEMPORARY TABLE tmp_table (
      status VARCHAR(2)
    ) SELECT @status AS status;
    
  • Изрично прехвърляне потребителската променлива към по-специфичен тип данни:

    DROP TEMPORARY TABLE IF EXISTS tmp_table;
    CREATE TEMPORARY TABLE tmp_table
      SELECT CAST(@status AS CHAR(2)) AS status;
    
  • Използване на локални променливи, които са декларирани с изричен тип данни:

    DECLARE status VARCHAR(2) DEFAULT @status;
    DROP TEMPORARY TABLE IF EXISTS tmp_table;
    CREATE TEMPORARY TABLE tmp_table
      SELECT status;
    
  • Заобикаляне на проблема чрез извикване на mysqli_stmt::store_result() преди mysqli_stmt::bind_result() , което кара набора от резултати да се съхранява в libmysql (извън ограниченията на паметта на PHP) и след това PHP ще разпредели само действителната памет, необходима за съхраняване на записа при изтеглянето му:

    $stmt->execute();
    $stmt->store_result();
    $stmt->bind_result( $status );
    $stmt->fetch();
    
  • Повишаване на лимит на паметта на PHP така че да може да побере разпределението на 4GiB буфери (въпреки че човек трябва да е наясно с последиците за хардуерните ресурси от това) - например, за да премахне изцяло ограниченията на паметта (въпреки че е наясно с потенциалните отрицателни странични ефекти от това, например от изтичане на истинска памет):

    ini_set('memory_limit', '-1');
    
  • Прекомпилиране на PHP, конфигуриран да използва родния драйвер за mysqlnd (включен с PHP от v5.3.0, но не е конфигуриран по подразбиране до PHP v5.4.0) вместо libmysql:

    ./configure --with-mysqli=mysqlnd
    
  • Надстройка до PHP v5.4.0 или по-нова версия, така че mysqlnd да се използва по подразбиране.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как работи Hibernate Batch insert?

  2. MYSQL last_insert_id() и едновременност

  3. MySQL &PHP:Търсене по множество ключови думи

  4. LOAD DATA LOCAL INFILE дава грешка. Използваната команда не е разрешена с тази версия на MySQL

  5. Play 2.4 - Slick 3.0.0 - DELETE не работи