Модели в Zend Framework - PullRequest
       44

Модели в Zend Framework

33 голосов
/ 17 ноября 2008

Как вы реализовали модели в Zend Framework?

Я видел базовый class User extends Zend_Db_Table_Abstract, а затем звонил на него в ваши контроллеры:

$foo = new User;

$foo->fetchAll()

а как насчет более сложных применений? В разделе «Быстрый старт» документации приведен такой пример, но я все еще чувствую, что у меня нет примера «наилучшего использования» для моделей в Zend Framework. Есть какие-нибудь интересные реализации?


РЕДАКТИРОВАТЬ: Я должен уточнить (в ответ на комментарий CMS) ... Я знаю о выполнении более сложных выборов. Меня интересовали общие подходы к концепции Модели и конкретные примеры того, как их реализовали другие (в основном, то, что упущено в руководстве, и то, что скрывают основные инструкции)

Ответы [ 11 ]

61 голосов
/ 17 ноября 2008

Я работал на Zend и довольно много работал над компонентом Zend_Db_Table.

Zend Framework не дает большого руководства по концепции «Модель» относительно шаблона Модель предметной области. Для Модели нет базового класса, потому что Модель инкапсулирует некоторую часть бизнес-логики, специфичную для вашего приложения. Я написал блог на эту тему более подробно.

Постоянство в базе данных должно быть внутренней деталью реализации Модели. Модель обычно использует одну или несколько таблиц. Обычный, но неправильный объектно-ориентированный дизайн - рассматривать модель как расширение таблицы. Другими словами, мы должны сказать, что модель HAS-A Table, а не модель IS-A Table.

Это пример IS-A:

class MyModel extends Zend_Db_Table_Abstract
{
} 

Это пример HAS-A:

class MyModel // extends nothing
{
    protected $some_table;
}

В реальной модели домена вы должны использовать $ some_table в методах MyModel.

Вы также можете прочитать взгляд Мартина Фаулера на шаблон проектирования Domain Model и его описание антипаттерна Anemic Domain Model , который, к сожалению, многие разработчики подходят к ОО-программированию. 1025 *

23 голосов
/ 17 ноября 2008

Я лично подкласс как Zend_Db_Table_Abstract, так и Zend_Db_Table_Row_Abstract. Основное различие между моим и вашим кодом заключается в том, что подкласс Zend_Db_Table_Abstract явно рассматривается как "таблица", а Zend_Db_Table_Row_Abstract - как "строка". Очень редко я вижу прямые вызовы для выбора объектов, SQL или встроенных методов базы данных ZF в моих контроллерах. Я пытаюсь скрыть логику запроса конкретных записей к вызовам за Zend_Db_Table_Abstract, например:

class Users extends Zend_Db_Table_Abstract {

    protected $_name = 'users';

    protected $_rowClass = 'User'; // <== THIS IS REALLY HELPFUL

    public function getById($id) {
        // RETURNS ONE INSTANCE OF 'User'
    }

    public function getActiveUsers() {
        // RETURNS MULTIPLE 'User' OBJECTS            
    }

}

class User extends Zend_Db_Table_Row_Abstract {

    public function setPassword() {
        // SET THE PASSWORD FOR A SINGLE ROW
    }

}

/* CONTROLLER */
public function setPasswordAction() {

    /* GET YOUR PARAMS */

    $users = new Users();

    $user = $users->getById($id);

    $user->setPassword($password);

    $user->save();
}

Есть множество способов подойти к этому. Не думаю, что это единственный, но я стараюсь следовать замыслу ZF. (Вот больше моих мыслей и ссылок по теме .) Этот подход немного усложняет урок, но я чувствую, что он заставляет контроллеры сосредоточиться на обработке ввода и координации с представлением; оставляя модель для выполнения конкретной работы приложения.

7 голосов
/ 27 января 2009

Я провел некоторое исследование по Моделям для ZF и наткнулся на интересную серию статей Мэтью Вейера О'Пинни, которые стоит проверить:

Это не «производственный код», и многое остается для воображения, но это хорошее чтение и оно мне очень помогло.

7 голосов
/ 17 ноября 2008

Никогда не используйте Zend_Db_Table в качестве вашей модели. Это просто доставляет вам неприятности. Либо вы пишете свои собственные классы моделей, которые используют Zend_Db_Table для общения с вашей базой данных, либо вы можете прочитать мой пост в блоге здесь для взлома, который позволяет вам несколько комбинировать класс "Модель" и Zend_Db_Table.

