Php 我可以在Doctrine2中迭代实体的属性吗?

Php 我可以在Doctrine2中迭代实体的属性吗?,php,doctrine,doctrine-orm,Php,Doctrine,Doctrine Orm,我用 我通过 $myblogrepo = $this->_doctrine->getRepository('Entities\Blog')->findBy(array('id' => 12); 如何获取字段名?我以为key=>可以工作,但它将key打印为0 所以我认为这会起作用: foreach($myblogrepo as $key =>$value){ echo $key . $value; } 但还是没什么。。 }使用findOneBy而不是findB

我用

我通过

$myblogrepo = $this->_doctrine->getRepository('Entities\Blog')->findBy(array('id' => 12);
如何获取字段名?我以为key=>可以工作,但它将key打印为0

所以我认为这会起作用:

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

echo $key . $value;

}
但还是没什么。。 }

使用findOneBy而不是findBy来选择单行

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

echo $key . $value;
}

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

很可能,您的博客实体的属性被声明为受保护。这就是为什么不能从实体本身的外部对它们进行迭代

如果您以只读方式使用博客实体,并且只需要访问标记为@列的属性:您不需要调用实体上的任何方法,就可以考虑使用数组水合。这样,您将处理简单的数组,$k=>$v类型的迭代将很好地工作

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

最后,您可以创建一个通用的getValues函数作为一个实用函数,该函数使用doctrine的类元数据来确定列和实体的类型,并对这些数据进行操作。下面是一个简单的实现:

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

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

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

我的所有实体都继承自EntityBase类,该类具有以下方法:

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;
}

因此,我所要做的就是调用$entity->toValueObject,然后获得一个标准对象,该对象的所有属性都是公共属性。

这是一个序列化器类的我的实现,该类还检查它是否是一个原则实体:

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;
}

我也试过了,但是你不能用它,你可以通过:$myblogrepo->id访问它,但这是值,我怎么才能得到这个键名?或字段名?执行$iterableResult=$myblogrepo->迭代;并使用foreach$iterableResult作为$key=>$value对值进行迭代。你完全可以用foreach遍历一个对象。试试看,就这么做了。注意:未定义的属性:Entities\Blog::$iterate确保使用$myblogrepo->iterate;而不是$myblogrepo->iterate;。iterate是一个方法,而不是一个属性。
/**
 * 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();
    }
}