2015-02-08 53 views
0

我正在構建一個web服務,它通過websocket連接傳輸域模型的json表示。這些實體被映射爲Doctrine,不幸的是我限制了我只能在實體類中使用protected或private屬性。爲了包括在JSON私有財產,我已經用在我的實體這一特質:從Doctrine實體中選擇用於序列​​化的屬性子集

/** 
* A trait enabling serialization for Doctrine entities for websocket transports. 
* Unfortunately, this cannot be included in the abstract class for Doctrine entities 
* as the parent class is unable to access private properties enforced by Doctrine. 
*/ 
trait SerializableTrait 
{ 
    /** 
    * Implements {@link \JsonSerializable} interface. 
    * @return string - json representation 
    */ 
    public function jsonSerialize() 
    { 
     return get_object_vars($this); 
    } 
} 

然而,在客戶端收到的對象應該只包含實體的屬性的子集,以減少負載websocket連接並防止嗅探私人信息。這可以優雅地在PHP中實現,而無需使用Reflection API或從基類爲客戶端對象創建子類(我不是真的想拆分實體類)。或者有沒有辦法在我認識的學說實體中使用公共財產?我正在尋找獨一無二的行

$lightweightEntity = EntityStripper::strip($entity); 

在此先感謝!

回答

0

儘管最初並不熱衷於使用Reflection API,但它似乎是唯一可行的解​​決方案。所以我想出了這個解決方案解析一個自定義的@Serializable註釋,以確定哪些屬性序列化:

use Doctrine\Common\Annotations\AnnotationReader; 
use App\Model\Annotations\Serializable; 

/** 
* A trait enabling serialization of Doctrine entities for websocket transports. 
*/ 
trait SerializableTrait 
{ 
    /** 
    * Implements {@link \JsonSerializable} interface and serializes all 
    * properties annotated with {@link Serializable}. 
    * @return string - json representation 
    */ 
    public function jsonSerialize() 
    { 
     // Circumvent Doctrine's restriction to protected properties 
     $reflection = new \ReflectionClass(get_class($this)); 
     $properties = array_keys($reflection->getdefaultProperties()); 
     $reader = new AnnotationReader(); 

     $serialize = array(); 

     foreach ($properties as $key) { 
      // Parse annotations 
      $property = new \ReflectionProperty(get_class($this), $key); 
      $annotation = $reader->getPropertyAnnotation($property, get_class(new Serializable())); 

      // Only serialize properties with annotation 
      if ($annotation) { 
       $serialize[$key] = $this->$key; 
      } 
     } 

     return json_encode($serialize, JSON_FORCE_OBJECT); 
    } 
}