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

时间:2011-08-17 13:17:10

标签: php doctrine doctrine-orm

我用

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

我通过

访问
foreach($myblogrepo as $key =>$value){

echo $key . $value;

}

我怎样才能获得字段名称?我认为关键=>会工作,但它打印键为0

所以我认为这样可行:

foreach($myblogrepo[0] as $key =>$value){

echo $key . $value;
}

但仍然没有.. }

4 个答案:

答案 0 :(得分:18)

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

如果您以只读方式使用Blog实体,并且只需要访问标记为@Columns的属性(读取:您不需要调用实体上的任何方法),您可以考虑使用阵列水化。这样你将处理简单数组,$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;
}

编辑 - 上述方法的一个更成熟的版本似乎是available here - 我还没有玩过它,但看起来很有希望。

答案 1 :(得分:1)

使用findOneBy代替findBy选择一行。

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

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

答案 2 :(得分:1)

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

我的所有实体都继承自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()并获得一个标准对象,其中所有实体的属性都是公共属性。

答案 3 :(得分: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();
    }
}