2011-01-27 21 views
7

Tengo el siguiente código PHP de prueba bastante simple que extrae los datos y los coloca en texto con formato JSON.Obtener datos de MYSQL en JSON usando PHP

me sale el siguiente error ..

Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 1979603 bytes) in /var/www/test.php on line 33

donde la línea 33 es la línea json_encode().

¿Hay alguna manera de hacerlo más eficiente? ¡El PHP.ini ya está configurado en 32M como máximo, por lo tanto, tiene un tamaño desde el estándar de 8M!

<?php 
    require('../../admin/db_login.php'); 

    $db=mysql_connect($host, $username, $password) or die('Could not connect'); 
    mysql_select_db($db_name, $db) or die(''); 

    $result = mysql_query("SELECT * from listinfo") or die('Could not query'); 
    $json = array(); 

    if(mysql_num_rows($result)){ 
      $row=mysql_fetch_assoc($result); 
     while($row=mysql_fetch_row($result)){ 
      // cast results to specific data types 

      $test_data[]=$row; 
     } 
     $json['testData']=$test_data; 
    } 

    mysql_close($db); 

    echo json_encode($json); 


    ?> 

Respuesta

16

Usted probablemente codifica una muy grande re ataset. Podrías codificar cada fila, una fila a la vez en lugar de codificarla en una operación grande.

<?php 
require('../../admin/db_login.php'); 

$db=mysql_connect($host, $username, $password) or die('Could not connect'); 
mysql_select_db($db_name, $db) or die(''); 

$result = mysql_query("SELECT * from listinfo") or die('Could not query'); 

if(mysql_num_rows($result)){ 
    echo '{"testData":['; 

    $first = true; 
    $row=mysql_fetch_assoc($result); 
    while($row=mysql_fetch_row($result)){ 
     // cast results to specific data types 

     if($first) { 
      $first = false; 
     } else { 
      echo ','; 
     } 
     echo json_encode($row); 
    } 
    echo ']}'; 
} else { 
    echo '[]'; 
} 

mysql_close($db); 

De esa manera, cada llamada a json_encode() sólo se codifica una pequeña matriz en lugar de uno grande. El resultado final es el mismo. Esta es la solución IMO que utilizará menos memoria.

+0

¡Me gusta! ¡Muy agradable! –

+0

@Lee: poco convencional, pero de esa manera no tiene que almacenar cada fila en una matriz para su posterior codificación. –

+0

Sí, un buen enfoque, de hecho, ¡también funciona más rápido! –

0

Como primera solución, configúrela a algo así como 256M o incluso 512M.

Es probable que el conjunto de datos que MySQL le devuelve sea bastante grande. Así que incluso si tu PHP es muy eficiente en la memoria, aún obtendrás el error de OoM. Entonces, como una solución más viable a largo plazo, use la declaración LIMIT (SELECT * FROM $table WHERE 1=1 LIMIT 0,30 (empiece desde el índice 0, obtenga 30 elementos).

EDIT: Oh, wow, ni siquiera vi el problema desde la primera solución ... bueno, todavía podría ser una buena idea para LIMIT su consulta :-)

10

Detener la duplicación de la matriz de datos

$json = array(); 

if(mysql_num_rows($result)){ 
     $row=mysql_fetch_assoc($result); 
    while($row=mysql_fetch_row($result)){ 
     // cast results to specific data types 

     $json['testData'][]=$row; 
    } 
} 

que ayudará a reducir el uso de memoria

+0

Pffff, estaba a punto de escribir exactamente lo mismo ... uno de los buenos Marcos. – acm

+0

sí, yo también: d +1 para eso: D – Edmhs

+0

Sí, buen grito! ¡No me di cuenta de que lo estaba duplicando allí! Eso ha funcionado con 16 bytes, configurando a 64M ahora cabe :-) –

7

Uso ésta:

$result = mysql_query("SELECT * FROM listinfo"); 

$json = array(); 
$total_records = mysql_num_rows($result); 

if($total_records > 0){ 
    while ($row = mysql_fetch_array($result, MYSQL_ASSOC)){ 
    $json[] = $row; 
    } 
} 

echo json_encode($json); 
+1

¿Por qué está usando 'if ($ total_records> = 1) {' y '$ total_records = mysql_num_rows ($ result);'? – neworld

+1

alguna explicación sería agradable –

0

Aquí está mi primer JSON que funciona perfectamente

<?php 
// connect to mysql server 
mysql_connect($host, $username, $password) or die('Could not connect'); 
// select the db name 
mysql_select_db($dbname); 
    // enter your sql query 
    $sql = "Select * from Order_Details"; 
// Creates temp array variable 
$temp = array(); 
// Gets table details 
$result = mysql_query($sql); 
// Adds each records/row to $temp 
while($row=mysql_fetch_row($result)) { 
    $temp[] = $row; 
} 
// Formats json from temp and shows/print on page 
echo json_encode($temp); 
?> 
Cuestiones relacionadas