Подтвердить что ты не робот

Доктрина 2 Каков рекомендуемый способ доступа к свойствам?

Я помню, что читал, что в моделях Doctrine 2 я не должен публиковать свойства/поля. Как же вы могли бы разоблачить эти поля? Песочница использует методы get*() и set*(). Это лучшая идея? Это очень громоздко. Использование магических методов __get() __set() сделает вещи похожими на настраиваемые поля public?

Какова ваша рекомендация?

4b9b3361

Ответ 1

Здесь вы не можете использовать общедоступные свойства: Как публичные поля "ломают ленивую загрузку" в Doctrine 2?

Вы правы, что __get() и __set() могут облегчить доступ к полям protected/private.

Вот простой пример:

public function __get($name)
{
  if(property_exists($this, $name)){
    return $this->$name;
  }
}

Конечно, это дает доступ ко всем свойствам. Вы можете поместить это в класс, который все ваши объекты расширены, а затем определить не подлежащие оценке поля как private. Или вы можете использовать массив для определения того, какие свойства должны быть доступны: $this->accessable = array('name', 'age')

Существует множество способов защитить все свойства и по-прежнему иметь достаточно простой способ получить/установить их.

Ответ 2

Если какая-либо информация должна быть обнародована, определите для нее геттер. Если он модифицируется, добавьте сеттер (еще лучше, добавьте свободный сеттер!).

API более чисты, без магии. Мне не нравится магия в моем коде.

Только мои два цента:)


Благодаря "плавному сеттеру" я имел в виду, что он реализовал свободный интерфейс .

Ответ 3

Лично мне не нравится шаблонный код с тривиальной целью - он делает код уродливым и утомительным для чтения. Поэтому я предпочитаю __get/__set. Тем не менее, у них есть несколько недостатков:

  • они значительно медленнее, чем обычные вызовы функций, хотя и не настолько, что это должно иметь значение на практике, поскольку доступ к базе данных на несколько порядков медленнее
  • __get/__set вызывается только тогда, когда поле не отображается; если вы получаете доступ к свойствам в коде класса сущности, они не вызываются, а прокси не имеет возможности загружать себя. (Доктрина пытается избежать этого, мгновенно загружая прокси-сервер, как только вызывается один из его общедоступных методов, но есть некоторые исключения, такие как __construct или __wake, где это не имеет смысла, поэтому вы можете попасть в проблему например, чтение поля в конструкторе.)
  • PHP имеет некоторые запутывающие поведения, связанные с магическими методами - e. г. empty($entity->field) не будет вызывать __get (и, таким образом, он будет нарушать поведение прокси, если используется)

Ответ 4

Вместо того, чтобы иметь раздельные геттер и сеттеры или даже использовать магические функции. Есть ли проблема с наличием чего-то подобного в классе

public function Set($attrib, $value)
{
    $this->$attrib = $value;    
}

public function Get($attrib)
{
    return $this->$attrib;
}   

Это облегчает доступ к атрибутам и означает, что они динамически устанавливаются из массивов пары ключей.. любые комментарии? или альтернативные предложения?

Ответ 5

Да, методы getter и setter - это способ доступа к вашим данным. Они немного громоздки, поэтому некоторые люди не любят доктрину2 или зимуют. Но вам нужно сделать это только один раз для каждого объекта, а затем они очень гибкие, чтобы вывести форматирование вывода, на которое вы надеетесь. Вы можете использовать cli, чтобы сделать что-то из этого для вас. Но когда вы их прокатываете, я не считаю это большой сделкой. Тем более, что вы делаете это только со свойствами, которые вам нужны.

Приветствия

Ответ 6

Doctine 2 предоставляет [инструмент командной строки] [1] для генерации базовых классов сущностей

используйте следующее, чтобы получить базовое определение класса Entity из вашего сопоставления, в комплекте с функциями getter/setter для каждого свойства:

path/to/doctrine_cli orm:generate-entities --generate-methods=true path/to/entities/

Вы по-прежнему несете ответственность за изменение каждого получателя/сеттера, чтобы убедиться, что они являются надлежащим типом данных, поскольку методы getter/setter, сгенерированные для Entity, не выполняют кастинг/преобразование типов.