Июль 202008
 

Источник: Integrating Zend Framework and Doctrine
Автор: Ruben Vermeersch
Перевод: Лобач Олег

Эта статья научит вас всем шагам, необходимым для создания проекта, использующего Zend Framework и Doctrine. Шаг за шагом мы создадим простейшую доску сообщений.

Прежде, чем начать

Хоть я и старался сохранить статью простой, это не значит, что тут будет введение в обе технологии. Я предлагаю вам поиграть с обеими технологиями по отдельности, прежде чем пытаться объединить их. Они обе имеют достаточно хорошую документацию, что бы с нее начать: Zend Framework Quick Start и Doctrine's My First Project. Кроме того, Akra's Zend Framework Tutorial («Введение в Zend Framework» — перевод от Александра Мусаева) тоже очень хорошее введение в тему.

Zend Framework имеет «используй-как-хочешь» архитектуру. Это значит, что вы свободны в использовании только тех частей, которые вам нужны, в отличии от других фреймворков, предлагающих решения «все-или-ничего». Эта архитектура (используй-как-хочешь) великолепна: она позволяет нам разрабатывать настоящие Zend Framework приложения, без использования ZF абстракции от БД (Zend_Db). Хотя Zend_Db не плохая технология, она все еще довольно низкоуровневая, и слишком близка к базе данных. Используя Doctrine, вы можете манипулировать вашими данными как объектами, не слишком беспокоясь о базе данных.

Zend Framework предоставляет вам много свободы в том, как строить своё приложение. Иными словами, он не заставляет вас использовать строго определенную структуру проекта. В этой статье я старался наиболее близко следовать предлагаемой по умолчанию структура проекта. Тем не менее, все это вопрос личного вкуса.

Итак, приступим!

Сначала мы создадим типовую структуру проекта и установим библиотеки. Откройте файл-менеджер и создайте структуру папок, как показано ниже. Я объясню, назначение этих папок через минуту.

Типовая структура папок

Типовая структура папок

Тут много папок, но большинство из них должны быть вам знакомы, если вы уже разрабатывали приложения на Zend Framework. Вот отличия:

  • application/doctrine/ — в ней содержаться все файлы данных Doctrine, такие как sql и yaml схемы бд, миграции, дампы, и т.п.
  • application/models/ — Doctrine будет автоматически генерировать файлы моделей в этой директории, что легко использовать в рамках вашего Zend Framework приложения.
  • library/ — как правило, вы бы просто установить свою копию Zend Framework в эту папку. В нашем приложении нам нужны две библиотеки: Zend Framework и Doctrine. Таким образом, мы делаем два подкаталога и устанавливаем туда библиотеки.
  • scripts/ — Doctrine поставляется с удобнымм скриптами командной строки (делее просто «скрипты доктрины»), мы будем хранить их здесь (как в предложении, упомянутом выше).

Следующий шаг — установка Zend Framework и Doctrine. Загрузите последнюю версию с соответствующих веб-сайтов и разархивируйте library (для ZF) или lib (для Doctrine) в созданные нами папки. Должно получиться приблизительно следующее:

Zend Framework и Doctrine установлены

Время заняться загрузочным файлом

Если вы помните по Zend Framework Quick Start, мы должны создать загрузочный файл. Мы сделаем это сейчас, но с некоторыми изменениями, с тем, чтобы использовать Doctrine.

Во-первых, мы создадим файлы public/index.php и public/.htaccess. Запустите ваш любимый редактор и скопируйте следующие куски кода:

public/index.php

public/.htaccess

Как вы видите, все так же, как и в любом приложении на базе Zend Framework.

Файл application/bootstrap.php выглядит немного иначе. Я разделил его на два файла: application/bootstrap.php и application/global.php. Первый занимается обработкой запросов клиентов, последний подключает все необходимые файлы. Я разделил их потому, что код из global.php нужен также в скриптах Doctrine (которое мы увидим через минутку).

application/global.php

application/bootstrap.php

Давайте рассмотрим его шаг за шагом:

Это всегда хорошая идея — установить правильную обработку ошибок и часовой пояс. Здесь ничего особенного.

