2011-01-27 5 views
7

J'ai le code PHP de test assez simple qui suit extrait les données et les met en texte formaté JSON.Obtenir des données de MYSQL dans JSON en utilisant PHP

je reçois l'erreur suivante ..

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

Où la ligne 33 est la ligne json_encode().

Y at-il un moyen de rendre cela plus efficace? Le PHP.ini est déjà réglé sur 32M au maximum, donc dimensionné à partir de la norme 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); 


    ?> 

Répondre

16

Vous encodez probablement un très grand ré ataset. Vous pouvez encoder chaque ligne, une rangée à la fois au lieu de l'encoder en une seule opération.

<?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 cette façon, chaque appel à json_encode() encode uniquement un petit tableau au lieu d'un grand. Le résultat est le même. Ceci est la solution IMO qui utilisera le moins de mémoire.

+0

J'aime ça! Très agréable! –

+0

@Lee: non conventionnel, mais de cette façon vous n'avez pas besoin de stocker chaque ligne dans un tableau pour un encodage ultérieur. –

+0

Ouais, une belle approche en effet, ça marche plus vite aussi! –

0

Dans un premier temps de travail, réglez-le à quelque chose comme 256M ou même 512M.

Il est probable que l'ensemble de données que MySQL vous renvoie soit assez grand. Donc, même si votre PHP est très efficace en termes de mémoire, vous aurez toujours l'erreur OoM. Donc, comme une solution à long terme plus viable utiliser l'instruction LIMIT (SELECT * FROM $table WHERE 1=1 LIMIT 0,30 (commencer à partir de l'indice 0, obtenir 30 articles)

EDIT: Oh wow, je n'ai même pas vu le problème de la première solution ... Eh bien, peut-être encore une bonne idée de LIMIT votre requête :-)

10

Arrêtez dupliquer votre tableau de données

$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; 
    } 
} 

qui aidera à réduire votre utilisation de la mémoire

+0

Pffff, était sur le point d'écrire exactement la même chose ... Nice one Mark. – acm

+0

oui mee aussi: d +1 pour ça: D – Edmhs

+0

Oui bon cri! Je n'ai pas réalisé que je le reproduisais du tout! Cela a fonctionné avec 16 octets de plus, le réglage à 64M maintenant il convient :-) –

7

Utilisez celui-ci:

$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

Pourquoi utilisez-vous 'if ($ total_records> = 1) {' et '$ total_records = mysql_num_rows ($ result);'? – neworld

+1

une explication serait bien –

0

Voici mon premier JSON qui fonctionne parfaitement

<?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); 
?> 
Questions connexes