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

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

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

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

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

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

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

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

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

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

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

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

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

    Просто мои два цента 🙂


    «Свободным сеттером» я имел в виду, что он реализовал плавный интерфейс .

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

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

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

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

    ура

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

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

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

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