简体   繁体   中英

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;

}

how can i get the field names? i thought the key => would work but it print s the key as 0

so i thought this would work:

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

echo $key . $value;
}

but still nothing.. }

In all likelihood, your Blog entity's properties are declared as protected . This is why you can't iterate over them from outside the the Entity itself.

If you're using your Blog entities in a read-only fashion, and only need access to the properties marked as @Columns (read: you don't need to call any methods on your entity), you might consider using array-hydration. That way you'll be dealing with simple arrays, and $k=>$v type iteration will work fine.

Otherwise, you'll need to create some kind of getValues() method on your entity class. This could be a simple implementation that just builds and array and returns it.

Finally, you could create a general-purpose getValues() as a utility function that uses doctrine's class metadata to figure out what columns and entity has, and operate on those data. A simple implementation like this:

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 - A more mature version of the above method seems to be available here - I've not played with it yet, but it looks promising.

If you just need to get the properties of the entity in a fast and easy way, this is what I do in my projects:

All my entities inherit from an EntityBase class, which has the following method:

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

So all I have to do is call $entity->toValueObject() and I obtain a standard object with all of the entity's properties as public properties.

Use findOneBy instead of findBy to select a single row.

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

Your key was 0 because it was the first row in a possible multi-row result.

This is a my implementation of a serializer class that also check if it is a doctrine entity:

/**
 * 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();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM