标记类字段

时间:2016-04-20 20:04:23

标签: php reflection

我正在寻找一种标记字段的方法,并稍后使用该标记对该对象进行不同的操作。

例如,序列化没有标记字段的对象:

class A(){
   public $field1;

   //@dont_serialize
   public $field2;
} 

$obj = new A();
$obj->field1 = "important data";
$obj->field2 = "not important data";

function MySerialize($obj){
  $arr = (array) $obj;
  $new_arr = array();   
  foreach ($arr as $key => $value) {
      if (THIS FEILD IS NOT MARKED AS @dont_serialize)
      {
        $new_arr[$key] = $value
      }
  }
  return serialize($new_arr);
}

如何实现不会序列化标记字段的MySerialize()?

3 个答案:

答案 0 :(得分:1)

您需要阅读注释并对其进行处理,这个答案就是一个很好的例子:https://stackoverflow.com/a/9742661/3354887

还有一个docblock解析器:https://github.com/doctrine/annotations

答案 1 :(得分:1)

要继续使用反射API,你应该"标记"您的字段带有"适当的"(格式化)注释。
以下是使用ReflectionClass类,ReflectionProperty::getDocCommentReflectionProperty::getNameReflectionProperty::getValue方法的工作解决方案:

class A {

    public $field1;
    public $field2;

    /**
     * @dont_serialize
     */
    public $field3;

}

$obj = new A();
$obj->field1 = "important data";
$obj->field2 = "needed data";
$obj->field3 = "not important data";

function MySerialize($obj) {
    $reflector = new ReflectionClass(get_class($obj));
    $props = $reflector->getProperties();
    $new_arr = [];

    foreach ($props as $property) {
        if (strpos($property->getDocComment(), "@dont_serialize") === false) {
            $new_arr[$property->getName()] = $property->getValue($obj);
        }
    }
    return serialize($new_arr);
}

print_r(MySerialize($obj));

输出:

"a:2:{s:6:"field1";s:14:"important data";s:6:"field2";s:11:"needed data";}"

答案 2 :(得分:0)

仅仅为了序列化的目的,有一种更好的方法,而不是标记属性和使用反射。

有魔术函数__sleep(),_ _ wakeup()...允许更改将用serialize()函数序列化的字段,详细信息请看 http://php.net/language.oop5.magic