【问题标题】:How do I map a JSON object to a PHP Class?如何将 JSON 对象映射到 PHP 类?
【发布时间】:2013-06-16 07:53:45
【问题描述】:

我正在构建一个将公司添加到 MySQL 数据库的 REST API endpint。客户端发送带有附加数据包的 POST 请求。数据包是一个 JSON 对象。假设 JSON 公司对象的格式与 API 使用的公司类完全匹配。

如何将 JSON 公司对象数据放入公司类?实例化一个公司对象,json_decode() JSON 对象,然后调用几十个set() 方法似乎很愚蠢。

这似乎特别愚蠢,因为我计划在我的客户端包中提供相同的模型来构建作为 JSON 传递给我的 API 的对象,然后再被解码并再次映射回相同的对象。

我错过了什么吗?在构建我的 API 时,我经常遇到一些看似多余的事情,但也许这就是必须发生的事情。

【问题讨论】:

标签: php json api class oop


【解决方案1】:

我遇到了同样的问题,所以我写了一个packagist来解决它,这是给你的礼物。
https://packagist.org/packages/stark641/stark-object
https://github.com/stark641/stark-object

  1. 可以从json生成PHP类文件
./vendor/bin/stark-object-gen --path=/tmp --json='{"foo_bar":{"foo":1.3,"bar":[641,641]}}'

output
Class FooBar saved at: /tmp/FooBar.php
Class BaseClass saved at: /tmp/BaseClass.php
  1. 您可以将 json 映射到 php 对象
class FooBarClass extends StarkObject
{
    /** @var string */
    public $foo;

    /** @var integer */
    public $bar;
}

class DemoClass extends StarkObject
{
    /** @var FooBarClass */
    public $foobar;

    /** @var FooBarClass[] */
    public $foobars;

}

$json = '{"foobar":{"foo":"hello world","bar":64100},"foobars":[{"foo":"hello","bar":641},{"foo":"world","bar":664411}]}';
$demo = (new DemoClass())->fromJson($json);

var_export($demo);

【讨论】:

    【解决方案2】:

    这个可能对你有帮助。

     class ObjectMapper
        {
    
            protected string $modelClass='';
    
            public function __construct(string $modelClass){
            $this->modelClass = $modelClass;
    }
    
            protected function mapObject(array $values){
                $object = new $this->modelClass();
                foreach ($values as $key=>$value){
                    $mapperFunction = 'set'.$key;
                    $object->{$mapperFunction}($value);
                }
                return $object;
            }
    
        }
    
    

    【讨论】:

      【解决方案3】:

      我们构建了JsonMapper 以将 JSON 对象自动映射到我们自己的模型类。

      它只依赖于 docblock 类型信息进行映射,大多数类属性无论如何都有。

      【讨论】:

        【解决方案4】:

        你为什么不处理,全部在Company对象的构造函数中,这样你传入JSON对象作为参数,构造函数处理所有的赋值。这样你甚至不需要公共的 set 方法。

        $companyData = $_POST['company'];
        //or $companyData = json_decode($_POST['company']);
        //or whatever depending on how you are posting
        
        class Company {
            private $companyName;
            //etc...
            function __construct(array $data) {
                foreach($data as $key => $val) {
                    if(property_exists(__CLASS__,$key)) {
                        $this->$key = $val;
                    }
                }
            }
        }
        

        【讨论】:

          【解决方案5】:

          你为什么不在 Company 对象中创建一个方法来声明对象的变量(你不需要为每个变量编写一个 set 方法,只需要一个设置所有变量的方法)。

          //Why not write something like this in the class
          function setFromJSON($json){
             $jsonArray = json_decode($json, true);
             foreach($jsonArray as $key=>$value){
                $this->$key = $value;
             }
          }
          

          【讨论】:

          • json_decode的第二个参数必须设置为true,否则无法进行key/value迭代。我对您的答案进行了编辑。
          【解决方案6】:

          不要将您获得的 JSON 数据与您要使用的数据对象完全匹配。数据库和对象将会发生变化,您不希望这些影响您创建的界面,反之亦然。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2017-12-24
            • 2011-08-09
            • 2019-05-27
            • 1970-01-01
            • 1970-01-01
            • 2012-04-16
            • 2012-04-23
            • 2015-06-27
            相关资源
            最近更新 更多