2012-02-19 22 views
6

He pasado un par de horas mirando varias respuestas similares antes de publicar mi problema.PHP: no se puede codificar json con varias filas

Estoy recuperando datos de una tabla en mi base de datos, y quiero codificarlos en un JSON. Sin embargo, el resultado de json_encode() solo es válido cuando la tabla tiene una sola fila. Si hay más de una fila, la prueba en http://jsonlint.com/ devuelve un error.

Esta es mi consulta:

$result = mysql_query($query); 

    $rows = array(); 

    //retrieve and print every record 
    while($r = mysql_fetch_assoc($result)){ 
     $rows['data'] = $r; 

     //echo result as json 
     echo json_encode($rows); 
    } 

que me pone el siguiente JSON:

{ 
"data": 
    { 
     "entry_id":"2", 
     "entry_type":"Information Relevant to the Subject", 
     "entry":"This is my second entry." 
    } 
} 


{ 
"data":{ 
     "entry_id":"1", 
     "entry_type":"My Opinion About What Happened", 
     "entry":"This is my first entry." 
    } 
} 

Cuando ejecuto la prueba en http://jsonlint.com/, devuelve este error:

Parse error on line 29: 
    ..."No comment" }}{ "data": {  
    ---------------------^ 
    Expecting 'EOF', '}', ',', ']' 

Sin embargo, si solo uso esta primera mitad de JSON ...

{ 
"data": 
    { 
     "entry_id":"2", 
     "entry_type":"Information Relevant to the Subject", 
     "entry":"This is my second entry." 
    } 
} 

... o si sólo probar la segunda mitad ...

{ 
    "data":{ 
     "entry_id":"1", 
     "entry_type":"My Opinion About What Happened", 
     "entry":"This is my first entry." 
    } 
} 

... la misma prueba volverá "Válido JSON".

Lo que quiero es poder generar en un solo JSON [válido] cada fila en la tabla.

Cualquier sugerencia será muy apreciada.

Respuesta

14

El problema es que estás escupiendo separada JSON para cada fila, en lugar de hacer todo a la vez.

$result = mysql_query($query); 

$rows = array(); 

//retrieve and print every record 
while($r = mysql_fetch_assoc($result)){ 
    // $rows[] = $r; has the same effect, without the superfluous data attribute 
    $rows[] = array('data' => $r); 
} 

// now all the rows have been fetched, it can be encoded 
echo json_encode($rows); 

El pequeño cambio que he hecho es almacenar cada fila de la base de datos como un nuevo valor en la matriz $rows. Esto significa que cuando haya terminado, su matriz $rows contiene todas de las filas de su consulta, y así puede obtener el resultado correcto una vez que haya finalizado.

El problema con su solución es que está haciendo eco de JSON válido para una fila de la base de datos, pero json_encode() no conoce todas las otras filas, por lo que obtiene una sucesión de objetos JSON individuales, en oposición a uno solo que contiene una matriz.

+0

¡Muchas gracias! Toda la solución funciona, y la suya proporciona la explicación más completa. No solo esto es correcto, sino que ignoro por completo que los otros ejemplos colocan la función json_encode fuera del ciclo while. Me disculpo por no darme cuenta, y gracias por su tiempo. – asraelarcangel

3

necesita cambiar su código PHP en algo como esto:

$result = mysql_query($query); 

$rows = array(); 

//retrieve every record and put it into an array that we can later turn into JSON 
while($r = mysql_fetch_assoc($result)){ 
    $rows[]['data'] = $r; 
} 
//echo result as json 
echo json_encode($rows); 
+0

+1 de mí también :-) –

+0

Gracias, esto también funciona. – asraelarcangel

0

creo que debe hacer

$rows = array(); 
while($r = mysql_fetch_assoc($result)){ 
    $rows[]['data'] = $r; 
} 
echo json_encode($rows); 

eco debe ser colocado fuera del bucle.

+1

sí, pero esto sobrescribirá $ rows ['data'] cada vez que el script pasa por el ciclo while, por lo que no funcionará :) – Daan

+1

Gracias, no lo noté solo copié y pegué su código pero lo arreglé ahora . –

+0

Gracias por su solución. Lo probé y funciona bien. – asraelarcangel

0

yo estaba tratando de la misma en mi PHP, así que vine Whit esto ...

$find = mysql_query("SELECT Id,nombre, appaterno, apmaterno, semestre, seccion, carrera FROM Alumno"); 

    //check that records exist 
    if(mysql_num_rows($find)>0) { 
     $response= array(); 
     $response["success"] = 1; 

     while($line = mysql_fetch_assoc($find)){} 
      $response[] = $line; //This worked for me 
     } 

     echo json_encode($response); 

    } else { 
     //Return error 
     $response["success"] = 0; 
     $response["error"] = 1; 
     $response["error_msg"] = "Alumno could not be found"; 
     echo json_encode($response); 
    } 

Y, en mi clase de Android ...

if (Integer.parseInt(json.getString("success")) == 1) { 

        Iterator<String> iter = json.keys(); 
        while (iter.hasNext()) { 
         String key = iter.next(); 
         try { 
          Object value = json.get(key); 
          if (!value.equals(1)) { 

           JSONObject jsonArray = (JSONObject) value; 

           int id = jsonArray.getInt("Id"); 
           if (!db.ExisteAlumo(id)) { 
            Log.e("DB EXISTE:","INN"); 
            Alumno a = new Alumno(); 

            int carrera=0; 
            a.setId_alumno(id); 
            a.setNombre(jsonArray.getString("nombre")); 
            a.setAp_paterno(jsonArray.getString("appaterno")); 
            a.setAp_materno(jsonArray.getString("apmaterno")); 
            a.setSemestre(Integer.valueOf(jsonArray.getString("semestre"))); 
            a.setSeccion(jsonArray.getString("seccion")); 
            if(jsonArray.getString("carrera").equals("C")) 
             carrera=1; 
            if(jsonArray.getString("carrera").equals("E")) 
             carrera=2; 
            if(jsonArray.getString("carrera").equals("M")) 
             carrera=3; 
            if(jsonArray.getString("carrera").equals("S")) 
             carrera=4; 
            a.setCarrera(carrera); 

            db.addAlumno(a); 

           } 

          } 
         } catch (JSONException e) { 
          // Something went wrong! 
         } 

       } 
0

I tienen que haber pasado 15 horas en este tema.Se intentó cada variación discutida anteriormente. Finalmente pude obtener la 'solución estándar' funcionando. El problema, muy extraño, parece ser este:

Cuando el intervalo se establece más allá de 14 horas, parece que json no puede analizarlo. Debe haber un límite para JSON.

$sql= "SELECT cpu_name, used, timestamp FROM tbl_cpu_use WHERE timestamp>(NOW() - INTERVAL 14 HOUR) ORDER BY id"; 
$result=mysql_query($sql); 
if ($result){ 
    $i=0; 
    $return =[]; 
    while($row = mysql_fetch_array($result, MYSQL_NUM)){ 
     $rows[] = $row; 
    } 
    echo json_encode($rows); 
}else{ 
    echo "ERROR"; 
}