Slim 框架无法使用受保护变量编码为 json
Slim framework unable to encode to json with protected variables
基本上我是用 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 的 class 代码:
<?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;
}
}
唯一有效的方法是 public。
我明白了public/private/protected。虽然这是我第一次使用框架和面向对象 php。
在另一条路线中使用相同的数据库调用,然后我可以将服务器列表传递给视图并且它工作正常。
所以我猜两个问题。
- 为什么 json 编码失败?
- 我是不是做错了什么/有更好的方法吗?
简而言之,对象可以转化为数组。
对象的 public 属性将用作数组中的 $key => $value
对。
由于属性受到保护,因此不包括这些值。
虽然数组实际上为空似乎合乎逻辑,但 PHP 将对象转换为数组的过程并没有得到充分的记录。
实际上,我建议您创建一个 public 方法,将对象转换为数组。
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;
});
Slim 的Response::withJson()
doesn't do anything magic. It relies on the PHP function json_encode()
进行编码。 json_encode()
也不知道有什么绝招。如果您将一个对象传递给它进行编码,它会获得它可以从中获得的所有数据。这仅意味着它的 public 属性,因为,这就是 OOP 的工作方式。
但是,如果您在 class 中实现 JsonSerializable
接口,那么在编码 class 的对象时,您可以控制 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"}
基本上我是用 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 的 class 代码:
<?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;
}
}
唯一有效的方法是 public。
我明白了public/private/protected。虽然这是我第一次使用框架和面向对象 php。
在另一条路线中使用相同的数据库调用,然后我可以将服务器列表传递给视图并且它工作正常。
所以我猜两个问题。
- 为什么 json 编码失败?
- 我是不是做错了什么/有更好的方法吗?
简而言之,对象可以转化为数组。
对象的 public 属性将用作数组中的 $key => $value
对。
由于属性受到保护,因此不包括这些值。
虽然数组实际上为空似乎合乎逻辑,但 PHP 将对象转换为数组的过程并没有得到充分的记录。
实际上,我建议您创建一个 public 方法,将对象转换为数组。
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;
});
Slim 的Response::withJson()
doesn't do anything magic. It relies on the PHP function json_encode()
进行编码。 json_encode()
也不知道有什么绝招。如果您将一个对象传递给它进行编码,它会获得它可以从中获得的所有数据。这仅意味着它的 public 属性,因为,这就是 OOP 的工作方式。
但是,如果您在 class 中实现 JsonSerializable
接口,那么在编码 class 的对象时,您可以控制 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"}