Zend Framework

Работа с компонентами в Zend Framework. Структура директорий, модели, представления, контроллеры, модули, маршруты. Взаимодействие между компонентами. Работа с формами и моделями объектно-ориентированного фреймворка. Паттерн Data Mapper, особенности.

Рубрика Программирование, компьютеры и кибернетика
Вид курсовая работа
Язык русский
Дата добавления 12.01.2016

Введение

ZendFramework - это открытый, объектно-ориентированый фреймворк для PHP 5. Zend Framework часто называют "библиотекой компонентов" потому что он имеет много слабо связаных компонентов, которые можно использовать, в большей или меньшей степени, независимо.

ZendFramework также предоставляет расширенную реализацию паттерна Модель-Вид-Контроллер (Model-View-Controller - MVC), который можно использовать для создания базовой структуры приложения. MVC своего рода стандарт в проектировании современных веб-приложений, так как большая часть кода веб-приложений подпадает под одну из трех категорий: представление, бизнес логику или доступ к данным. Паттерн MVC хорошо моделирует разделение этих понятий. В результате, код представления, бизнес логики и доступа к данным разделен и сгруппирован в разных частях приложения. Четко определенное разделение необходимо для поддержания кода организованным, особенно при командной разработке.

Рисунок 1 - Общий вид MVC

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

View - Вид, определяет, какое представление имеет информация, передаваемая пользователю. Обычно, контроллеры передают данные виду для отображения их в каком-либо формате. Кроме того, вид часто получает данные от пользователя. Это та часть паттерна, в которой, вероятнее всего, находится HTML разметка вашего MVC приложения.

Controller - Контроллеры связывают весь паттерн в единое целое. Они управляют моделями, на основе пользовательского ввода и других факторов решают какой из видов отобразить, передают виду необходимые данные, или полностью передают управление другому контроллеру.

ZendFramework имеет следующие особенности:

Все компоненты написаны на полностью объектно-ориентированном коде PHP 5 и E_STRICT совместимы

Архитектура "слабого связывания" с минимальными зависимостями между частями проекта(Use-at-will architecture with loosely coupled components and minimal interdependencies)

Расширяемая реализация MVC, по умолчанию поддерживающая макеты и PHP-шаблоны

Поддержка большого количества СУБД, включая MariaDB, MySQL, Oracle,IBMDB2, PostgreSQL, SQLite и Informix Dynamic Server

Формирование, отправка и получение почтовых сообщений по протоколам mbox, Maildir, POP3 и IMAP4

Гибкая система кеширования с поддержкой различных типов - в памяти или в файловой системе(Flexible caching sub-system with support for many types of backends, such asmemory or a file system)

Глава 1. Работа с компонентами в ZendFramework

Для разработки приложение на РНР типичным является внедрение РНР-кода в один или несколько HTML-документов с помощью специальных разделителей. Это упрощает создание динамических веб-страниц, содержащих конструкции языков программирования, такие как переменные или вызовы функций; достаточно просто изменить значения переменных, внедренных в HTML-код, и содержимое страницы соответствующим образом изменится.

Приложения ZendFramework создаются в соответствии с общепринятым набором принципов, способствующих повторному использованию кода, простоте его сопровождения и масштабируемости. Одной из основ этого подхода является паттерн проектирования Модель-Представление-Контроллер (Model-View- Controller, MVC), отделяющий бизнес-логику приложения от пользовательского интерфейса и моделей данных и разрешающий работать с ними по отдельности. Паттерн MVC также способствует эффективной организации и разделению обязанностей приложения и позволяет независимо тестировать различные компоненты.

1.1 Структура директорий ZendFramework

На данный момент в ZendFramework жестко не стандартизирована структура директорий приложения, но в официальной документации рекомендуется использовать общепринятую схему. Эта схема основана на том, что пользователь, как предполагается, имеет полный доступ к конфигурированию сервера Apache. Для начала надо создать директорию Zend-проекта в корневом каталоге вашего тестового веб-сайта(zf-tutorial). Это будет означать, что URL этой директории примет вид http://localhost/zf-tutorial (адрес может варьироваться, в зависимости от настроек сервера). После этого нужно дополнительно создать следующую структуру каталогов для хранения файлов веб-приложения:

zf-tutorial/ /application /controllers /models /views /filters /helpers /scripts /library /public /images /scripts /styles