Именно здесь мы подключаем Doctrine. Как вы видите, мы установили include_path для подключения Zend Framework и Doctrine. Мы также подключили папки, в которых Doctrine будет генерировать файлы моделей. Заметим, что нам не нужно настраивать автозагрузчик Doctrine. Использование загрузчика Зенда работает так же хорошо, до тех пор, пока include_path настроен правильно. Предупреждение: в текущей версии ZF (1.5.1) есть ошибка, приводящая к печати безобидных предупреждений при использовании классов шаблонов Doctrine. Она должна быть исправлена в будущих версиях.

Это последний кусочек кода. Во-первых, мы создали соединение с базой данных. Чтобы не усложнять, я просто забил в код это строковое значение. В реальных системах вы должны использовать что-нибудь подобное Zend_Config. Я оставлю это вам в качестве домашнего задания. Во-вторых, этот кусок кода настраивает пути к инструментам Doctrine для командной строки (которые генерируют весь код и схемы баз данных). Я сохранил этот массив в Zend_Registry, который является универсальным хранилищем, местом, где вы можете хранить объекты и получить их в нужный момент.

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

Содержимое файла application/bootstrap.php не должно вызывать у вас удивления. Опять же, я пытался сохранить этот пример как можно более простым.

Наконец, давайте настроим интерфейс командной строки Doctrine:

scripts/doctrine-cli

Сделайте этот сценарий исполняемым:

и вы готовы двигаться дальше.

Создание приложения

Теперь, когда мы подготовили базовые скрипты, давайте создадим простейшее приложение с использованием Zend Framework и Doctrine. Мы будем создавать очень простую доску сообщений, место, где пользователи могут отправлять сообщения и просматривать чужие сообщения.

Мы будем делать это очень просто: только один контроллер и один скрипт. Скопируйте следующие файлы:

application/views/scripts/index/index.phtml

application/controllers/IndexController.php

Как вы видите, остались три больших TODO пункта: один в скрипте и два в контроллере. Это места, где мы будем подключать Doctrine. Но для этого мы должны в первую очередь определить некоторые объекты данных. Мы вернемся к контроллеру и скрипту позже, сейчас пришло время для создания схемы базы данных.

Определение схемы базы данных

Doctrine позволяет указать ваши схемы баз данных в YAML-файлах, очень простом текстовом представлении. Мы воспользуемся этим и пусть Doctrine генерирует PHP-файлы автоматически. Я определил следующие схему:

application/doctrine/schema/schema.yml

В этом приложении нам нужен только один простой объект: Сообщение, имеющий 4 поля: обязательный уникальный идентификатор, время, когда сообщение было отправлено, название темы и само сообщение.

Теперь мы можем использовать командную строку Doctrine для создания файлов моделей и таблиц баз данных. Из вашего шелла выполните следующее:

Если все прошло хорошо, ошибок напечатано не будет. Если это все же произошло, проверьте параметры соединения с БД и указание путей.

Соеденим все вместе

Теперь давайте окончательно решим куски TODO. Мы заменим их шаг за шагом. Полный код для завершенных файлов имеется в конце статьи. Во-первых, мы добавим код для хранения сообщений. Замените это:

Вот этим (игнорируя тэги <?php и ?>):

Как вы видите, мы используем объект класса Сообщение. Этот класс был автоматически сгенерирован Doctrine. Вы можете найти его в application/models/. Автозагрузчик позаботится о загрузке всего, что потребуется.

Мы также должны получать сообщения, чтобы показать их. Во-первых, контроллер. Заменить:

На:

Опять же, это очень просто. Я использовал DQL запрос, чтобы сортировать в обратной хронологической последовательности.

Теперь все, что осталось — показать сообщение в нашем скрипте представления. Опять же, замените:

На:

И мы сделали, результат должен выглядеть подобно этому:

Завершенное приложение

Завершенное приложение

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

Заключение

Итак, у вас теперь есть чистое и ясное приложение-пример интеграции Zend Framework и Doctrine. Как следование некоторой философии, эта возможность интеграции их очень понятным образом, превращает создание приложений в сплошное удовольствие.

Если у Вас есть какие-либо замечания, комментарии или вопросы, не стесняйтесь, пишите мне по электронной почте (ruben@savanne.be), или оставляйте комментарий в моем блоге.

Приложение: Полный код файлов

application/controllers/IndexController.php

application/views/scripts/index/index.phtml

Похожие записи

  • Сергей

    Всё это хорошо, но вот какой возникает вопрос: для нужд приложения мы используем Доктрин, но для своих внутренних нужд Zend Framework использует Zend_Db, который также создаёт коннектор к базе. Как сделать так, чтобы этот коннектор был один и для Доктрин и для Zend_Db?

  • http://lobach.info Лобач Олег

    Э... это какие свои внутренние нужды у ZF?

    • http://chat-ogo.ru Пришелец

      Zend_Auth_Adapter_DbTable используется с параметром коннекта БД

  • http://lobach.info Лобач Олег

    На работе было несколько проектов на связке доктрины и ЗФ. Ни разу не возникло ситуации, когда поднимался коннект Zend_Db.

    • Андрей Буторин

      Олег, впорос по поводу проектов на ЗФ и Д. Меня интересует насколько реально сделать высоконагруженный сайт на связке ЗФ и Доктрины. По своему опыту знаю, что ЗФ вещь небыстрая, но удобная. Подозреваю, что с доктриной обстоит так же. Могли бы вы привести примеры проектов на связке ЗФ и доктрины или хотя бы описать их направленность и примерную посещаемость? Вообще, как на ваш взгляд, можно ли использовать ЗФ и Д в любом проекте (не задумываясь о будущей посещаемости сайта)?

      • http://lobach.info Лобач Олег

        Андрей, опыта разработки высоконагруженных проектов на связке ZF + D у меня еще нет. Но есть опыт разработки только на ZF (т.е. с использованием нативного Zend_Db) достаточно нагруженного проекта. В качестве примера могу привести iii.ru — несколько десятков тысяч посетителей и несколько миллионов запросов в сутки. Построен на ZF. Единственное изменение в фреймворке — полностью убрали все require_once и задействовали автозагрузку.

        Вопрос производительности решается кэшированием и увеличением мощности сервера (в том числе и увеличением количества серверов). Просто при проектировании высоконагруженного приложения надо закладывать в архитектуру эти решения. Конечно, гугл на ZF врядли целесообразно писать, но проект на несколько десятков (и даже сотен) тысяч вполне реально.

        • Андрей Буторин

          Спасибо за обнадеживающий ответ. (вот кстати нашел: у человека 100 000 посетителей ежедневно till.vox.com/library/post...performance.html)

          • http://lobach.info Лобач Олег

            Я тоже натыкался на этот пост и он у меня помечен «на прочтение»

  • Сергей

    Прошу прощения, я не слишком компетентен, вот например как у нас работает AuthController:

    разве класс Zend_Auth_Adapter_DbTable не должен в качестве параметра получать объект Zend_DB? и как это сделать с помощью Доктрины?

    • http://lobach.info Лобач Олег

      Нашел реализацию адаптера для Doctrine — j.mp/6Hv90s

  • http://lobach.info Лобач Олег

    Да. Тут соглашусь. Класс Zend_Auth_Adapter_DbTable использует коннект Zend_Db.

    Чтобы в данном случае воспользоваться доктриной, надо написать собственный адаптер, реализующий интерфейс Zend_Auth_Adapter_Interface. В принципе, повторить Zend_Auth_Adapter_DbTable для доктрины не должно составить особого труда — там все достаточно просто и прозрачно.

  • Сергей

    Спасибо, разобрался. Жаль, что никто не осветил эту проблему. Ведь получается что все используют два соединения с базой.

  • http://lobach.info Лобач Олег

    Рад что чем-то помог :)

  • haspadar

    Могу обрадовать — ничего писать не надо даже для этого.

    Есть Zend_Auth_Adapter_Doctrine_Table официальный причем

    http://framework.zend.com/wiki/display/ZFPROP/Zend_Auth_Adapter_Doctrine_Table

  • http://lobach.info Лобач Олег

    Отличная новость! Спасибо.

    Правда, это еще не официальный адаптер, это всего лишь предложение, но воспользоваться вполне возможно.

    Еще раз спасибо.

  • nod

    Внимание для корректного отображения результатов работы контролера (ZF 1.6) необходимо изменить bootstrap.php на следующий.

    Это строка некорректна:

    FILE: application/bootstrap.php

  • nek

    Здравствуйте.

    Могли бы вы написать статью по интеграции ZF v1.10 и Doctrine?

    Пробовал адаптировать код из этой стати для ZF 1.10.

    Получилось мягко сказать, погано.

    • http://lobach.info Лобач Олег

      Я давно собираюсь это сделать, но сейчас свободного времени практически нет :(

      А в чем именно проблема?