基本上我用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;
}
}
这里是ServerEntity:
<?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;
}
}
唯一可行的方法是public。
我理解public/private/protected。虽然这是我第一次使用框架和面向对象的php。
在另一条路由中使用相同的数据库调用,我可以将服务器列表传递给视图,它工作得很好。
我想有两个问题。
- 为什么json编码失败?
- 我做了一些根本性的错误/有更好的方法来做到这一点吗?
Slim's 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"}
简而言之,可以将对象转换为数组。
对象的公共属性将被用作数组中的$key => $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;
});