Как можно понять из названий, здесь выделены специальные директории для файлов моделей, видов и контроллеров приложения. Графика, скрипты и CSS файлы будут храниться в отдельных подкаталогах, расположенных внутри открытой для публичного доступа директории public.

1.2 Модели

Каждое приложение, будь то простой запрос имени пользователя и пароля или многовалютная корзина в интернет-магазине, управляется данными. В паттерне MVC этот «слой данных» представлен одной или несколькими моделями, которые предоставляют функции для получения, сохранения, удаления и иных действий с данными приложения. Слой данных безразличен к способу их вывода: он имеет Дело только с самими данными и не имеет никакого отношения к тому, как эти данные будут представлены пользователю. В сущности, он предоставляет логически независимый интерфейс для манипулирования данными приложения.

Чтобы проиллюстрировать это, рассмотрим простое веб-приложение, которое позволяет пользователям отправлять классифицированные объявления, связанные с подержанными автомобилями. В соответствии с паттерном MVC данные этого приложения -- списки автомобилей -- можно представить моделью Listing, которая предоставляет методы для взаимодействия с лежащими в ее основе данными. Эта Модель не связана с визуальным отображением списков; напротив, она содержит Функции, необходимые для доступа и модификации отдельных списков и их атрибутов в хранилище данных.

<?php

