【问题标题】:Slim framework unable to encode to json with protected variablesSlim 框架无法使用受保护的变量编码为 json
【发布时间】:2016-12-16 00:07:54
【问题描述】:

基本上,我使用 json 编码响应,无法弄清楚为什么它一直返回正确数量的数组成员,但它们是空的。

 $app->get('/api/server_list', function ($request, $response, $args) {
 $serverlist = new ServerListing($this->db);
 $servers = $serverlist->getServers();
 $newResponse = $response->withJson($servers);
 return $newResponse;    
 });

这是上面的输出,添加了 print_r($servers)

[{},{}]Array
(
    [0] => ServerEntity Object
        (
            [id:protected] => 1
            [serverName:protected] => dc1.domain.com
        )

    [1] => ServerEntity Object
        (
            [id:protected] => 2
            [serverName:protected] => dc2.domain.com
        )

)

ServerListing 的类代码如下:

 <?php

class ServerListing extends Listing
{
    public function getServers() {
        $sql = "SELECT * from servers";
        $stmt = $this->db->query($sql);

        $results = [];

        while($row = $stmt->fetch()) {
            $results[] = new ServerEntity($row);
        }
        return $results;
    }
}

这里是服务器实体:

 <?php

 class ServerEntity
 {
     public $id;
     public $serverName;

     public function __construct(array $data) {

         if(isset($data['id'])) {
             $this->id = $data['id'];
          }

         $this->serverName = $data['name'];
     }

         public function getId() {
             return $this->id;
     }
         public function getServerName() {
             return $this->serverName;
     }

 }

它的唯一工作方式是公开。

我了解公共/私人/受保护。虽然这是我第一次使用框架和面向对象的 php。

在另一个路由中使用相同的数据库调用,然后我可以将服务器列表传递给一个视图,它工作正常。

所以我猜有两个问题。

  1. json 编码为什么会失败?
  2. 我做错了什么/有没有更好的方法来做到这一点?

【问题讨论】:

    标签: php json slim


    【解决方案1】:

    Slim 的Response::withJson() 没有任何神奇之处。它依赖 PHP 函数 json_encode() 进行编码。 json_encode() 也不知道有什么特别的技巧。如果您将一个对象传递给它进行编码,它会获得它可以从中获得的所有数据。这仅意味着它的公共属性,因为这就是 OOP 的工作方式。

    但是,如果您在一个类中实现了JsonSerializable 接口,那么在编码该类的对象时,您可以控制json_encode() 可用的数据。

    例如:

    class ServerEntity implements JsonSerializable
    {
        private $id;
        private $serverName;
    
        // ... your existing code here
    
        public function jsonSerialize()
        {
            return array(
                'id'   => $this->id,
                'name' => $this->serverName,
            );
        }
    }
    

    一些测试代码:

    echo(json_encode(new ServerEntity(array('id' => 7, 'name' => 'foo'))));
    

    输出是:

    {"id":7,"name":"foo"}
    

    【讨论】:

    • 好吧,这是有道理的。我并没有真正意识到幕后发生了什么。谢谢你的解释。
    【解决方案2】:

    简而言之,一个对象可以转换成一个数组。

    对象的公共属性将用作数组中的$key =&gt; $value 对。

    由于属性受到保护,因此不包括值。

    虽然数组实际上为空似乎是合乎逻辑的,但 PHP 将对象转换为数组的过程并没有得到足够好的记录。

    在实践中,我建议您创建一个将 Object 转换为数组的公共方法。

    class ServerEntity {
     //...
        public function toArray() {
             return array("id" => $this->id, "name" => $this->name);
        }
     //...
    }
    

    那么你可以简单地做......

    $app->get('/api/server_list', function ($request, $response, $args) {
        $serverlist = new ServerListing($this->db);
        $servers = $serverlist->getServers();
        $objects = array();
    
        foreach ($servers as $server) {
            $objects[] = $server->toArray();
        }
    
        $newResponse = $response->withJson($objects);
        return $newResponse;    
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-02
      相关资源
      最近更新 更多