sql >> Database teknologi >  >> RDS >> Mysql

PHP mysql_stmt::fetch() giver PHP fatal fejlhukommelse opbrugt

Du vil opdage, at dette kun sker når @status er NULL eller en streng.

Problemet er todelt:

  1. I modsætning til lokale variabler , MySQL brugervariabler understøtter et meget begrænset sæt datatyper:

    Dokumentationen nævner ikke, at de faktiske datatyper brugt er henholdsvis BIGINT , DECIMAL(65,30) , DOUBLE , LONGBLOB , LONGTEXT og LONGBLOB . Med hensyn til den sidste forklarer manualen i det mindste:

    Opbevaring af de første tre af disse datatyper (dvs. for heltal-, decimal- og flydende kommaværdier) kræver henholdsvis 8, 30 og 8 bytes. De andre datatyper (dvs. for streng og NULL værdier) kræver (op til) 4 gigabyte lagerplads.

  2. Da du bruger en version af PHP før v5.4.0, er standard MySQL-driveren libmysql , hvormed kun kolonnetype-metadata er tilgængelige fra serveren ved databinding - så MySQLi forsøger at allokere tilstrækkelig hukommelse til at holde alle mulige værdier (selvom den fulde buffer i sidste ende ikke er påkrævet); altså NULL - og brugervariabler med strengværdi, som har en maksimal mulig størrelse på 4GiB, får PHP til at overskride standardhukommelsesgrænsen (på 128MiB siden PHP v5.2.0).

Dine muligheder omfatter:

  • Tilsidesættelse af kolonnedatatypen i tabeldefinitionen:

    DROP TEMPORARY TABLE IF EXISTS tmp_table;
    CREATE TEMPORARY TABLE tmp_table (
      status VARCHAR(2)
    ) SELECT @status AS status;
    
  • Eksplicit casting brugervariablen til en mere specifik datatype:

    DROP TEMPORARY TABLE IF EXISTS tmp_table;
    CREATE TEMPORARY TABLE tmp_table
      SELECT CAST(@status AS CHAR(2)) AS status;
    
  • Brug af lokale variabler, som er deklareret med en eksplicit datatype:

    DECLARE status VARCHAR(2) DEFAULT @status;
    DROP TEMPORARY TABLE IF EXISTS tmp_table;
    CREATE TEMPORARY TABLE tmp_table
      SELECT status;
    
  • Løsning af problemet ved at kalde mysqli_stmt::store_result() før mysqli_stmt::bind_result() , hvilket får resultatsættet til at blive lagret i libmysql (uden for PHPs hukommelsesgrænser), og derefter vil PHP kun allokere den faktiske hukommelse, der kræves til at holde posten, når den hentes:

    $stmt->execute();
    $stmt->store_result();
    $stmt->bind_result( $status );
    $stmt->fetch();
    
  • Hæver PHPs hukommelsesgrænse så det kan imødekomme tildelingen af ​​4GiB-buffere (selvom man bør være opmærksom på implikationerne for hardwareressourcer af at gøre det) - for eksempel for at fjerne hukommelsesbegrænsningerne helt (selvom vær opmærksom på potentielle negative bivirkninger ved at gøre dette, fx fra ægte hukommelseslækager):

    ini_set('memory_limit', '-1');
    
  • Genkompilering af PHP, konfigureret til at bruge den oprindelige mysqlnd-driver (inkluderet med PHP siden v5.3.0, men ikke konfigureret som standard før PHP v5.4.0) i stedet for libmysql:

    ./configure --with-mysqli=mysqlnd
    
  • Opgradering til PHP v5.4.0 eller nyere, så mysqlnd bruges som standard.




  1. SQLite JSON_REMOVE()

  2. hvordan opretter man login-side i Android-appen?

  3. MySQL 5.6 DATETIME accepterer ikke millisekunder/mikrosekunder

  4. JDBC ResultSet:Jeg har brug for en getDateTime, men der er kun getDate og getTimeStamp