Можно ли перебирать свойства Entity в Doctrine2?

я использую

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

я получаю доступ через

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

как я могу получить имена полей? Я думал, что ключ => будет работать, но он печатает s ключ как 0

поэтому я думал, что это сработает:

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

но все равно ничего.}

По всей вероятности, свойства объекта вашего блога объявляются protected . Вот почему вы не можете перебирать их извне самого сущности.

Если вы используете объекты своего блога в режиме «только для чтения» и вам нужен только доступ к свойствам, помеченным как @Columns (читайте: вам не нужно вызывать какие-либо методы в вашей сущности), вы можете рассмотреть возможность использования массива-гидратации , Таким образом, вы будете иметь дело с простыми массивами, а итерация $k=>$v будет работать нормально.

В противном случае вам нужно создать какой-то метод getValues ​​() для вашего класса сущности. Это может быть простая реализация, которая просто строит и массирует и возвращает ее.

Наконец, вы можете создать универсальный getValues ​​() как функцию полезности, которая использует метаданные класса доктрины, чтобы выяснить, какие столбцы и сущность имеют, и работать с этими данными. Простая реализация:

 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 . Более зрелая версия вышеупомянутого метода, похоже, доступна здесь. Я еще не играл с ней, но выглядит многообещающе.

Используйте findOneBy вместо findBy чтобы выбрать одну строку.

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

Ваш ключ был 0 потому что это была первая строка в возможном многострочном результате.

Если вам просто нужно быстро и легко получить свойства объекта, это то, что я делаю в своих проектах:

Все мои объекты наследуются от класса 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() и я получаю стандартный объект со всеми свойствами объекта как общедоступными.

Это моя реализация класса сериализатора, который также проверяет, является ли он объектом доктрины:

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