2012-03-13 7 views
11

Quiero convertir matriz de objetos a JSON codificación, hago como estoJSON de codificación no está trabajando con matriz de objetos

$allVisits = $mapper->getAllVisits($year, $month); 
echo json_encode($allVisits); 

y aquí es getAllVisists método

function getAllVisits($year, $month) { 
    $where = array(
     'year = ?' => $year, 
     'month = ?' => $month 
    ); 
    $resultSet = $this->getDbTable()->fetchAll($where); 
    $visitsEntries = array(); 
    foreach ($resultSet as $row) { 

     $entry = new Visits_Model_Visit(); 
     $entry->setId($row->visit_id) 
       ->setDay($row->day) 
       ->setDate($row->date) 
       ->setTarget($row->target) 
       ->setStatus($row->visit_status) 
       ->setTime($row->visit_time); 

     $visitsEntries[] = $entry; 
    } 
    return $visitsEntries; 
} 

cuando me hago eco de la tamaño de $ allVisits devuélvalo número correcto de registros, pero en js los valores se reciben vacío como esto [{}, {}, {}, {}]

Editar

Cuando print_r ($ allVisists) brfore que lo codifica vuelve

Array 
(
    [0] => Visits_Model_Visit Object 
     (
      [day:private] => sunday 
      [date:private] => 2012-03-06 
      [target:private] => شسي 
      [id:private] => 1 
      [status:private] => 0 
      [time:private] => 12:00:00 
     ) 

    [1] => Visits_Model_Visit Object 
     (
      [day:private] => sunday 
      [date:private] => 2012-03-06 
      [target:private] => clinnics 
      [id:private] => 4 
      [status:private] => 0 
      [time:private] => 00:00:00 
     ) 

    [2] => Visits_Model_Visit Object 
     (
      [day:private] => Tuesday 
      [date:private] => 2012-03-06 
      [target:private] => clinnics 
      [id:private] => 5 
      [status:private] => 0 
      [time:private] => 00:00:00 
     ) 

    [3] => Visits_Model_Visit Object 
     (
      [day:private] => Wednesday 
      [date:private] => 2012-03-28 
      [target:private] => ??????? ??????? 
      [id:private] => 7 
      [status:private] => 0 
      [time:private] => 12:00:00 
     ) 

) 
+0

¿Has probado 'print_r ($ allVisits)' antes de llamar a 'json_encode'? – jerrymouse

+0

Imprime la matriz correctamente – palAlaa

Respuesta

15

está usando el json_encode con objetos que no tienen ningún miembros del público. json_encode solo funciona en los miembros que puede "ver", es por eso que están vacíos.

A partir de PHP 5.4 se puede hacer uso de la JsonSerializable interface para controlar qué datos se ofrecen para json_encode, por ejemplo:

class Visits_Model_Visit implements JsonSerializable { 
    ... 
    public function jsonSerialize() { 
     return (object) get_object_vars($this); 
    } 
    ... 
} 

Si está por debajo 5.4 también se puede implementar esa función w/o se extiende desde el interfaz y luego asignar el valor correcto manualmente:

$visitsEntries[] = $entry->jsonSerialize(); 

Espero que esto ayude.

+0

Puede implementar JsonSerializable en versiones anteriores de PHP si sigues mi enfoque a continuación: – Westy92

5

son propiedad privada o protegida para el objeto? Si es así, json encode no puede verlos dentro del objeto. Lo soluciono creando un método 'toJson' en mis objetos que necesito serializar en json. En este método, recorro las propiedades de los objetos y construyo manualmente un objeto genérico, que paso a json_encode. Luego devuelvo la cadena Json de este método.

¡No solo haga públicas todas las propiedades de sus objetos!

+1

De acuerdo. Sería un error estar en desacuerdo con el último consejo de Ray. – Jake

4

Como dice Ray si las propiedades de su clase están protegidas o son privadas, estas no serán escuchadas.

Desde PHP 5.4 en lugar de utilizar el método comment toJson, tiene la capacidad de especificar qué datos se serializarán implementando la interfaz JsonSerializable, por lo que json_encode sabe cómo trabajar en esto.

