将PHP类实例转为JSON

回答 5 浏览 6.1万 2012-03-27

我想把一个对象的内容以JSON格式回传。我对PHP没有经验,我想知道是否有预定义的函数可以做到这一点(比如json_encode()),或者你必须自己建立字符串? 当谷歌搜索 "PHP对象到JSON "时,我只找到了垃圾。

class Error {
    private $name;
    private $code;
    private $msg;
    public function __construct($ErrorName, $ErrorCode, $ErrorMSG){
        $this->name = $ErrorName;
        $this->code = $ErrorCode;
        $this->msg = $ErrorMSG;
    }
    public function getCode(){
        return $this->code;
    }
    public function getName(){
        return $this->name;
    }
    public function getMsg(){
        return $this->msg;
    }
    public function toJSON(){
        $json = "";

        return json_encode($json);
    }
}

我希望toJSON返回的是什么。

{ name: "the content of $name var", code :1001, msg : 请求时出现错误}。

Reinard 提问于2012-03-27
在写这篇文章的时候,prob还没有出现,但是如果你现在使用>5.4,你可以让你的类实现JsonSerializable。Andrew Brown 2014-04-03
5 个回答
#1楼 已采纳
得票数 48

你就快到了。看看get_object_vars与json_encode的结合,你就会得到你需要的一切。做到:

json_encode(get_object_vars($error));

应该能准确地返回你所寻找的东西。

评论中提到了get_object_vars对可见性的尊重,所以可以考虑在你的类中做类似下面这样的事情。

public function expose() {
    return get_object_vars($this);
}

然后将之前的建议改为:。

json_encode($error->expose());

这应该能解决能见度问题。

clexmond 提问于2012-03-27
clexmond 修改于2012-03-27
我之前试过这个方法,但它返回{}。我想我之前做错了什么,谢谢你,伙计!"。Reinard 2012-03-27
AFAIK get_object_vars也考虑到了它被调用的范围,所以如果你从对象内部的方法中调用它,你也将获得对私有变量的访问权。Felipe Ribeiro 2012-03-27
json_encode(get_object_vars($error));将显示公共成员,不显示私人成员。grifos 2012-03-27
是的,get_object_vars尊重可见性,所以你可能需要添加一个 "expose "方法或类似的东西来处理这个问题。我将把这个建议添加到答案中。clexmond 2012-03-27
#2楼
得票数 41

PHP 5.4+ 中的另一种解决方案是使用 JsonSerializable 接口。

class Error implements \JsonSerializable
{
    private $name;
    private $code;
    private $msg;

    public function __construct($errorName, $errorCode, $errorMSG)
    {
        $this->name = $errorName;
        $this->code = $errorCode;
        $this->msg = $errorMSG;
    }

    public function jsonSerialize()
    {
        return get_object_vars($this);
    }
}

然后,你可以用json_encode将你的错误对象转换为JSON格式。

$error = new MyError("Page not found", 404, "Unfortunately, the page does not exist");
echo json_encode($error);

查看例子,在这里

更多关于\JsonSerializable的信息。

Mandy Schoep 提问于2016-07-18
Mandy Schoep 修改于2019-10-09
注意,类的名称应该是MyError,因为第二个代码片段创建了一个MyError的新实例,而不是Error。Weetz 2021-09-06
#3楼
得票数 10

你需要将你的变量公开,以便它们能出现在json_encode()上。

另外,你要找的代码是

public function toJSON(){
    return json_encode($this);
}
Madara's Ghost 提问于2012-03-27
我喜欢这个方法,因为我不知道get_object_vars有什么方法可以排除你不希望序列化的属性。Jim H. 2012-03-27
#4楼
得票数 5
public function toJSON(){
    $json = array(
        'name' => $this->getName(),
        'code' => $this->getCode(),
        'msg' => $this->getMsg(),
    );

    return json_encode($json);
}

演示:http://codepad.org/mPNGD6Gv

Naftali 提问于2012-03-27
Naftali 修改于2012-03-27
#5楼
得票数 0

在Linux中,以下内容将在一个文件~/.config/scriptname/scriptname.conf中写入一个给定的类条目的值,如果该文件不存在,则创建该文件,否则在加载时读取并设置回该类值。

/* Example class */
class flag {
  static $COLORSET = ["\033[34;1m","\033[31;1m"];
}
/* Retrieve and set back values, otherwise create config file with the defined value --------------------------------------------------*/
if (!is_file($_SERVER["HOME"]."/.config/".$_SERVER["SCRIPT_NAME"]."/".$_SERVER["SCRIPT_NAME"].".conf")){
    @mkdir($_SERVER["HOME"]."/.config/".$_SERVER["SCRIPT_NAME"]);
    @file_put_contents($_SERVER["HOME"]."/.config/".$_SERVER["SCRIPT_NAME"]."/".$_SERVER["SCRIPT_NAME"].".conf",json_encode(["COLORSET"=>flag::$COLORSET]));
} else {
    flag::$COLORSET = json_decode(file_get_contents($_SERVER["HOME"]."/.config/".$_SERVER["SCRIPT_NAME"]."/".$_SERVER["SCRIPT_NAME"].".conf"), true)["COLORSET"];       
}
NVRM 提问于2019-11-16