Могу ли я перебрать свойства сущности в Doctrine2? - PullRequest
8 голосов
/ 17 августа 2011

я использую

$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 ]

18 голосов
/ 17 августа 2011

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

Если вы используете объекты Blog только для чтения и вам нужен только доступ к свойствам, помеченным как @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;
}

РЕДАКТИРОВАТЬ - более зрелая версия описанного выше метода, по-видимому, доступна здесь - я еще не играл с ним, но выглядит многообещающе.

1 голос
/ 15 мая 2015

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

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

1 голос
/ 17 августа 2011

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

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

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

0 голосов
/ 24 сентября 2016

Это моя реализация класса сериализатора, который также проверяет, является ли он сущностью доктрины:

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