Главное, что не нужно делать, это то, что когда вы используете Zend_Db_Table непосредственно в своих контроллерах, вы в конечном итоге делаете одни и те же вещи в нескольких местах. Если вам нужно внести изменения в некоторые из этой логики, вы должны внести изменения в нескольких местах. Нехорошо. Мой первый профессиональный проект был выполнен именно так, потому что я был единственным в компании, который должен был научиться использовать ZF, и сейчас это полный беспорядок.

Я также склонен писать вспомогательные функции в своих классах для сложных извлечений. Что-то вроде $ table-> doNameFetchAll () или $ table-> doOrderFetchAll ().

5 голосов
/ 29 октября 2010

Модель не имеет никакого отношения к базе данных . Что делать, если я получаю данные из RSS-канала или службы SOAP или считываю файлы из FS?

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

3 голосов
/ 17 ноября 2008

Пропустите ZF для моделей, есть гораздо лучшие решения. Буква «М» в «MVC» ZF практически отсутствует. Читая свои документы, они вообще не упоминают модели - это хорошо, это означает, что вы можете использовать практически все, что хотите, без написания большого количества кода адаптера.

Взгляните на Doctrine для моделей вместо этого. Он быстро становится де-факто ORM для PHP.

1 голос
/ 06 апреля 2010

http://zfsite.andreinikolov.com/2008/08/zend_db_table-time-overhead-about-25-percents/

Немного подвох 22, Zend_Table в принципе хорош, но генерирует некоторые потери производительности (без кэширования) ...

1 голос
/ 30 января 2009

Я использую Propel 1.3 вместо Zend_Db_Table. Это сложно настроить, но круто. Он может проверить вашу базу данных и автоматически сгенерировать все ваши модели. Фактически генерирует 2 уровня и 2 типа модели.

Примеры для таблицы 'user':

Уровень 1: BaseModel и BasePeer: они перезаписываются каждый раз, когда вы восстанавливаете ORM. т.е. BaseUser.php & BaseUserPeer.php

Уровень 2: StubModel & StubPeer: они не перезаписываются. Это те, кого вы настраиваете. т.е. User.php & UserPeer.php

Тип 1: Модель - для базовых операций CRUD, а не для запросов, т. Е. User.php Тип 2: Peer - для запросов. Это статические объекты. т.е. UserPeer.php

Итак, чтобы создать пользователя:

$derek = new User();
$derek->setFirstName('Derek');
$derek->save();

Чтобы найти всех дереков:

$c = new Criteria();
$c->add(UserPeer::FIRST_NAME, 'Derek');
$dereks = UserPeer::doSelect($c);
1 голос
/ 17 ноября 2008

Сущность базы данных - не единственный вид компонента модели. Таким образом, на самом деле не имеет смысла говорить о моделях (во множественном числе) - Ваше приложение имеет модель one , которая содержит множество компонентов. Некоторые из этих компонентов могут быть табличными шлюзами (и, следовательно, расширяться от Zend_Db), а другие - нет.

Я рекомендую вам приобрести книгу Эрика Эванса Domain Driven Design , которая отлично объясняет, как построить объектную модель.

1 голос
/ 17 ноября 2008

вы можете расширить класс Zend_Db_Table_Abstract и добавить к нему несколько полезных методов. Например, вы можете добавить метод changePassword () в свой пользовательский класс и манипулировать его данными. или вы можете изменить метод __toString () вашего класса по умолчанию, чтобы у вас был настроенный метод __toString (), который, скажем, возвращает всю контактную информацию пользователя (имя, адрес, номер телефона) в хорошо отформатированной строке , в вашем конструкторе вы можете заполнить ваши данные в свойствах вашего объекта. затем используйте их как:

public function __toString() {
   $data = $this->_name . ', ' . $this->_adderss . ', call: ' . $this->_phone;
   return $data;
}

ваша модель расширяет Zend_Db_Table_Abstract просто для того, чтобы упростить процесс доступа к ее данным, но функциональность, которую вы можете иметь с этими данными, полностью зависит от ваших творческих способностей и потребностей. Я рекомендую вам книгу Кэла Эванса «Руководство php | architect по программированию на Zend Framework». книга очень информативна и легко читается. главы 4 и 6 будут полезны в этом отношении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...