2012-03-13 10 views
11

chcę przekonwertować tablicę obiektów do kodowania json, robię jak tenjson kodowanie nie jest praca z tablicą obiektów

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

i oto jest metoda getAllVisists

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

kiedy echo wielkość $ allVisits zwróci poprawną liczbę rekordów, ale w js wartości odbierane są puste jak ta [{} {} {} {}]

Edit

Kiedy print_r ($ allVisists) brfore kodującego go zwraca

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

Czy próbowałeś 'print_r ($ allVisits)' przed wywołaniem 'json_encode'? – jerrymouse

+0

Drukuje poprawnie tablicę – palAlaa

Odpowiedz

15

Używasz json_encode z obiektami, które nie mają żadnych publicznych członków. json_encode działa tylko na elementach, które może "zobaczyć", dlatego są puste.

Od PHP 5.4 można skorzystać z JsonSerializable interface kontrolować, które dane zostaną zaoferowane do json_encode, np:

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

Jeśli jesteś poniżej 5.4 można również realizować tę funkcję w/o rozciągającą się od interfejs i następnie przypisanie właściwej wartości ręcznie:

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

Mam nadzieję, że to pomoże.

+0

Możesz zaimplementować JsonSerializable we wcześniejszych wersjach PHP jeśli podążasz za moim podejściem poniżej: – Westy92

5

Czy właściwości prywatne lub chronione dla obiektu? Jeśli tak, to kodowanie JSON nie może ich zobaczyć wewnątrz obiektu. Rozumiem to poprzez stworzenie metody "toJson" w moich obiektach, którą muszę serializować w json. W tej metodzie chodzę po właściwościach obiektów i ręcznie konstruuję obiekt ogólny, który przekazuję do json_encode. Następnie zwracam ciąg Json z tej metody.

Nie tylko upublicznij wszystkie właściwości swoich obiektów !!!!

+1

Uzgodniono. Myliłbyś się, aby nie zgodzić się z ostatnią radą Raya. – Jake

4

Jak mówi Ray, jeśli twoje właściwości klasy są chronione lub prywatne, nie zostaną one przeniesione.

Od PHP 5.4 zamiast używania skomentowanej metody toJson, masz możliwość określenia, które dane będą serializowane za pomocą interfejsu JsonSerializable, więc json_encode wie, jak pracować nad tym.

/* 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 dla 5.4. Spowoduje to wyczyszczenie pół tuzina moich wewnętrznych api. Palce przekroczyły aktualizację, nie psują mojego serwera. – Jake

+0

@arraintxo moja firma właśnie aktualizuje się do wersji 5.3 :(Nie mam interfejsu JsonSerializable – Ray

+0

@Ray, moje rozwiązanie pozwala zaimplementować JsonSerialable we wcześniejszych wersjach PHP – Westy92

2

Domyślnie json_encode() tylko serializuje publiczne właściwości obiektu. Tworzenie wszystkich właściwości, które chcesz serializować publicznie jest NOT rozwiązanie! PHP 5.4 i nowsze wersje mają interfejs JsonSerializable, ale proponuję proste rozwiązanie dla wcześniejszych wersji PHP.

Ponieważ JsonSerializable to tylko część PHP 5.4 i późniejszych, należy ją utworzyć samodzielnie.

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

To nie było takie trudne, prawda? Teraz możemy zaimplementować JsonSerializable bez obawy o to, jakiej wersji PHP używamy!

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 
     ); 
    } 
    ... 
} 

Teraz można po prostu zadzwonić jsonSerialize(), aby uzyskać tablicę asocjacyjną, które można zakodować z 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(); 
    ... 

Możesz następnie zadzwonić pod numer json_encode($visitsEntries), aby uzyskać pożądany wynik.

[ 
    { 
     "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

Dlaczego tablica? Chcę obiektu - i pytanie brzmi "... tablica obiektów" – Srneczek

+0

Tablica asocjacyjna, ponieważ po wywołaniu json_encode() na niej, zostanie przekonwertowana na prawidłową notację JSON dla Obiekt: klucze w tablicy będą nazwami właściwości obiektu, a wartości będą, no cóż, wartościami tych właściwości, zaktualizuję odpowiedź z wynikiem końcowym – Westy92

+0

Zaktualizuj mój komentarz: json_encode() faktycznie nie sprawdza, czy przechodzisz w tablicy lub obiekcie, więc musisz jawnie rzucić go na to, czego potrzebujesz na wyjściu. Więc tablica jest w porządku, to po prostu PHP, którego oczekiwałem, że będzie mądrzejszy, niż jest w rzeczywistości. – Srneczek

0

Dla tych, którzy szukają prostą odpowiedź, w przeciwieństwie do innych skomplikowanych odpowiedzi mój jest dzieło sztuki:

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

Nawet gdy $ user-> jsonSerialize() wyprowadza stdObject, json_encode jest tak głupi, nie ma pojęcia, że ​​to jest obiekt, więc musisz stwierdzić, że jawnie z odlewaniem go do (obiekt) - czy nie lubisz PHP, ponieważ jest to prostota?

+0

Jak dokładnie to działa? – user431806

+0

jak to działa? casting w PHP? – Srneczek

+0

Nie. Klasa Protocol ::, do której się odwołuje – user431806