我正在构建一个web服务,它通过websocket连接传输域模型的json表示。实体与Doctrine映射,不幸的是,我只限制在我的实体类中使用protected或private属性。为了在json中包含私有属性,我一直在我的实体中使用这个特性:
/**
* 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或从客户端对象的基类继承(我不想真正拆分实体类)。或者有没有办法在Doctrine实体中使用我不知道的公共属性?
我正在寻找一些独特的东西$lightweightEntity = EntityStripper::strip($entity);
提前致谢!
答案 0 :(得分: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);
}
}