/* PHP >= 5.4 only */ 
class Visits_Model_Visit implement JsonSerializable { 
    public function jsonSerialize() 
    { 
     return array(
      'day' => $this->day, 
      'date' => $this->date, 
      'target' => $this->target, 
      'id' => $this->id, 
      'status' => $this->status, 
     ); 
    } 
} 
+0

Yay para 5.4. Esto limpiará media docena de mis API internas. Los dedos cruzaron la actualización no rompe mi servidor. – Jake

+0

@arraintxo empresa se acaba de actualizar a PHP 5.3 :(No entiendo la interfaz JsonSerializable. – Ray

+0

@Ray, mi solución permite implementar JsonSerialable en versiones anteriores de PHP. – Westy92

2

De forma predeterminada, json_encode() solo serializa las propiedades públicas de un objeto. Hacer que todas las propiedades que desee publique en serie sea ¡NO la solución! PHP 5.4 y posterior tiene la interfaz JsonSerializable, pero propongo una solución directa para las versiones anteriores de PHP.

Como JsonSerializable es solo una parte de PHP 5.4 y posterior, créelo usted mismo.

if (!interface_exists('JsonSerializable')) { 
    interface JsonSerializable { 
     public function jsonSerialize(); 
    } 
} 

Eso no fue tan difícil, ¿verdad? ¡Ahora podemos implementar JsonSerializable sin preocuparnos por la versión de PHP que estamos usando!

class Visits_Model_Visit implements JsonSerializable { 
    ... 
    // Only put properties here that you want serialized. 
    public function jsonSerialize() { 
     return Array(
      'day' => $this->day, 
      'date' => $this->date, 
      'target' => $this->target, 
      'id'  => $this->id, 
      'status' => $this->status, 
      'obj' => $this->obj->jsonSerialize(), // example for other objects 
      'time' => $this->time 
     ); 
    } 
    ... 
} 

Ahora puede simplemente llamar jsonSerialize() para obtener una matriz asociativa que se puede codificar con json_encode().

... 
    $entry = new Visits_Model_Visit(); 
    $entry->setId($row->visit_id) 
      ->setDay($row->day) 
      ->setDate($row->date) 
      ->setTarget($row->target) 
      ->setStatus($row->visit_status) 
      ->setTime($row->visit_time); 

    $visitsEntries[] = $entry->jsonSerialize(); 
    ... 

A continuación, puede llamar json_encode($visitsEntries) para obtener el resultado deseado.

[ 
    { 
     "day":"sunday", 
     "date":"2012-03-06", 
     "target":"\u0634\u0633\u064a", 
     "id":1, 
     "status":0, 
     "time":"12:00:00" 
    }, 
    { 
     "day":"sunday", 
     "date":"2012-03-06", 
     "target":"clinnics", 
     "id":4, 
     "status":0, 
     "time":"00:00:00" 
    }, 
    ... 
] 
+0

¿Por qué matriz? Quiero objeto - y la pregunta es "... matriz de OBJETOS" – Srneczek

+0

Una matriz asociativa porque cuando llamas a json_encode() en ella, se convertirá a la notación JSON adecuada para un objeto. Las claves en la matriz serán los nombres de las propiedades "objeto", y los valores serán, bueno, los valores de esas propiedades. Actualizaré mi respuesta con el resultado final. – Westy92

+0

Actualice mi comentario: json_encode() en realidad no comprueba si pasa en una matriz u objeto, por lo que tiene que convertirlo explícitamente en lo que necesite en la salida. Así que la matriz está bien, es solo PHP que esperaba ser más inteligente de lo que realmente es. – Srneczek

0

Para aquellos que están buscando una respuesta simple , a diferencia de otras respuestas complicadas mi es obra de arte:

json_encode(array(
    Protocol::PARAM_CODE => Protocol::CODE_SUCCESS, 
    Protocol::PARAM_USER => (object)$user->jsonSerialize() 
)); 

Incluso cuando $ usuario-> jsonSerialize() muestra stdObject, json_encode es tan tonto, no tiene idea de que es un objeto, así que tienes que decir que explícitamente con fundirlo en (objeto) - ¿no te encanta PHP por su simplicidad?

+0

¿Cómo funciona esto exactamente? – user431806

+0

¿cómo funciona qué? ¿casting en PHP? – Srneczek

+0

No. La clase Protocol :: class a la que hace referencia – user431806

Cuestiones relacionadas