Json encode не работает с массивом объектов

Я хочу преобразовать массив объектов в json-кодировку, я делаю вот так

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

и здесь метод 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;
}

когда я повторяю размер $allVisits, он возвращает правильное количество записей, но в js значения принимаются пустым, как это [{}, {}, {}, {}]

Edit

Когда я print_r ($ allVisists) перекодирует его, он возвращает

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
        )

)

Ответ 1

Вы используете json_encode с объектами, которые не имеют каких-либо публичных элементов. json_encode работает только с теми членами, которые он может "видеть", поэтому они пусты.

Начиная с PHP 5.4 вы можете использовать JsonSerializable interface для управления тем, какие данные будут предложены для json_encode, например:

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

Если вы находитесь ниже 5.4, вы также можете реализовать эту функцию без расширения, а затем назначить правильное значение вручную:

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

Надеюсь, что это поможет.

Ответ 2

Являются ли свойства частными или защищенными для объекта? Если это так, json encode не может видеть их внутри объекта. Я обойду это, создав метод "toJson" в своих объектах, который мне нужно сериализовать в json. В этом методе я прохожу свойства объектов и вручную создаю общий объект, который я передаю в json_encode. Затем я возвращаю строку Json из этого метода.

Не просто публиковать все свойства объекта!!!!

Ответ 3

Как говорит Рэй, если ваши свойства класса защищены или закрыты, они не будут отменены.

Поскольку PHP 5.4 вместо использования метода commented toJson, вы можете указать, какие данные будут сериализованы, реализуя интерфейс JsonSerializable, поэтому json_encode знает, как работать с этим.

/* 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,
        );
    }
}

Ответ 4

По умолчанию json_encode() только сериализует общедоступные свойства объекта. Создание всех свойств, которые вы хотите получить от сериализованного сообщества, НЕ является решением! PHP 5.4 и более поздние версии имеют интерфейс JsonSerializable, но я предлагаю простое решение для более ранних версий PHP.

Так как JsonSerializable является частью PHP 5.4 и более поздних версий, создайте его самостоятельно.

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

Это было не так сложно, не так ли? Теперь мы можем реализовать JsonSerializable, не беспокоясь о том, какую версию PHP мы используем!

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

Теперь вы можете просто вызвать jsonSerialize(), чтобы получить ассоциативный массив, который вы можете кодировать с помощью 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();
    ...

Затем вы можете вызвать json_encode($visitsEntries), чтобы получить желаемый результат.

[
   {
      "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"
   },
   ...
]

Ответ 5

Для тех, кто ищет простой ответ, в отличие от других сложных ответов, я - это произведение искусства:

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

Даже когда $user- > jsonSerialize() выводит stdObject, json_encode настолько тупой, он не имеет понятия, что это объект, поэтому вам нужно указать явно с литьем его в (объект ) - вам не нравится PHP для простоты?