Готовы вывести свои навыки PHP на новый уровень? В этой новой серии «С нуля» мы сосредоточимся исключительно на Zend Framework — полнофункциональном PHP-фреймворке, созданном Zend Technologies. Этот второй урок из нашей серии называется «Модели и интеграция доктрины ORM».
Рассмотрение
Добро пожаловать в наш Zend Framework из серии Scratch ! В нашем последнем уроке мы узнали некоторые основные вещи о Zend Framework, такие как:
- Где скачать последние файлы Zend Framework
- Где и как его настроить локально
- Создание вашего первого проекта Zend Framework и настройка VirtualHost на вашем веб-сервере
- Как именно Zend Framework реализует шаблон MVC и стандартную маршрутизацию приложений
- Передача данных из контроллера в его представление
- Создание макета для всего сайта для вашего приложения Zend Framework
- Создание новых контроллеров и действий
Если вы еще этого не сделали, вам следует прочитать предыдущее руководство . Это действительно облегчит вам понимание некоторых основ Zend Framework и поможет вам понять некоторые вещи, которые мы обсудим в этом руководстве.
Во второй части этой серии мы поговорим о важной части любого веб-приложения — МОДЕЛЯХ . Мы также рассмотрим, как интегрировать очень популярный Doctrine ORM с нашим проектом Zend Framework, и выясним, почему его гораздо лучше использовать, чем родной Zend Framework Zend_Db
. Итак, без лишних слов, давайте начнем!
Что такое «модели»?
Когда я начал пытаться понять концепцию MVC, я прочитал немало аналогий, в которых попытался объяснить, что конкретно представляет каждый из этих компонентов. Одна из лучших аналогий, которые я читал до сих пор, была из этой статьи, Другой способ думать о MVC . Это выглядит примерно так:
Итак, давайте представим банк.
Сейф — это база данных — здесь хранятся все самые важные вкусности, и они хорошо защищены от внешнего мира.
Тогда у нас есть банкиры или в программном плане модели . Банкиры — единственные, кто имеет доступ к сейфу (БД). Они, как правило, толстые, старые и ленивые, что очень хорошо следует одному из правил MVC: * толстые модели , тощие контроллеры *. Мы увидим, почему и как эта аналогия применима чуть позже.
Теперь у нас есть среднестатистические банковские работники, суслики, бегуны, контролеры. Контроллеры или суслики бегают, поэтому они должны быть стройными и худыми. Они берут добычу или информацию у банкиров ( Модели ) и передают ее клиентам банка.
Банкиры ( Модели ) были на работе некоторое время, поэтому они принимают все важные решения. Что приводит нас к другому правилу: * сохранить как можно больше бизнес-логики в модели *. Контролеры, наши среднестатистические работники, не должны принимать такие решения, они спрашивают у банкира подробности, получают информацию и передают ее клиенту (представление). Следовательно, мы продолжаем следовать правилу * жирных моделей , тощих контроллеров *. Суслики не принимают важных решений, но они не могут быть просто тупыми (поэтому небольшая бизнес-логика в контроллере в порядке). Однако, как только суслик начинает слишком много думать, банкир расстраивается и ваш банк (или ваше приложение) выходит из бизнеса. Итак, еще раз, всегда помните, чтобы перенести как можно больше бизнес-логики (или принятия решений) в модель.
Теперь банкиры уверены, что, черт возьми, они не собираются напрямую общаться с клиентами (вид), они слишком важны в своих удобных креслах для этого. Таким образом, соблюдается другое правило: * Модели не должны общаться с представлениями *. Эта связь между банкиром и клиентом (модель и представление) всегда обрабатывается сусликом (контроллером). (Да, есть некоторые исключения из этого правила для супер VIP-клиентов, но пока давайте придерживаться основ).
Бывает и так, что одному работнику (контролеру) приходится получать информацию от нескольких банкиров , и это вполне приемлемо. Однако, если банкиры связаны друг с другом (в противном случае, как они могли бы получить такую хорошую работу?)… Банкиры ( Модели ) сначала будут общаться друг с другом, а затем передавать накопительную информацию своему суслику, который с радостью доставит ее клиенту ( Посмотреть). Итак, вот еще одно правило: * Связанные модели предоставляют информацию контроллеру через их ассоциации (отношения) *.
Так что насчет нашего клиента (вид)? Банки совершают ошибки, и клиент должен быть достаточно умен, чтобы сбалансировать свой счет и принять некоторые решения. В терминах MVC мы получаем еще одно простое правило: * вполне допустимо, чтобы представления содержали некоторую логику, которая касается представления или представления *. Следуя нашей аналогии, клиент не забудет надеть брюки, когда они идут в банк, но они не собираются рассказывать банкирам, как обрабатывать транзакции.
Диаграмма архитектуры MVC
Изображение предоставлено ash.MVC (теперь называется Opendelight)
В двух словах:
- Модели являются представителями базы данных и должны быть там, где находится вся бизнес-логика приложения.
- Контроллеры связываются с моделями и просят их получить необходимую им информацию.
- Эта информация затем передается контроллером в представление и отображается
- Очень редко модель напрямую взаимодействует с представлением, но иногда это может происходить при необходимости
- Модели могут общаться с другими моделями и не являются самодостаточными. У них есть отношения, которые переплетаются друг с другом
- Эти отношения облегчают и ускоряют получение информации контроллером, поскольку он не должен взаимодействовать с различными моделями — модели могут делать это сами
Мы можем видеть, насколько важны Модели в любом приложении, так как оно отвечает за любые динамические действия, которые происходят в приложении. Теперь, когда у нас есть достаточно четкое понимание обязанностей модели, а также представления и контроллера, давайте погрузимся в реализацию моделей в нашем приложении.
Шаг 1 — Настройка приложения Zend для подключения к базе данных
Первое, что нам нужно сделать, это подключить наше приложение Zend к базе данных. К счастью, команда zf
может позаботиться об этом. Откройте командную строку (или терминал), cd
в папку thenextsocial
и введите следующее:
1
|
zf configure db-adapter «adapter=PDO_MYSQL&dbname=thenextsocial&host=localhost&username=[your local database username]&password=[your local database password]» -s development
|
Если все правильно, вы должны получить вывод, похожий на:
1
|
A db configuration for the development section has been written to the application config file.
|
Кроме того, вы должны увидеть две новые строки в вашем файле application.ini
:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
resources.db.adapter = «PDO_MYSQL»
resources.db.params.dbname = «thenextsocial»
resources.db.params.host = «localhost»
resources.db.params.username = «[your local database username]»
resources.db.params.password = «[your local database password]»
</p></code>
<h3>The application.ini explained</h3>
<p>The <code>application.ini</code> is a configuration file which should contain all of the configuration we have for an application.
<div class=»tutorial_image»>
<img src=»http://nettuts.s3.amazonaws.com/1122_zend2/images/application_ini.png» alt=»The application.ini file» title=»The application.ini file» />
<small>The <code>application.ini</code> file</small>
</div>
<p>I’m sure you’ve noticed that the <code>application.ini</code> file has sections enclosed in [square brackets].
<p>To add to that, you can “inherit”
<p>To configure our project to use the <code>development</code> configuration settings, open or create an <strong>.htaccess</strong> file inside the <strong>public_html</strong> folder, and make sure that it looks like this:</p>
[php]
SetEnv APPLICATION_ENV development
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ — [NC,L]
RewriteRule ^.*$ index.php [NC,L]
|
Мы ясно видим, что директива SetEnv APPLICATION_ENV
устанавливает среду нашего приложения. Если и когда мы переместим приложение в другую среду, это должно быть единственное, что нам нужно изменить. Это гарантирует, что все, на что наше приложение работает, определено в application.ini
, что гарантирует, что наше приложение не полагается на какие-либо внешние настройки. Это помогает устранить проблему «она работает на моей машине для разработки, почему она не работает на рабочем сервере?» .
Шаг 2 — Создание базы данных и некоторых таблиц
Прежде чем мы создадим вашу первую модель для приложения, нам понадобится база данных, которую модель будет представлять первой. Давайте начнем с чего-то простого — таблицы User , где мы сохраним всех зарегистрированных пользователей для TheNextSocial .
Войдите в свою базу данных MySQL и создайте базу данных под названием thenextsocial . После создания выполните следующий запрос для создания таблицы User и прилагаемой таблицы User Settings :
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
CREATE TABLE `thenextsocial`.`user` (
`id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
`email` VARCHAR(100) NOT NULL,
`password` TEXT NOT NULL,
`salt` TEXT NOT NULL,
`date_created` DATETIME NOT NULL,
PRIMARY KEY (`id`),
UNIQUE INDEX `Index_email`(`email`)
)
ENGINE = InnoDB
CHARACTER SET utf8 COLLATE utf8_general_ci;
CREATE TABLE `thenextsocial`.`user_settings` (
`id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` INTEGER UNSIGNED NOT NULL,
`name` VARCHAR(100) NOT NULL,
`value` TEXT NOT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `FK_user_settings_user_id` FOREIGN KEY `FK_user_settings_user_id` (`user_id`)
REFERENCES `user` (`id`)
ON DELETE CASCADE
ON UPDATE CASCADE
)
ENGINE = InnoDB
CHARACTER SET utf8 COLLATE utf8_general_ci;
|
Эти SQL-запросы должны создавать две таблицы. Пользовательская таблица со следующими столбцами:
- id — уникальный идентификатор для каждого пользователя
- email — адрес электронной почты пользователя, также уникальный
- пароль — пароль пользователя, который мы будем хэшировать
- соль — случайная соль, которую мы будем использовать для хеширования пароля пользователя
- date_created — дата и время создания пользовательской записи
И таблица user_settings , где мы будем хранить любые пользовательские настройки со столбцами:
- id — уникальный идентификатор для каждого параметра
- user_id —
user_id
который является внешним ключом дляuser.id
- name — строка текста, представляющая настройку
- значение — значение настройки
Следует отметить, что таблица « Пользователь и пользовательские настройки» имеет отношение « один ко многим» , что означает, что одна запись пользователя может быть связана с несколькими записями пользовательских настроек . Это облегчит хранение любой информации, связанной с пользователем, например, его имени или фотографии профиля.
Теперь, когда у нас есть несколько таблиц для игры, давайте узнаем, как создать нашу первую модель: модель пользователя .
Шаг 3 — Создание вашей первой модели
Шаблон проектирования DAO
Как и во многих приложениях, обычный способ использования моделей моделей в Zend Framework — это использование популярного шаблона проектирования, называемого шаблоном «DAO». В этом шаблоне у нас есть следующие компоненты:
Шаблон проектирования DAO
- Table Data Gateway (DataSource), который соединяет наше приложение с источником данных, таблицей MySQL
- Data Mapper (DataAccessObject), который отображает данные, извлеченные из базы данных, в
- Объект данных (Data), который представляет строку из нашей базы данных, после того, как DataMapper отобразит в нее данные
Начнем с создания шлюза табличных данных для таблицы User
с помощью инструмента zf
CLI:
1
2
3
|
zf create db-table User user
Creating a DbTable at thenextsocial/application/models/DbTable/User.php
Updating project profile ‘thenextsocial/.zfproject.xml’
|
zf create db-table
принимает два параметра:
- ClassName — название класса
- database_table — имя таблицы
Откройте файл User.php
находящийся в папке application/models/DbTable
и он должен выглядеть следующим образом:
1
2
3
4
5
6
7
8
9
|
<?php
class Application_Model_DbTable_User extends Zend_Db_Table_Abstract
{
protected $_name = ‘user’;
}
|
Теперь давайте создадим класс Data Mapper . Опять же, используя инструмент zf
CLI:
1
2
3
|
zf create model UserMapper
Creating a model at thenextsocial/application/models/UserMapper.php
Updating project profile ‘thenextsocial/.zfproject.xml’
|
Файл UserMapper.php
будет пустым прямо сейчас, но мы добавим немного кода позже. Сейчас нам нужно создать объект данных , который является моделью User
:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
zf create model User
Creating a model at thenextsocial/application/models/User.php
Updating project profile ‘thenextsocial/.zfproject.xml’
</p></code>
<p>Now that we have all three components of the DAO pattern, we create the code for the files.
[php]
<?php
class Application_Model_UserMapper
{
protected $_db_table;
public function __construct()
{
//Instantiate the Table Data Gateway for the User table
$this->_db_table = new Application_Model_DbTable_User();
}
public function save(Application_Model_User $user_object)
{
//Create an associative array
//of the data you want to update
$data = array(
’email’ => $user_object->email,
‘password’ => $user_object->password,
);
//Check if the user object has an ID
//if no, it means the user is a new user
//if yes, then it means you’re updating an old user
if( is_null($user_object->id) ) {
$data[‘salt’] = $user_object->salt;
$data[‘date_created’] = date(‘Ymd H:i:s’);
$this->_db_table->insert($data);
} else {
$this->_db_table->update($data, array(‘id = ?’ => $user_object->id));
}
}
public function getUserById($id)
{
//use the Table Gateway to find the row that
//the id represents
$result = $this->_db_table->find($id);
//if not found, throw an exsception
if( count($result) == 0 ) {
throw new Exception(‘User not found’);
}
//if found, get the result, and map it to the
//corresponding Data Object
$row = $result->current();
$user_object = new Application_Model_User($row);
//return the user object
return $user_object;
}
}
|
Здесь у нас есть три метода:
- __construct () — конструктор для класса. После создания он создает экземпляр шлюза табличных данных и сохраняет его
- save (Application_Model_User $ user_object) — принимает
Application_Model_User
и сохраняет данные из объекта в базу данных - getUserById ($ id) — принимает целочисленный
$id
который представляет одну строку из таблицы базы данных, извлекает ее, затем возвращает Application_Model_User с сопоставленными данными
Откройте User.php
и вставьте следующий код в:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
<?php
class Application_Model_User
{
//declare the user’s attributes
private $id;
private $email;
private $password;
private $salt;
private $date_created;
//upon construction, map the values
//from the $user_row if available
public function __construct($user_row = null)
{
if( !is_null($user_row) && $user_row instanceof Zend_Db_Table_Row ) {
$this->id = $user_row->id;
$this->email = $user_row->email;
$this->password = $user_row->password;
$this->salt = $user_row->salt;
$this->date_created = $user_row->date_created;
}
}
//magic function __set to set the
//attributes of the User model
public function __set($name, $value)
{
switch($name) {
case ‘id’:
//if the id isn’t null, you shouldn’t update it!
if( !is_null($this->id) ) {
throw new Exception(‘Cannot update User\’s id!’);
}
break;
case ‘date_created’:
//same goes for date_created
if( !is_null($this->date_created) ) {
throw new Exception(‘Cannot update User\’s date_created’);
}
break;
case ‘password’:
//if you’re updating the password, hash it first with the salt
$value = sha1($value.$this->salt);
break;
}
//set the attribute with the value
$this->$name = $value;
}
public function __get($name)
{
return $this->$name;
}
}
|
- __construct ($ user_row) — принимает необязательный объект
Zend_Db_Table_Row
, который представляет одну строку из базы данных, и отображает данные в себя - __set ($ name, $ value) — магическая функция, которая заботится о настройке всех атрибутов для модели.
- __get ($ name) — магическая функция, которая заботится о получении атрибута модели.
Давайте попробуем это! Если вы следовали предыдущему руководству, у вас должен быть файл IndexController.php
. Откройте его и вставьте этот код, который создает нового пользователя:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
public function indexAction()
{
// action body
$this->view->current_date_and_time = date(‘M d, Y — H:i:s’);
$user = new Application_Model_User();
$user->email = ‘[email protected]’;
$user->salt = sha1(time());
$user->password = ‘test’;
$user->date_created = date(‘Ymd H:i:s’);
$user_mapper = new Application_Model_UserMapper();
$user_mapper->save($user);
}
|
Теперь перейдите на http://thenextsocial.local/
. Как только он загрузится, проверьте таблицу thenextsocial.user
на MySQL и, если все работает, у вас должна быть новая запись User
!
Новая запись User
!
Теперь давайте попробуем обновить эту запись. Вернитесь к IndexController.php
и обновите код, чтобы он соответствовал следующему:
01
02
03
04
05
06
07
08
09
10
|
public function indexAction()
{
// action body
$this->view->current_date_and_time = date(‘M d, Y — H:i:s’);
$user_mapper = new Application_Model_UserMapper();
$user = $user_mapper->getUserById(1);
$user->email = ‘[email protected]’;
$user_mapper->save($user);
}
|
Проверьте таблицу MySQL еще раз, и вы должны увидеть, что адрес электронной почты для записи был обновлен!
Обновленная запись User
Поздравляем! Вы успешно создали свою первую модель Zend Framework !
Учение ОРМ
Вступление
На веб-сайте Doctrine ORM http://doctrine-project.org/projects/orm :
Объектно-реляционный маппер (ORM) для PHP, расположенный на мощном уровне абстракции базы данных (DBAL). Одной из его основных функций является возможность писать запросы к базе данных на проприетарном объектно-ориентированном диалекте SQL под названием Doctrine Query Language (DQL), вдохновленном Hibernates HQL. Это предоставляет разработчикам мощную альтернативу SQL, которая поддерживает гибкость без необходимости дублирования кода.
По сути, библиотека Doctrine ORM абстрагирует большую часть, если не всю реализацию модели для приложения. Вот некоторые из невероятных преимуществ, которые я обнаружил при использовании Doctrine с Zend Framework:
- Очень прост в использовании, гарантированно сократит время разработки вдвое
- Работает так же хорошо с различными типами БД с минимальными необходимыми настройками. Например, Doctrine упростила для меня перенос приложения, над которым я работал ранее, с использованием MySQL на MSSQL
- Инструмент скаффолдинга, называемый
Doctrine_Cli
который очень быстро создает модели из базы данных.
Для начала вам следует сначала загрузить библиотеку Doctrine ORM с их сайта. Я буду использовать версию 1.2.4 . Перейдите по адресу http://www.doctrine-project.org/projects/orm/1.2/download/1.2.4 и нажмите ссылку Скачать пакет 1.2.4 .
Загрузка Доктрины ОРМ
После загрузки откройте его и извлеките содержимое. Внутри вы должны увидеть папку Doctrine-1.2.4 и файл package.xml . Зайдите в папку, и вы увидите папку Doctrine, файл Doctrine.php и файл LICENSE .
Doctrine скачать содержимое
Скопируйте папку Doctrine и файл Doctrine.php и поместите его в путь включения вашей установки PHP. Если вы помните, как мы настраивали Zend Framework из предыдущего урока, то, скорее всего, это та же папка, в которую вы поместили файлы библиотеки Zend .
Библиотека Doctrine с библиотекой Zend в PHP include_path
Теперь мы готовы интегрировать его с нашим приложением Zend! Начните с повторного открытия application.ini
и добавления следующей конфигурации в блок [development : production]
:
01
02
03
04
05
06
07
08
09
10
11
|
;Doctrine settings
resources.doctrine.connection_string = «mysql://[replace with db username]:[replace with db password]@localhost/thenextsocial»
resources.doctrine.models_path = APPLICATION_PATH «/models»
resources.doctrine.generate_models_options.pearStyle = true
resources.doctrine.generate_models_options.generateTableClasses = true
resources.doctrine.generate_models_options.generateBaseClasses = true
resources.doctrine.generate_models_options.classPrefix = «Model_»
resources.doctrine.generate_models_options.baseClassPrefix = «Base_»
resources.doctrine.generate_models_options.baseClassesDirectory =
resources.doctrine.generate_models_options.classPrefixFiles = false
resources.doctrine.generate_models_options.generateAccessors = false
|
Теперь, когда мы настроили нашу конфигурацию, откройте файл Bootstrap.php
приложения. Вы найдете это в thenextsocial/application
.
Bootstrap.php
Bootstrap.php
позволяет нам инициализировать любые ресурсы, которые мы могли бы использовать в нашем приложении. По сути, все ресурсы, которые нам нужны, должны быть размещены здесь. Мы углубимся в это более подробно позже в этой серии, но сейчас все, что вам нужно знать, это то, что формат методов здесь такой:
1
2
3
4
|
protected function _initYourResource()
{
//Do your resource setup here
}
|
Внутри файла Bootstra.php
добавьте следующий код для инициализации Doctrine с приложением:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
<?php
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
public function _initDoctrine()
{
//require the Doctrine.php file
require_once ‘Doctrine.php’;
//Get a Zend Autoloader instance
$loader = Zend_Loader_Autoloader::getInstance();
//Autoload all the Doctrine files
$loader->pushAutoloader(array(‘Doctrine’, ‘autoload’));
//Get the Doctrine settings from application.ini
$doctrineConfig = $this->getOption(‘doctrine’);
//Get a Doctrine Manager instance so we can set some settings
$manager = Doctrine_Manager::getInstance();
//set models to be autoloaded and not included (Doctrine_Core::MODEL_LOADING_AGGRESSIVE)
$manager->setAttribute(
Doctrine::ATTR_MODEL_LOADING,
Doctrine::MODEL_LOADING_CONSERVATIVE);
//enable ModelTable classes to be loaded automatically
$manager->setAttribute(
Doctrine_Core::ATTR_AUTOLOAD_TABLE_CLASSES,
true
);
//enable validation on save()
$manager->setAttribute(
Doctrine_Core::ATTR_VALIDATE,
Doctrine_Core::VALIDATE_ALL
);
//enable sql callbacks to make SoftDelete and other behaviours work transparently
$manager->setAttribute(
Doctrine_Core::ATTR_USE_DQL_CALLBACKS,
true
);
//not entirely sure what this does 🙂
$manager->setAttribute(
Doctrine_Core::ATTR_AUTO_ACCESSOR_OVERRIDE,
true
);
//enable automatic queries resource freeing
$manager->setAttribute(
Doctrine_Core::ATTR_AUTO_FREE_QUERY_OBJECTS,
true
);
//connect to database
$manager->openConnection($doctrineConfig[‘connection_string’]);
//set to utf8
$manager->connection()->setCharset(‘utf8’);
return $manager;
}
protected function _initAutoload()
{
// Add autoloader empty namespace
$autoLoader = Zend_Loader_Autoloader::getInstance();
$resourceLoader = new Zend_Loader_Autoloader_Resource(array(
‘basePath’ => APPLICATION_PATH,
‘namespace’ => »,
‘resourceTypes’ => array(
‘model’ => array(
‘path’ => ‘models/’,
‘namespace’ => ‘Model_’
)
),
));
// Return it so that it can be stored by the bootstrap
return $autoLoader;
}
}
|
Настройки, которые я здесь выполнил, основаны на сценарии, который я нашел в прошлом на http://dev.juokaz.com , и который поддерживал Юозас Казюкенас, один из членов команды проекта Doctrine. К сожалению, блог уже закрыт, поэтому я не смогу на него ссылаться. Также обратите внимание, что у нас есть другой метод с именем _initAutoload()
. Это в основном инициализирует Zend Autoloader, который будет автоматически загружать все сгенерированные модели в папке models
. Это избавляет нас от необходимости включать эти файлы один за другим.
Затем нам нужно настроить сценарий командной строки Doctrine, который мы будем использовать для автоматической генерации моделей из базы данных. Вернитесь к thenextsocial
папке и создайте папку с именем scripts
. Внутри создайте файл с именем doctrine-cli.php
и поместите в него следующее:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
<?php
/**
* Doctrine CLI script
*
* @author Juozas Kaziukenas ([email protected])
*/
define(‘APPLICATION_ENV’, ‘development’);
define(‘APPLICATION_PATH’, realpath(dirname(__FILE__) . ‘/../application’));
set_include_path(implode(PATH_SEPARATOR, array(
realpath(APPLICATION_PATH . ‘/../library’),
‘./’,
get_include_path(),
)));
require_once ‘Zend/Application.php’;
// Create application, bootstrap, and run
$application = new Zend_Application(
APPLICATION_ENV,
APPLICATION_PATH .
);
$application->getBootstrap()->bootstrap(‘doctrine’);
// set aggressive loading to make sure migrations are working
Doctrine_Manager::getInstance()->setAttribute(
Doctrine::ATTR_MODEL_LOADING,
Doctrine_Core::MODEL_LOADING_AGGRESSIVE
);
$options = $application->getBootstrap()->getOptions();
$cli = new Doctrine_Cli($options[‘doctrine’]);
$cli->run($_SERVER[‘argv’]);
|
Вернитесь внутрь к папке с вашими models
и удалите имеющиеся у нас файлы пользовательских моделей (если хотите, вы можете сначала переместить их в другое место, но их не должно быть внутри папки). Затем откройте командную строку (или терминал), cd
в папку scripts
и введите следующую команду:
1
|
php doctrine-cli.php
|
Вы должны увидеть что-то вроде этого:
Ожидаемый вывод CLI Doctrine
Если все получилось, начнем создавать модели! Введите следующее:
1
|
php doctrine-cli.php generate-models-db
|
Теперь вы должны увидеть следующий вывод:
Генерация моделей с использованием Doctrine CLI
Если вы это сделали, проверьте папку с вашими models
раз, и вы увидите несколько совершенно новых моделей User
и UserSettings
, сгенерированных Doctrine!
Сгенерированные модели!
Если вы откроете файлы, вы не увидите много внутри. Большая часть кода для моделей абстрагируется от библиотеки Doctrine. Расширяя класс Doctrine_Record
, мы получили много готовых методов из библиотеки. IndexController.php
откройте IndexController.php
и замените старый тестовый код следующим:
01
02
03
04
05
06
07
08
09
10
11
12
|
public function indexAction()
{
// action body
$this->view->current_date_and_time = date(‘M d, Y — H:i:s’);
$user = new Model_User();
$user->email = ‘[email protected]’;
$user->password = ‘test’;
$user->salt = sha1(time());
$user->date_created = date(‘Ymd H:i:s’);
$user->save();
}
|
После этого вернитесь на http: //thenextsocial.local . Если страница загружается, проверьте таблицу MySQL, и вы увидите, что была добавлена новая запись о User
!
Запись User
через Doctrine ORM
Теперь давайте попробуем несколько более сложных вещей — извлечение существующего User
помощью встроенных методов Doctrine и его обновление. Обновите код так, чтобы он выглядел так:
1
2
3
4
5
6
7
8
9
|
public function indexAction()
{
// action body
$this->view->current_date_and_time = date(‘M d, Y — H:i:s’);
$user = Doctrine_Core::getTable(‘Model_User’)->findOneByEmailAndPassword(‘[email protected]’, ‘test’);
$user->password = ‘new_password’;
$user->save();
}
|
Метод findOneByEmailAndPassword()
— это удобный метод, предварительно созданный Doctrine, чтобы упростить выбор одной строки из базы данных. Самое замечательное в этом то, что вы можете смешивать и сопоставлять столбцы таблицы в методе. Например, вы можете вызвать что-то вроде findOneByIdAndNameAndPasswordAndSalt()
и оно все равно будет работать!
Обновление User
записи через Doctrine ORM
Теперь мы можем сделать намного больше, используя Doctrine ORM для реализации модели приложения. Такие вещи, как Doctrine Query Language (DQL) , использующие преимущества отношений между моделями и генерирующие модели из YAML . В оставшейся части серии мы будем использовать Doctrine ORM для реализации приложения в модели, так что вы фактически изучите две вещи в серии вместо одной! Гол!
Вывод
К настоящему времени вы должны знать следующее:
- Что такое «модели»
- Подключение вашего Zend-приложения к базе данных
- Как работает
application.ini
- Шаблон проектирования DAO
- Создание моделей с использованием инструмента ZF CLI
- Где скачать Doctrine ORM и как его установить
- Интеграция Doctrine ORM с вашим приложением Zend
-
Bootstrap.php
- Генерация моделей с помощью инструмента Doctrine CLI
- Основное использование моделей, созданных с помощью Doctrine
Теперь, когда вы знаете, как реализовать Модели в приложении на основе Zend Framework, у вас есть знания для создания динамических веб-сайтов. Попробуйте поиграться с приложением, создайте несколько новых контроллеров и моделей, которые читают, обновляют, сохраняют и удаляют из базы данных.
В нашем следующем уроке мы узнаем о некоторых часто используемых компонентах библиотеки Zend Framework, компонентах Zend_Auth и Zend_Acl и создадим систему аутентификации TheNextSocial !
До этого следите за обновлениями и помните, что весь код, используемый здесь, доступен в репозитории TheNextSocial GitHub !