Can I iterate over an Entity's properties in Doctrine2?
i use
$myblo开发者_Python百科grepo = $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();
}
}
精彩评论