首页 > 解决方案 > 如何对实体进行动态setmethod数据?

问题描述

我想为对象设置很多 JSON 数据,但我不想写很多 set 方法。例子:

//(POST : JSON DATA) JSON keys equals entity variable names
{
"data1": "banana",
"data2": "index, follow",
"data3": "true",
"data4": "abcdef",
"data5": "false",
"big_data1": "lorem ipsum ...."
"name": "apple"
  ....
}

我的实体(短版)

class Category
{
 //....
 private $data1;

 public setData1(string $data1): self{
  $this->data1 = $data1;
  return $this;
 }
 public getData1():string{ return $this->data1; }

 //...
}

我的控制器

//...
public function index(){
  //post data json to object
  $data = json_decode($postdata); # data object
  $category = new Category(); # new category class

  $object = new \ReflectionObject($category);

  /**
     What is the next step?
     $this->setData1($data->data1);
     $this->setData2($data->data2);
     if(!empty($data->big_data12)
       $this->setBigData12($data->big_data12)
     .
     .
     .
     $this->setData12($data->data12)

  */
}

如何做一个简单的方法?如何避免编写许多 set 方法?

标签: php

解决方案


根本不需要使用反射。您可以使用魔术方法。具体来说,_call()文档

一个非常简单、幼稚的实现:

class Category
{
    private $data1;
    private $data2;
    private $data3;
    private $bigData12;

    public function __call($method, array $arguments)
    {
        $verb = substr($method, 0, 3);
        $noun = lcfirst(substr($method, 3));

        if (!property_exists($this, $noun)) {
            throw new Exception('Property does not exist');
        }

        switch($verb) {
            case 'set':
                $this->$noun = $arguments[0];
                return $this;

            case 'get':
                return $this->$noun;
        }
    }

}

$cat = new Category();
$cat->setData1('hello')
    ->setData2('hola')
    ->setData3(12345)
    ->setBigData12('hello world');

echo $cat->getData1(), "\n";
echo $cat->getData2(), "\n";
echo $cat->getData3(), "\n";
echo $cat->getBigData12(), "\n";

你可以看到它在这里工作。

请注意,我不建议这样做太多。这种事情很容易出错,不能进行类型提示,收益从微不足道到不存在。


推荐阅读