Du vil opdage, at dette kun sker når @status
er NULL
eller en streng.
Problemet er todelt:
-
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
ogLONGBLOB
. 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. -
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ørmysqli_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.