我可以在Doctrine2中迭代entity的属性吗?


Can I iterate over an Entity's properties in Doctrine2?

i use

$myblogrepo = $this->_doctrine->getRepository('Entities'Blog')->findBy(array('id' => 12);

i access via

foreach($myblogrepo as $key =>$value){
echo $key . $value;
}

如何获得字段名称?我以为键=>可以工作,但它打印的键为0

所以我认为这将工作:

foreach($myblogrepo[0] as $key =>$value){
echo $key . $value;
}

但仍然没有…}

很可能,您的Blog实体的属性被声明为protected。这就是为什么你不能从实体本身之外迭代它们的原因。

如果您以只读方式使用Blog实体,并且只需要访问标记为@Columns的属性(读取:您不需要在您的实体上调用任何方法),您可能会考虑使用array-hydration。这样你就可以处理简单的数组,并且$k=>$v类型的迭代将工作得很好。

否则,您将需要在实体类上创建某种getValues()方法。这可以是一个简单的实现,只是构建一个数组并返回它。

最后,您可以创建一个通用的getValues()作为一个实用程序函数,它使用doctrine的类元数据来找出哪些列和实体具有,并对这些数据进行操作。像这样的简单实现:

function getEntityColumnValues($entity,$em){
  $cols = $em->getClassMetadata(get_class($entity))->getColumnNames();
  $values = array();
  foreach($cols as $col){
    $getter = 'get'.ucfirst($col);
    $values[$col] = $entity->$getter();
  }
  return $values;
}

EDIT -上面方法的一个更成熟的版本似乎在这里可用-我还没有玩过它,但它看起来很有希望。

如果您只需要以快速简便的方式获取实体的属性,这就是我在我的项目中所做的:

我所有的实体都继承自一个EntityBase类,它有以下方法:

public function toValueObject()
{
    $result = new 'stdClass();
    foreach ($this as $property => $value) {
        $getter = 'get' . ucfirst($property);
        if (method_exists($this, $getter)) {
            $result->$property = $this->$getter();
        }
    }
    return $result;
}

所以我所要做的就是调用$entity->toValueObject(),我获得一个标准的对象与所有实体的属性作为公共属性。

使用findOneBy代替findBy来选择单行

$myblogrepo = $this->_doctrine->getRepository('Entities'Blog')->findOneBy(array('id' => 12);

您的键是0,因为它是可能的多行结果中的第一行。

这是一个序列化器类的实现,它也检查它是否是一个学说实体:

/**
 * JsonApiSerializer constructor.
 * @param EntityManagerInterface $em
 */
public function __construct(EntityManagerInterface $em)
{
    $this->em = $em;
}
/**
 * @param $payLoad
 * @return string
 */
public function serialize($payLoad, $type)
{
    $serializedPayload = new 'stdClass();
    $serializedPayload->data = new 'stdClass();
    $serializedPayload->data->type = $type;
    if ($this->isDoctrineEntity($payLoad)) {
        $this->addEntityColumnValues($serializedPayload, $payLoad);
    }
    return json_encode($serializedPayload);
}
private function isDoctrineEntity($payLoad)
{
    if (is_object($payLoad)) {
        $payLoad = ($payLoad instanceof Proxy)
            ? get_parent_class($payLoad)
            : get_class($payLoad);
    }
    return !$this->em->getMetadataFactory()->isTransient($payLoad);
}
private function addEntityColumnValues(&$serializedPayload, $entity){
    $serializedPayload->data->attributes = new 'stdClass();
    $classMetaData = $this->em->getClassMetadata(get_class($entity));
    $columnNames = $classMetaData->getColumnNames();
    foreach($columnNames as $columnName){
        $fieldName = $classMetaData->getFieldForColumn($columnName);
        $getter = 'get'.ucfirst($fieldName);
        $serializedPayload->data->attributes->$columnName = $entity->$getter();
    }
}