php json encode无法处理对象数组

sauutmhj  于 2023-06-04  发布在  PHP
关注(0)|答案(5)|浏览(221)

我想把数组对象转换成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中,接收到的值为空,如[{},{},{}]

编辑

当我在编码前打印_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
        )

)
e4eetjau

e4eetjau1#

您正在对没有任何公共成员的对象使用json_encodejson_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,你也可以实现这个函数,w/o从接口扩展,然后手动分配正确的值:

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

希望这能帮上忙。

mu0hgdu0

mu0hgdu02#

正如Ray所说,如果你的类属性是protected或private的,这些属性将不会被jsoned。
由于PHP 5.4没有使用注解的toJson方法,您可以指定哪些数据将被序列化,实现JsonSerializable接口,因此json_encode知道如何处理这一点。

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

u5i3ibmn3#

默认情况下,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"
   },
   ...
]
f0ofjuux

f0ofjuux4#

对象的属性是私有的还是受保护的?如果是这样,json encode就无法在对象内部看到它们。我通过在我需要序列化为json的对象中创建一个'toJson'方法来解决这个问题。在这个方法中,我遍历对象属性并手动构造一个通用对象,然后将其传递给json_encode。然后我从这个方法返回JSON字符串。
不要只是将所有对象属性都公开!!!!

bwitn5fc

bwitn5fc5#

对于那些正在寻找简单答案的人来说,与其他复杂答案不同,我的答案是一件艺术品:

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

即使当$user->jsonSerialize()输出stdObject时,json_encode也是如此愚蠢,它不知道它是对象,所以你必须通过将其转换为**(object)来声明显式**-难道你不喜欢PHP的简单性吗?

相关问题