class ListingModel {

public function constructO

{

// конструктор

}

public function read(Sid)

{

// код для получения единственного списка по его индефикатору

public function find(Scriteria)

{

// код для получения списков,соответствующих заданным критериям

public function save() {

// код для вставки или обновления списка

}

public function delete() {

// код для удаления списка

}

}

?>

Если данные приложения хранятся в базе данных, например MySQL, SQLite или PostgreSQL, модели могут использовать лежащий в ее основе слой абстракции для решения задач по управлению подключениями к базе и выполнению SQL- запросов. Zend Framework содержит слой абстракции для баз данных, Zend_Db, который предоставляет единообразный интерфейс к множеству различных СУБД (систем управления безами денных), а модели в Zend Framework обычно описываются с использованием паттерна Data Mapper. Также в приложение Zend Framework можно легко интегрировать сторонние модели, например, созданные с помощью средств объектно-реляционного отображения (Object-Relational Mapping, ORM), таких как Doctrine и Propel.

1.3 Представления

Тогда как модели занимаются только доступом и модификацией необработанных данных приложения, представления отвечают за то, как эти данные будут представлены пользователю. Представления можно считать слоем пользовательского интерфейса, ответственным за отображение данных, но неспособным получать к ним непосредственный доступ или изменять их. Представления могут получать данные от пользователя, но их «обязанности», опять же, ограничены созданием внешнего вида и поведения формы ввода; они не занимаются обработкой, очисткой или валидацией входных данных.

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

Ниже приведен пример представления, предназначенного для отображения последних списков:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"

"http://www.w3.org/TR/xhtmll/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8'7>

<base href='7" />

</head>

<body>

<div id="header">

<div id=,,logo">

<img src^Vimages/logo.gif" />

</div>

</div>

<div id="content>

<hl>Recent listings</hl>

<?php foreach ($this->listings as $1): ?>

<div class="listing">

<h3 class="listing_title">

<a href="/listing/view/<?php echo $l->id; ?>">

<?php echo $1->title: ?>

</a>

</h3>

<span class="listing_content">

<?php echo $l->content; ?>

</span>

</div>

<?php endforeach; ?>

</div>

</body>

</html>

Как показано в этом примере, представления описываются в виде сценариев РНР, содержащих HTML-код или разметку, необходимую для правильного формирования вывода и отображения его пользователю. Эти сценарии могут также содержать переменные-заполнители для динамических данных; значения этих заполнителей устанавливаются соответствующим контроллером и вставляются в представление при его формировании. В Zend Framework сценарии представления формируются компонентом Zend_View, который кроме этого предоставляет вспомогательные функции для экранирования вывода и набор «вспомогательных классов» для решения распространенных задач, связанных с представлением, таких как навигация, создание мета-тегов и генерация ссылок. Также довольно просто интегрировать в приложение Zend Framework сторонние механизмы шаблонизации, например Smarty или Savant, расширив абстрактный класс Zend_View_Interface.

1.4 Контроллеры

Контроллеры -- это связующее звено между моделями и представлениями. С помощью моделей они вносят изменения в данные приложений, а затем вызывают представления для отображения результатов для пользователя. Контроллер может быть связан с несколькими представлениями и может использовать разные представления в зависимости от результата, который требуется отобразить в любой конкретный момент времени. Таким образом, контроллеры можно считать слоем обработки, реагирующим на действия пользователей и инициирующим изменения в состоянии приложения и отображение нового состояния для пользователя.

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

Ниже приведен пример контроллера, который объединяет приведенные выше модель и представление:

<?php

class ListingController {

function indexActionO {

// код для инициализации модели

// и получения данных

$listing = new ListingModel();

Smatches = $listing->find(

array(

`date' => 4-10 days'.

`status' => 'published'

)

):

// код для инициализации представления

// и заполнения его данными, полученными от модели

$view = new ListingView();

$view->listings = $matches;

echo $view->render('recent.php');

}

}

?>

Как показано в этом примере, контроллер является посредником, вызывающим методы модели для проведения операций с данными приложения и использующим представления для отображения результатов этих операций. В Zend Framework контроллеры являются наследниками класса Zend_Controller_Action и содержат методы, иначе называемые действиями, имеющие код, необходимый для взаимодействия с моделями и представлениями. Существует также «сверхконтроллер», fwnt-контроллер, ответственный за перехват запросов пользователя и вызов подходящих контроллеров и методов-действий для их обслуживания (более подробно об этом рассказывается в следующем разделе).

Помимо трех ключевых компонентов, описанных выше, Zend Framework также вносит в процесс разработки приложения некоторые дополнительные идеи. Они описаны в следующих разделах.

1.5 Модули

По умолчанию все модели, контроллеры, действия и представления находятся в модуле default. Однако зачастую у вас может возникать желание сгруппировать модели, представления и контроллеры в неких «коробках», разделив их по различным функциональным областям вашего приложения. Это можно сделать с помощью модулей. Например, если ваше приложение содержит функции поиска, управления профилями пользователей и новости, вы можете создать отдельные модули search, profile и news и поместить в каждый из них соответствующие модели, представления и контроллеры.

Модули представляют собой удобный способ организации кода приложения или способ создания сторонних компонентов приложения, которые легко добавляются к существующей установке. Стандартный маршрутизатор Zend Framework полностью поддерживает работу с модулями, позволяя приступить к их использованию в приложении без написания собственного кода. Каждый модуль (за исключением модуля default) имеет свое пространство имен, это предотвращает возникновение коллизий между объектами или переменными.

1.6 Маршруты

Маршруты -- это связующее звено между пользовательскими запросами и выполняемыми действиями. Когда пользователь делает запрос к приложению по определенному URL, front-контроллер перехватывает этот запрос и, основываясь на шаблоне URL, принимает решение о том, какие контроллер и действие должны быть вызваны для обработки запроса. Этот процесс маршрутизации запросов контроллерам является ключевой частью потока выполнения приложения и обладает большими возможностями для настройки. Для сопоставления шаблона URL маршруты используют регулярные выражения и могут быть описаны с использованием синтаксиса XML- или INI-файлов.

По умолчанию ZendFramework содержит несколько стандартных маршрутов, подходящих для приложений малой или средней сложности. Эти стандартные маршруты предполагают, что URL в приложении имеют вид /модуль/контроллер/ действие, и соответствующим образом перенаправляют пользовательские запросы. Например, запрос URL http://application/auto/listing/index может автоматически сопоставляться действию ListingController::IndexAction в модуле auto. Имена контроллера и действия подчиняются определенным правилам использования регистра букв и именования.

Если стандартные маршруты являются слишком ограниченными или недостаточно гибкими для вашего приложения, ZendFramework разрешает использование маршрутов, определенных пользователем. Они поддерживают (помимо всего прочего) необязательные и обязательные параметры, значения по умолчанию и объединение нескольких маршрутов в цепочки, а также позволяют подробно настроить маршрутизацию вашего приложения таким образом, что адреса URL не требуют отражения внутренней системы контроллеров, действий и модулей.

1.7 Макеты

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

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

1.8 Взаимодействие между компонентами

Рисунок 2

На рисунке показано движение запроса в типичном приложении ZendFramework.

Поскольку перед контроллером ставится задача перехвата запросов клиента и направления их подходящему целевому объекту для формирования ответа, front- контроллер играет ключевую роль в движении запроса через приложение.

1.Когда приходит запрос, файл .htaccess веб-сервера автоматически приводит его к стандартному формату и передает сценарию index.php. Этот сценарий подготавливает окружение приложения, читает его конфигурационный файл и создает экземпляр front-контроллера.

2.Front-контроллер анализирует запрос и определяет основные компоненты URL. Затем он направляет запрос подходящему контроллеру. Для выполнения этой маршрутизации front-контроллер проверяет как стандартные, так и пользовательские маршруты и задействует методы сопоставления по шаблону для выбора цели запроса.

3.Если найдено совпадение, front-контроллер передает управление соответствующему контроллеру. Будучи вызванным, действие вносит изменения в состояние приложения, используя одну или несколько моделей. Оно также выбирает отображаемое представление и устанавливает в нем необходимые параметры. После завершения действия выбранное представление формирует страницу с его выводом, в случае необходимости помещая вывод в макет. После чего этот вывод возвращается клиенту

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

Как говорилось ранее, подсистема маршрутизации автоматически сопоставляет URL в формате /модуль/контроллер/действие соответствующим модулю, контроллеру и действию. Например, для доступа к действию ListingController :: SaveAction в модуле auto вам необходимо будет запросить URL http://application/auto/listing/save. Аналогично, для доступа к действию NewsController::editAction в модуле content вам потребуется запросить URL http://application/content/news/edit.

Глава 2. Работа с формами в ZendFramework

Чтобы показать, как ZendFramework может помочь вам с созданием форм, будет достаточно небольшого, но наглядного примера написания сценария для обработки форм с помощью стандартной HTML - разметки:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN” “http://www.w3.org/TR/xhtmll/DTD/xhtmn-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

<head>

</head>

<body>

<h2>Create Item</h2>

<?php

if (!isset($_POST[.submit'])) {

// запрос POST не отправлялся, отображаем форму ?>

<form method="post" action="/item/create">

<table>

<tr>

<td>Item name:</td>

<td><input type="text” name="name" size="30" /></td>

</tr>

<tr>

<td>Item quantity:</td>

<td><input type="text" name="qty" size="3" /></td>

</tr>

<tr>

<td colspan="2">

<input type="submit" name="submit" value="Submit" />

</td>

</tr>

</table>

</form>

<?php } else {

// отправлен запрос POST, проверяем входные данные

if (trim($_P0ST['name']) == ”) { dieC ERROR: Missing value - Item name `):

}

if (trim($_P0ST[`qty']) -- ") { dieC ERROR: Missing value - Item quantity -);

if ($_P0ST[`qty'] <= 0) { dieC ERROR: Invalid value - Item quantity -):

// обрабатываем входные данные

// например сохраняем их в базу данных *

// попытка подключения try {

$pdo = new PDO(`mysql:dbname=test;host=loca1host', 'user', `pass'):

// создаем и выполняем запрос

INSERT $name = $pdo->quote($_POST[`name']):

$qty = $pdo->quote($_POST[`qty']);

$sql = "INSERT INTO shoppinglist (name, qty) VALUES ($name. $qty)":

$pdo->exec($sql) or die("ERROR: " . implode(":". $pdo->errorInfo()));

// закрываем подключение

unset($pdo):

// отображаем сообщение об успешной операции echo `Thank you for your submission':

}

catch (Exception $e) { die("ERROR: " . $e->getMessage()):

}

}

?>

</body>

</html>

Этот сценарий разбит на две части условным оператором, проверяющим значение переменной $_POST, чтобы определить, была ли форма отправлена. Первая его половина отображает форму ввода с двумя полями и кнопкой отправки, а вторая проверяет правильность формата введенных данных, затем экранирует их и добавляет в базу данных.

Внешний вид формы показан на рисунке 2.

Рисунок 3 - Форма, созданная с помощью стандартной HTML-разметки

Хотя приведенный сценарий и весь подход в целом работают на практике, невозможно отрицать тот факт, что у них сущствует ряд проблем:

1.Один и тот же файл сценария содержит как элементы интерфейса, описанные на HTML, так и бизнес-логику на РНР. Как говорилось в предыдущей главе, такое соседство не только неряшливо выглядит, но и осложняет сопровождение. Помимо этого, становится сложнее поддерживать согласованность форм, так как код, необходимый для создания каждой из них, может подвергаться существенной модификации.

2.Каждый раз, когда в первой половине сценария вы добавляете на форму новое поле, вам также необходимо добавить соответствующий набор проверок и сообщений об ошибках в его вторую половину. Это надоедающее и часто повторяющееся действие; взять хотя бы тот факт, что две первые проверки из предыдущего примера делают, в сущности, одно и то же.

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

В состав Zend Framework входит набор компонентов с общим названием Zend_ Form, которые решают перечисленные проблемы. В целях демонстрации рассмотрим следующий пример, где Zend_Form используется, чтобы создать сценарий, эквивалентный предыдущему:

<?php

class Form_Item_Create extends Zend_Form {

public function init()

{

// инициализируем форму $this->setAction('/item/create')

->setMethod(`post');

// создаем текстовое поле для ввода имени Sname = new Zend_Form_Element_Text(`name'):

$name->setLabel(`Item name:')

->setOptions(array(`size' => `35'))

->setRequired(true)

->addValidator(`NotEmpty'. true)

->addValidator(`Alpha'. true)

->addFilter(`HtmlEntities')

->addFilter(.`StringTrim');

// создаем текстовое поле для ввода количества $qty = new Zend__Form_Element_Text(`qty'):

$qty->setLabel(`Item quantity:'):

'$qty->setOptions(array(`size' => `4'))

->setRequired(true)

* ->addValidator(`NotEmpty'. true)

->addValidator(`Int'. true)

->addFilter(`HtmlEntities')

->addFi1 ter(`StringTrim');

// создаем кнопку для отправки

^submit = new Zend Form Element Submit(`submit');

$submit->setLabel('Submit')

->setOptions(array('class' => 'submit')):

// добавляем к форме элементы $thi s->addElement($name)

->addElement($qty)

->addE1ement($submi t):

}

}

class ExampleControl1er extends Zend_Controller_Action {

public function formActionO

{

Sform = new Form_Item_Create;

$this->view->form = Sform; if (Sthis->getRequest()->isPostO) { if (Sform->isValid($this->getRequest()->getPost())) {

Svalues = $form->getValues();

$pdo = new PD0(`mysql;dbname=test;host=localhost'. `user', `pass'); $sql = sprintf("INSERT INTO shoppinglist (name, qty)

VALUES (`Јs\ `Јd')\ $values[`name']. $values[`qty']); $pdo->exec($sql);

$thi s->_helper->getHelper(`FIashMessenger')

->addMessage(`Спасибо');

$this->_redirect(`/index/success');

}

}

}

На рисунке 3 показана форма, созданная с использованием компонента Zend.Form.

Рисунок 4 - Форма, созданная с использованием компонента Zend.Form

В коде, создающем приведенную на рис. 3.2 форму, вы наверняка заметили три особенности:

1.В сценарии нет ни одной строчки HTML-кода. Форма и ее элементы представлены в виде объектов РНР и настраиваются с помощью методов этих объектов. Такой подход обеспечивает согласованность и создает веб-форму, соответствующую стандартам.

2.Для распространенных задач валидации и очистки ввода доступны встроенные валидаторы и фильтры. Они уменьшают количество выполняемой работы, помогают создавать более простой в сопровождении код и избегать повторений. Кроме того, для соответствия нестандартным требованиям валидаторы можно комбинировать и расширять.

3.Валидаторы указываются одновременно с полями формы. Это позволяет форме «знать», какие данные поддерживаются каждым полем, и легко определять источник ошибок ввода. Для более строгой валидации одному полю можно назначить несколько валидаторов.

Отсюда вытекает, что Zend_Form предоставляет удобное, простое в сопровождении и расширяемое решение для создания форм ввода и валидации данных.

Глава 3. Работа с моделями в ZendFramework

Введенные на форме данные не растворяются в пустоте; они должны куда-то попадать. Обычно под «куда-то» подразумевается база данных, например MySQL, SQLite или PostgreSQL, поэтому добавление поддержки базы данных в приложение становится основной задачей разработчика.

Однако база данных -- лишь часть: для взаимодействия с ней вам также потребуются модели. Они логически не зависят от представлений и контролеров и служат в качестве слоя данных приложения, предоставляя все необходимые Функции для манипуляций с его данными. ZendFramework упрощает написание модулелей, соответствующих требованиям вашего приложения.

3.1 Модели

Модели представляют слой данных, ответственный как за предоставление канала, через который можно получить доступ к данным, так и за поддержание и соблюдение любых бизнес-правил связанных с этими данными. Например, при создании системы учета книг для онлайн-библиотеки вы можете использовать модель Transaction, которая будет не только записывать информацию о взятых и возвращенных книгах, но и содержать правила, запрещающие читателю иметь на руках более пяти книг единовременно или автоматически рассчитывающие плату за просроченный возврат и списывающие ее со счета соответствующего пользователя. Аналогично, при создании приложения для продажи авиабилетов вы можете использовать модель Ticket, которая будет не только сохранять и получать записи о приобретении билетов, но и автоматически увеличивать или уменьшать стоимость билета в зависимости от загруженности конкретного рейса.

Пример простой модели:

<?php

// модель для обработки данных о клиентах class MemberModel {

protected $db;

public Sid;

public Sname;

public Sage;

public Stype;

private Srate;

// конструктор

// инициализируем подключение к базе данных

public function_construct()

{

Sthis->db = new PD0('mysql;dbname=db;host=localhost', 'user', 'pass');

Sthis->db->setAttribute(PDO::ATTR_ERRMODE, PDO;:ERRMODE_EXCEPTION);

}

// получаем запись о клиенте по его идентификатору

public function fetch(Sid)

{

Sid = $this->db->quote(Sthis->id);

Srs = Sthis->db->query("SELECT * FROM member WHERE id = Sid");

return $rs->fetchAll(PDO::FETCH_ASSOC);

}

// получаем записи обо всех клиентах

public function fetchAll()

{

$rs = $this->db->query('SELECT * FROM member");

return $rs->fetchAll(PDO::FETCH_ASSOC);

}

// добавляем новую запись о клиенте

public function save()

// фильтруем входные данные

{

$f = array();

$f['name'] = htmlentities($this->name):

$f['age'] = htmlentities($this->age);

$f['type'] = htmlentities($this->type):

// проверяем возраст

if ($f['age'] < 18) { throw new Exception('Member under 18);

}

// автоматически вычисляем скидку в зависимости от статуса клиента

switch ($fС * type']) {

case 'silver';

$f['rate'] = 0; break;

case 'gold';

$f['rate'] = 0.10; break;

case 'platinum';

$f['rate'] = 0.25; break;

}

$this->db->exec(

'INSERT INTO member (Name, Age. Type. DiscountRate) VALUESC . $this->db->quote($f['name']) . '. '

$this->db->quote($f['age']) . '. '

$this->db->quote($f['type']) . '. '

$this->db->quote($f['rate']) . ')'

):

return $this->db->lastlnsertld();

}

}

?>

Как видно, для взаимодействия с базой данных MySQL эта модель использует абстракции РНР -- PDO. Она предоставляет несколько методов для полудня записей из базы данных и сохранения их в базу. В ней также содержатся некоторые бизнес-правила (автоматический подсчет скидки, основанный на статусе клиента) и некоторые правила валидации ввода (проверка того, что клиент не моложе 18 лет). Как и у всех хороших моделей, ее начальной и конечной целью являются данные; модель не содержит сведений о том, как эти данные форматируются и отображаются.

Пример возможного использования этой модели в приложении:

<?php

class Sandbox_ExampleController extends Zend_Controller_Action {

public function saveActionO {

if ($this->getRequest()->isPost()) { if ($form->isValid($this->getRequest()->getPost())) {

$model = new MemberModel;

$model->name = $form->getValue('name');

$model->age = $form->getValue('age');

$model->type = $form->getValue('type'):

Sid = $model->save();

$this->view->message = "Record saved with ID: Sid";

}

}

}

}

директория фреймворк паттерн

3.2 Паттерны для моделей

Для работы с моделями существуют два часто используемых паттерна: DataMapper и ActiveRecord. В предыдущем примере продемонстрирован паттерн ActiveRecord, в котором класс модели непосредственно соответствует таблице в базе данных и предоставляет для работы с записями этой таблицы такие методы, как save(), update() и delete(). Очевидно, что в этом паттерне модели и соответствующие им таблицы базы данных тесно связаны друг с другом, и внесение изменений в одну из них требует внесения изменений в другую.

Паттерн DataMapper несколько отличается от ActiveRecord, так как не требует наличия отношения 1:1 между классом модели и соответствующей таблицей базы данных. Вместо этого в нем используется промежуточный слой (mapper -- от отображающий класс), с помощью которого решается задача отображения данных из класса модели на поля таблицы. В этом случае именно отображающий класс предоставляет методы save(), update() и fetch() и осуществляет преобразования» необходимые для корректного отображения элементов класса на поля в базах данных. Данный паттерн обладает большей гибкостью и большим разнообразием возможных конфигураций, нежели ActiveRecord; кроме этого, отделение данных от их хранилища приводит к созданию более удобных для восприятия простых сопровождений моделей. Однако реализовать паттерн DataMapper сложнее чем ActiveRecord.

Как правильно выбрать паттерн? Простого ответа на этот вопрос не существует потому что он равносилен вопросу о том, какой сорт мороженого лучше. Паттерн ActiveRecord, по определению, предполагает, что для хранения данных вы используете базу данных, а модели, основанные на этом паттерне, тесно связаны с ее структурой. Такой сценарий подойдет для маленьких проектов или для проектов, в которых основная функциональность по большей части соответствует стандартному набору команд SELECT, INSERT, UPDATE и DELETE. Паттерн DataMapper позволяет явно разделить бизнес-правила уровня приложения и хранилище данных, и именно сама модель, а не лежащая в основе база данных, используется для определения данных. Как следствие, вы не ограничены только лишь базой данных; класс отображения может столь же легко отображать данные на другие типы хранилищ, такие как обычные файлы, XML или LDAP. Этот паттерн подойдет для проектов со сложными структурами данных и/или пользовательскими форматами для их хранения или же для проектов, основная функциональность которых требует более сложных взаимодействий между сущностями приложения.

3.3 Границы модели

Зачастую сложно провести черту между тем, что должно находиться в модели, и тем, что должно находиться в контроллере. Например, для описанного ранее примера с банковскими операциями можно утверждать, что валидация, относящаяся к суммам и местоположениям, должна осуществляться в контроллере, а не в модели. Однако в целом сообщество разработчиков приняло подход «толстая модель, тонкий контроллер», рекомендованный различными программистами, включая Мартина Фоулера (Martin Fowler), Джеймиса Бака (Jamis Buck) и Криса Хартджеса (Chris Hartjes). Этот подход предлагает по возможности размещать бизнес-логику в моделях, а не в контроллерах, и обладает рядом преимуществ:

1.Инкапсулируя ключевые бизнес-правила в объектах и методах объектов, пригодных для многократного использования, «толстые» модели уменьшают дублирование и помогают разработчикам придерживаться принципа «Не повторяй самого себя» (Don't Repeat Yourself, DRY). Впоследствии для согласованного применения этих правил в приложении можно использовать цепочки наследования. Кроме того, определение моделей с использованием принципов ООП дает возможность наращивать функциональность базовых моделей по мере необходимости, а также разграничивать открытые и закрытые атрибуты моделей в более крупных приложениях.

2.Самодостаточные «толстые» модели, инкапсулирующие все бизнес-правила, необходимые для их корректной работы, являются более переносимыми, чем «тонкие» модели, которые полагаются на то, что за соблюдение бизнес-правил будут отвечать контроллеры приложения. Поскольку основная часть бизнес- логики приложения находится в модели, а не в контроллере, упрощается, например, переход на другой фреймворк, так как можно просто переместить модель в новую систему, и она будет работать как обычно, не требуя существенной Модификации.

3.Когда большая часть тяжелой работы выполняется «толстыми» моделями, Контроллеры обычно содержат лишь несколько строк узкоспециализированного кода. Это упрощает их чтение и понимание, а также повышает общую производительность (поскольку контроллеры обычно вызываются чаще, чем модели). Помимо этого, упрощается сопровождение кода: например, если вам потребуется изменить бизнес-правила для определенной сущности в приложении, необходимо будет обновить только модель для этой сущности, а не все контроллеры, которые ее используют.

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

Важно отметить, что в состав Zend Framework не входит компонент Zend_Model или набор стандартных моделей, которые вы могли бы «присоединить» к своему приложению: придется создавать собственные модели. Zend Framework включает в себя несколько инструментов, способных помочь в решении этой задачи: например, слой абстракции баз данных Zend_Db_Adapter и интерфейс для операций с таблицами Zend_Db_Table.

Заключение

В отличии от других языков программирования PHP не навязывает общий стандарт написания кода. В результате стиль кода в различных приложениях на PHP существенно различается у разных разработчиков, что затрудняет поддержание согласованности проекта. Относительный недостаток строгости в PHP приводит к появлению некачественного кода, что делает его уязвимым. ZendFramework ,напротив, объединяет в себе приёмы программирования, считающимся лучшим на сегодняшний день, представляет стандартную схему размещения фалов в файловой системе и обеспечивает встроенную поддержку для решения распространённых задач, возникающих при разработке приложений, таких как валидация и очистка входных данных. Следовательно, использование этого фреймворка как основы для создания проекта на PHP автоматически приводит к созданию более качественного кода и приложения, более устойчивого к проблемам безопасности.

Размещено на stud.wiki




Подобные документы

  • Обзор существующих технологий разработки программного обеспечения. Описание платформы NET Framework. Принцип работы платформы: компиляция исходного кода; процесс загрузки и исполнения кода; IL-код и верификация. Новые возможности платформы NET Framework.

    реферат [30,7 K], добавлен 01.03.2011

  • Розробка гри "Арканоід", з можливістю гри, як одного та і двох гравців одночасно на одному гральному полі, за допомогою Visual Studio 2008 з XNA Framework. Аналіз предметної галузі. Опис концептуальної моделі. Реалізація взаємодії між гравцем та системою.

    курсовая работа [5,5 M], добавлен 21.01.2010

  • Характеристика и состав Microsoft Solution Framework. Модель команды, её характеристики. Цели качества команды проекта. Модель процессов, её содержание. Принципы управления рисками. Утверждение целей и границ, плана проекта. Модель приложений MSF.

    презентация [752,5 K], добавлен 10.05.2013

  • Разработка программного приложения по учету договоров с поставщиками и клиентами для строительного предприятия. Особенности использования технологии Net Framework 2.0 в алгоритмически-логическом аспекте на основе реляционной базы, управляемой языком SQL.

    курсовая работа [3,0 M], добавлен 25.06.2011

  • Разработка клиентского приложения для информационной системы "Работа торгового склада" с помощью языка объектно-ориентированного программирования Delphi 6 и технологии InterBase Express. Описание реляционной модели данных и этапы ее проектирования.

    курсовая работа [1,0 M], добавлен 19.03.2009

  • Изучение сведений o плaтфopме .NET Framework. Характеристика метoдов дocтупa к бaзaм дaнныx. Рaзpaбoтка пpилoжения "Пocтaвкa и pеaлизaция пpoгpaммнoгo oбеcпечения", coдеpжaщего бaзу дaнныx и pacкpывaющего вcе acпекты paзpaбoтки бaзы дaнныx нa языке C+.

    курсовая работа [1,8 M], добавлен 12.12.2011

  • Обзор криптографических классов библиотеки Framework Class Libr: классы алгоритмов симметричного и асимметричного шифрования, хеширования. Классы-форматеры и деформатеры. Классы для формирования и проверки цифровой подписи. Примеры применения классов.

    курсовая работа [30,0 K], добавлен 27.12.2011

  • Использование объектно-ориентированного программирования - хорошее решение при разработке крупных программных проектов. Объект и класс как основа объектно-ориентированного языка. Понятие объектно-ориентированных языков. Языки и программное окружение.

    контрольная работа [60,1 K], добавлен 17.01.2011

  • Рассмотрение теоретических аспектов создания баз данных с применением системы объектно-ориентированного программирования Delphi. Ознакомление с компонентами доступа. Разработка базы данных "Библиотека". Описание основ интерфейса созданной программы.

    курсовая работа [1004,9 K], добавлен 26.10.2014

  • Автоформат при вводе. Работа со смарт-тегами. Работа с компонентами среды разработки Borland C++, их свойства, методы и правила их использования. Страница событий инспектора объектов. Создание интерфейса, эмулирующего пункт меню Microsoft Office Word.

    курсовая работа [524,5 K], добавлен 09.06.2015