framework.zend.com
Stable релиз 2.0 / 1.12

Построение приложения на базе Zend Framework. Часть 1. Zend_Controller, Zend_Db, Zend_Layout

К комментариям

Обновлено: 07.01.2009
Содержание

Введение

Данная статья является первой частью серии статей под названием "Построение приложения на базе Zend Framework". Каждая часть сопровождается кодом. Ранее эта статья была доступна под названием "Построение простого сайта на базе Zend Framework (с кодом)".

Если вы работаете с Zend Framework 1.8.0 и старше прочтите это.

В тексте затронуты следующие вопросы:

  • Паттерн MVC - на основе Zend_Controller, Zend_View, Zend_Layout и Zend_Db
  • Управление конфигурационными файлами - Zend_Config
  • Работа с базой данных - Zend_Db, Zend_Db_Select, Zend_Db_Table
  • Отделение представления (вида) с помощью системы шаблонов - Zend_View
  • Двухэтапное представление - Zend_Layout
  • Управление маршрутами - Zend_Controller_Router_Rewrite
  • Автоматическая загрузка классов - Zend_Loader
  • Работа с исключениями и обработчик ошибок

Старт

Для получения базовых навыков прочтите статью. Как и в той статье, мы будем располагать php файлы вне document root директории (за исключением точки входа index.php), для обеспечения большей безопасности.

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

Файловая структура Zend Framework
Рис. 1. Файловая структура Zend Framework



А вот так выглядит дерево папок сайта, в нашем случае папка public это document root :

Дерево папок сайта на базе Zend Framework
Рис. 2. Дерево папок сайта



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

Общий алгоритм работы сайта

Для общего понимания я схематически изобразил алгоритм работы сайта.

Алгоритм работы сайта на базе Zend Framework
Рис. 3. Алгоритм работы сайта



С помощью файла .htaccess все запросы к сайту перенаправляются на входную точку - файл index.php лежащий в корне document root.


RewriteEngine on

RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d

RewriteRule ^(.*)$ index.php/$1

Не перенаправляются только запросы на реально существующие файлы.

Рассмотрим код файла index.php


<?php

// Подключаем файл настроек
require '../application/settings/config.php';

// Создаем строку путей
$paths = implode(PATH_SEPARATOR,
array (
$config['path']['library'],
$config['path']['models'],
$config['path']['system']
));

// Пути по которым происходит поиск подключаемых файлов, это папка библиотек, моделей и системных файлов
set_include_path($paths);

// Подключение загрузчика
require 'Bootstrap.php';

// Запуск приложения
$bootstrap = new Bootstrap();
$bootstrap->run($config);

Так как мы не хотим каждый раз указывать полный путь к нужным файлам - задаем set_include_path. Подключаемые файлы это библиотеки Zend, системные классы, а также классы модели. Но не стоит указывать слишком много путей, иначе это может отразиться на производительности. Также старайтесь что бы путь к библиотекам Zend шел первым. index.php запускает $bootstrap->run() - основной метод нашего загрузочного класса Bootstrap.php. Этот класс предназначен для инициализации и настройки окружения. Приведу его код полностью:

     <?php

require 'Zend/Loader.php';

class Bootstrap
{
/**
* Объект конфигурации
*
* @var Zend_Config
*/
private $_config = null;

/**
* Запуск приложения
*
* @var array $config Конфигурация
*/
public function run($config)
{
try {
// Настройка загрузчика
$this->setLoader();

// Настройка конфигурации
$this->setConfig($config);

// Настройка Вида
$this->setView();

// Подключение к базе данных
$this->setDbAdapter();

// Подключение маршрутизации
$router = $this->setRouter();

// Создание объекта front контроллера
$front = Zend_Controller_Front::getInstance();

// Настройка front контроллера, указание базового URL, правил маршрутизации
$front->setBaseUrl($this->_config->url->base)
->throwexceptions(true)
->setRouter($router);

// Запуск приложения, в качестве параметра передаем путь к папке с контроллерами
Zend_Controller_Front::run($this->_config->path->controllers);

}
catch (Exception $e) {
// Перехват исключений
Error::catchException($e);
}
}
/**
* Настройка загрузчика
*/
public function setLoader()
{
// Запуск автозагрузки
Zend_Loader::registerAutoload();
}

/**
* Настройка конфигурации
*
* @param array $config Настройки
*/
public function setConfig($config)
{
$config = new Zend_Config($config);
$this->_config = $config;
Zend_Registry::set('config', $config);
}

/**
* Настройка вида
*/
public function setView()
{
// Инициализация Zend_Layout, настройка пути к макетам, а также имени главного макета.
// Параметр layout указан лишь для примера, по умолчанию имя макета именно "layout"
Zend_Layout::startMvc(array(
'layoutPath' => $this->_config->path->layouts,
'layout' => 'layout',
));

// Получение объекта Zend_Layout
$layout = Zend_Layout::getMvcInstance();

// Инициализация объекта Zend_View
$view = $layout->getView();

// Настройка расширения макетов
$layout->setViewSuffix('tpl');

// Задание базового URL
$view->baseUrl = $this->_config->url->base;

// Задание пути для view части
$view->setBasePath($this->_config->path->views);

// Установка объекта Zend_View
$layout->setView($view);

// Настройка расширения view скриптов с помощью Action помощников
$viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer();
$viewRenderer
->setView($view)
->setViewSuffix('tpl');

Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);
}

/**
* Установка соединения с базой данных и помещение его объекта в реестр.
*/
public function setDbAdapter()
{
// Подключение к БД, так как Zend_Db "понимает" Zend_Config,
// нам достаточно передать специально сформированный объект конфигурации в метод factory
$db = Zend_Db::factory($this->_config->db);

// Задание адаптера по умолчанию для наследников класса Zend_Db_Table_Abstract
Zend_Db_Table_Abstract::setDefaultAdapter($db);
// Занесение объекта соединения c БД в реестр
Zend_Registry::set('db', $db);
}

/**
* Настройка маршрутов
*/
public function setRouter()
{
// Подключение файла правил маршрутизации
require($this->_config->path->system . 'routes.php');
// Если переменная router не является объектом Zend_Controller_Router_Abstract,
// выбрасываем исключение
if (!($router instanceof Zend_Controller_Router_Abstract)) {
throw new Exception('Incorrect config file: routes');
}

return $router;
}
}

Практически каждая строчка откомментирована и уже сейчас вы можете полностью представить себе схему работы.

Хочу отметить, что существует другой вариант настройки окружения для работы сайта - плагины. Вместо класса Bootstrap мы могли бы создать плагин с названием вроде My_Plugin_Initialize и в нем использовать перехватчик routeStartup для настройки окружения. Получился бы такой же результат.

Далее, предположим мы обратились к следующей странице нашего сайта http://ilovezf/pages/1/ В этом случае будет вызван IndexController и его действие PageAction. (Такое поведение происходит потому что я добавил специальное правило в файл маршрутов routes.php, по умолчанию по такому запросу вызовется контроллер PagesController и действие 1, конечно если они существуют)

В контроллере происходит подключение модели и получение данных необходимых запрошенной странице. Затем происходит определение переменных для вида.

Наконец в главный макет application/views/scripts/layout.tpl подставляются нужные нам данные и весь полученный результат отправляется в браузер.

Далее я более подробно остановлюсь на ключевых моментах построения нашего приложения.

Zend_Loader

Этот класс позволяет использовать одну из замечательных возможностей php5 - автоматическую загрузку объектов, иначе называемую autoload. Если вы пишите ООП приложение то у вас, должно быть, не один десяток различных классов, и на некоторых страницах нужно подключить 5-10 классов. Если таких страниц много, то это очень неприятно. С Zend_Loader вам достаточно всего лишь указать название класса в нужном формате, и он сам произведет подключение.

То есть, в коде например пишем $news = new Text_News_Home();

Символ "_" используется как разделитель, Zend_Loader будет пытаться найти указанный класс по адресу Text/News/Home.php. (В рассматриваемом примере в index.php я указал относительно каких директорий будет происходить поиск)

Для автоматической загрузки можно использовать метод Zend_Loader::loadClass() или же выполнять Zend_Loader::registerAutoload(); что бы не писать каждый раз Zend_Loader::loadClass(). Правда registerAutoload() требует наличие модуля spl_autoload. С другими подходами к автозагрузке классов вы можете ознакомиться в статье. К сожалению, такая гибкость в подгрузке классов идет в ущерб производительности, если вопрос производительности стоит для вас очень остро, рекомендую ознакомится с официальным приложением к мануалу.

Zend_Registry

Класс реализует паттерн singleton и таким образом позволяет нам обращаться к нужным объектам из любого места кода. Это альтернатива использованию глобальных переменных. Класс оперирует реестром, в который заносятся объекты. Ключевые методы класса это get и set, которые заносят и получают объекты в реестр соответственно. В нашей статье в реестр заносятся объекты соединения с БД и объект конфигурации. Также важен метод isRegistery проверяющий существование объекта в реестре.

Zend_Config

Класс позволяет в ООП стиле работать с конфигурационными файлами. Поддерживаются конфигурационные файлы различного формата: php-массив, ini - файл, xml - файл. Для рассматриваемого примера я выбрал самый простой вариант - хранить настройки в php массиве. Вы можете использовать любой. В объекте Zend_Config все данные представлены в виде ассоциативного массива. Например таким образом: $config->path->system получаем значения физического пути папки с системными файлами.

Например вот так может выглядеть ваш конфигурационный файл:


<?php
$config = array (
// Настройки соединения с БД
'db' => array (
'adapter' => 'PDO_MYSQL',
'params' => array(
'host' => 'localhost',
'username' => 'root',
'password' => 'xxxx',
'dbname' => 'ilovezf',
'driver_options'=> array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES UTF8'),
'profiler' => false,
),
),
);

Управление маршрутами Zend_Controller_Router_Rewrite

Маршрутизация - это процесс принятия URI (той части URI, которая идет после базового URL) и ее разложения на части для определения того, какой контроллер и какое действие этого контроллера должны получить запрос и выполниться. Другими словами процесс маршрутизации дает нам возможность сопоставить адрес запрошенной страницы с конкретными контроллерами и действиями в нашем коде. С помощью Zend_Controller_Router_Rewrite можно задавать различные правила маршрутизации.


<?php

$router = new Zend_Controller_Router_Rewrite();

$router->addRoute('articles',
new Zend_Controller_Router_Route('articles/:articleId',
array('controller' => 'articles', 'action' => 'view'))
);

$router->addRoute('pages',
new Zend_Controller_Router_Route('pages/:pageId',
array('controller' => 'index', 'action' => 'page'))
);

Благодаря этим правилам мы добиваемся, например, того, что по запросу http://ilovezf/articles/1/ будет вызван контроллер articlesController и действие viewAction, кроме того, значение идентификатора статьи (в указанном запросе это 1) будет доступно по параметру articleId. Кроме Zend_Controller_Router_Route который используется для динамических маршрутов, есть еще Zend_Controller_Router_Route_Static для постоянных, неизменных маршрутов, например для URL типа http://ilovezf/exit/. Также существует Zend_Controller_Router_Route_Regex основанный на регулярных выражениях, это самый гибкий способ определения маршрутов.

Front контроллер

Zend_Controller_Front реализует паттерн Front Controller, используемый в приложениях MVC. Его назначение состоит в инициализации окружения запроса, прокладывании маршрута приходящего запроса и последующем запуске выявленных действий. Он агрегирует все ответы и возвращает их по завершении процесса. Другими этот класс выполняет роль некоторого директора управляющего всеми процессами приложения:

     // Создание объекта front контроллера 
$front = Zend_Controller_Front::getInstance();

// Настройка front контроллера, указание базового URL, правил маршрутизации
$front->setBaseUrl($this->_config->url->base)
->throwexceptions(true)
->setRouter($router);

// Запуск приложения, в качестве параметра передаем путь к папке с контроллерами
Zend_Controller_Front::run($this->_config->path->controllers);

Работа с исключениями и обработчик ошибок

Zend Framework предлагает несколько вариантов работы с исключениями. Во первых это плагин Zend_Controller_Plugins_ErrorHandler, он дает возможность перехватывать исключения вызванные отсутствием контроллера или действия, кроме того он перехватывает исключения выброшенные в контроллерах. Никакие другие исключения, например исключения маршрутизации, или исключения выброшенные в плагинах он не перехватывает. Этот плагин хорош именно для работы с ошибками типа 404, он позволяет в рамках общей структуры макетов отобразить страницу 404 с необходимыми сообщениями. За плагин отвечает контроллер ErrorController и действие errorAction.

Для того же что бы все таки обрабатывать остальные ошибки в рассматриваемом примере используется еще один обработчик ошибок /application/system/Error.php.


<?php

class Error
{

/**
* Управление ошибками
*
* @param exception $exception Перехватываемое исключение
*/
public static function catchException(Exception $exception)
{

// Получение текста ошибки
$message = $exception->getMessage();
// Получение трейса ошибки как строки
$trace = $exception->getTraceAsString();
$str = 'ERROR: ' . $message . "\n" . $trace;

$config = Zend_Registry::get('config');

// Если включен режим отладки отображаем сообщение о ошибке на экран
if($config->debug->on) {
Zend_Debug::dump($str);
}
// Иначе выводим сообщение об ошибке
else {
// Здесь может происходить логирование ошибки, уведомление вебмастера и т д
die('System error! Please try later');
}
}
}

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

Для того что бы все ошибки, включая ошибки не найденных контроллеров и действий, перехватывать своим обработчиком, необходимо при настройке front контроллера выполнить $front->throwexceptions(true).

Работа с контроллером

Контроллер является связующим звеном между видом и моделью. Основная задача контроллера это проверить данные что пришли от пользователя, выполнить те или иные действия с данными, используя методы модели, и наконец, определить переменные для вида. Для иллюстрации привожу откоментированный код контроллера ArticlesController

      <?php

class ArticlesController extends Zend_Controller_Action
{
/**
* Список статей
*/
public function indexAction()
{
$modelArticles = new Articles();
$articles = $modelArticles->getArticles();
$this->view->articles = $articles;
}

/**
* Выбранная статья
*/
public function viewAction()
{
// Получение параметра пришедшего от пользователя
$articleId = $this->_getParam('articleId');

// Создание объекта модели, благодаря autoload нам нет необходимости подключать класс через require
$modelArticles = new Articles();

// Выполнения метода модели по получению информации о статье
$article = $modelArticles->getArticles($articleId);

// Определение переменных для вида
$this->view->article = $article;
}
}

Работа с моделью

Работа с моделью практически не освещена в мануале, в файловой структуре предполагается папка models но не дается конкретных рекомендаций по ее использованию. И это не спроста, на самом деле отвечать за реализацию этой части MVC должен сам разработчик. Я рассматриваю модель как набор классов сохраняющих состояние системы и оперирующих с данными, это может быть получение данных, изменения данных, различные манипуляции и вставка данных в базу данных или другое хранилище. Я не допускаю составления и выполнения sql-запросов в классах контроллеров. Такие модели называются толстыми. О толстых моделях и худых контроллерах вы можете прочесть здесь. В рамках текущей статьи суть модели сводится к получению данных из базы. В рассматриваемом сайте-примере существует два класса модели, это Pages и Articles. В первом классе собраны функции работающие с сущностью "страница", во втором с сущностью "статьи". Как вы видите названия классов моделей отражают суть данных которыми они оперируют. Классы модели являются наследниками Zend_Db_Table_Abstract. Методы работы с базой и пример класса модели смотрите ниже.

Работа с базой данных

Для гибкой работы с БД Zend Framework предлагает несколько классов. Нам понадобятся Zend_Db_Table, Zend_Db_Select, Zend_Db_Table_Select. В Bootstrap.php задается соединение с БД, задается адаптер используемый по умолчанию.

     // Подключение к БД, так как Zend_Db "понимает" Zend_Config, 
//нам достаточно передать специально сформированный объект конфигурации в метод factory
$db = Zend_Db::factory($this->_config->db);

// Задание адаптера по умолчанию для наследников класса Zend_Db_Table_Abstract
Zend_Db_Table_Abstract::setDefaultAdapter($db);

// Занесение объекта соединения c БД в реестр
Zend_Registry::set('db', $db);

На самом деле создание экземпляра класса адаптера не приводит к немедленному соединению с сервером базы данных. Адаптер сохраняет параметры соединения и производит подключение, когда нужно произвести первый запрос к базе данных. Это значит, что само по себе создание объекта адаптера производится быстро и занимает мало ресурсов

Отмечу что если вы используете Zend_Cache вам пригодится метод Zend_Db_Table_Abstract::setDefaultMetadataCache, с его помощью вы можете закешировать метаданные таблиц. Таким образом запрос describe table не будет выполнятся при каждом создании объекта Zend_Db_Table.

Далее вся работа с базой данных у нас будет собрана в классах моделей.
Для примера рассмотрим код класса Articles


<?php

class Articles extends Zend_Db_Table_Abstract
{

// Имя таблицы
protected $_name = 'articles';

/**
* Получить все статьи или одну
*
* @param int $articleId Идентификатор статьи
* @return array
*/
public function getArticles($articleId = null)
{

// Создаем объект Zend_Db_Select
$select = $this->getAdapter()->select()
// Таблица из которой делается выборка
->from($this->_name)
// Добавление таблицы с помощью join, указывается поле связи
->join('users','users.id = articles.author_id',array('name'))
// Порядок сортировки
->order('id DESC')
// Количество возвращаемых записей
->limit(2)
;

if (!is_null($articleId)) {

// Условие на выборку
$select->where("articles.id = ?",$articleId);
// Выполнение запроса
$stmt = $this->getAdapter()->query($select);
// Получение данных в виде объекта, по умолчанию в виде ассоциативного массива
$result = $stmt->fetch(Zend_Db::FETCH_OBJ);


}
else {

$stmt = $this->getAdapter()->query($select);
// Получение данных в виде массива объектов, по умолчанию в виде массива ассоциативных массивов
$result = $stmt->fetchAll(Zend_Db::FETCH_OBJ);

}

return $result;

}

}

Класс Articles наследует абстрактный класс Zend_Db_Table_Abstract. Таким образом, мы получаем возможность использовать его функционал по работе с базой. Zend_Db_Table реализует паттерн Table Data Gateway. Идея в том что для каждой таблицы создается отдельный класс который предназначен для работы именно с этой таблицей. Таким образом, работа с БД делится на логические части, с которыми, в случае большого объема проекта, работать гораздо удобнее. Например, вся работа со статьями в сайте-примере собрана в классеArticles, а работа со страницами собрана в классе Pages.

Все что нам нужно, это указать название таблицы с которой мы работаем: protected $_name = 'articles';

Для различных сложных выборок из базы используется класс Zend_Db_Select, он предоставляет гибкий функционал для выполнения select запросов. Особенно отмечу объектно-ориентированный подход "покусочного" построения sql-запросов. Например:


$select = $this->getAdapter()->select()
->from('articles')
->where("articles.id = ?",$articleId)
->join('users', 'users.id = articles.author_id', array('name'))
->order('id DESC')
->limit(2);

"Куски" могут располагаться в произвольном порядке, это очень удобно когда у вас запросы строятся динамически.

Для защиты от sql-инъекций в select запросах предлагается механизм плейсхолдеров where('id = ?',$pageId);
В случае же update, delete запросов использующих условие where c данными полученными от пользователя, необходимо поступать немного по другому. Для защиты от sql-инъекций в таких случаях нужно экранировать спец символы и брать данные в кавычки самому. Я использую следующий метод:
$id = $this->getAdapter()->quote($id);

Если запросы на выборку у вас достаточно простые и не требуют данных из других таблиц, вы можете использовать методы fetchRow, fetchAll класса Zend_Db_Table_Select (Вы также можете использовать аналогичные методы класса Zend_Db_Table но они являются устаревшими и к использованию более не рекомендуются), пример:


<?php
/**
* Работа с страницами
*/
class Pages extends Zend_Db_Table_Abstract
{

// Имя таблицы
protected $_name = 'pages';

/**
* Получить одну страницу (альтернативой этому методу может быть встроенный метод find)
*
* @param int $pageId Идентификатор страницы
* @return array
*/
public function getPage($pageId)
{

// Создание объекта Zend_Db_Table_Select,
// Нам не нужно указывать название таблицы как в Zend_Db_Select
$select = $this->select()
// Накладываем условие
->where('id = ?', $pageId);

// Выполняем запрос и получаем объект Zend_Db_Table_Row в результате
// Нам не нужно предварительно выполнять запрос методом query, как в Zend_Db_Select
$result = $this->fetchRow($select);

return $result;

}
}

Итого, если вам необходимы запросы на вставку, удаление, изменение данных - нужно использовать Zend_Db_Table. Если вам необходимы простые запросы на выборку данных результатом которых есть данные только одной таблицы - можно использовать Zend_Db_Table_Select (а можно и Zend_Db_Select). Если же вам нужны сложные запросы с получением данных из других таблиц - лучше использовать Zend_Db_Select.

Работа с видом Zend_View и Zend_Layout

Для работы с видом Zend Framework предлагает два класса, это Zend_View и Zend_Layout.

При создании объектов этих классов в Bootstrap.php я произвел небольшую настройку. Изменил расширение этих файлов на привычное tpl.

Вот так выглядит скрипт вида, отвечающий за список статей.


<ul>
<?php foreach ($this->articles as $article): ?>
<li><a href = "<?php echo $this->url(array('articleId' => $article->id),'articles'); ?>">
<?php echo $article->title; ?></a></li>

<?php endforeach; ?>
</ul>

PHP код здесь отделен от html кода, кроме того используется pascal-подобный синтаксис php для лучшего визуального восприятия.

Zend_Layout реализует паттерн "двухэтапное представление" (Two Step View pattern). Данный паттерн предназначен для гибкой работы с макетами вида. Создается некий главный макет дизайна сайта. Обычно он содержит каркас html страницы


// Doctype
<html>
<head>

// Мета теги
// Подключение css и т д
</head>
<body>
...
</body>
</html>

А вот все что находится между <body></body> разбивается на блоки, причем у каждого блока есть свой маленький макет. Это может быть меню, новости, блок авторизации и т д. Таким образом, если мы хотим изменить html код меню, мы меняем всего лишь один макет. Вот так выглядит код главного макета index.tpl


<?php echo $this->doctype(Zend_View_Helper_Doctype::XHTML1_TRANSITIONAL); ?>
<html>
<head>
<?php echo $this->headTitle('I LOVE ZEND FRAMEWORK!'); ?>
<?php echo $this->headMeta()->appendHttpEquiv('Content-Type', 'text/html; charset=UTF-8'); ?>

<?php echo $this->headLink()->appendStylesheet($this->baseUrl.'public/design/css/style.css'); ?>
<?php echo $this->headScript(); ?>
</head>
<body>
<div id="menu">

<?php echo $this->partial('menu.tpl'); ?>
</div>
<div id="main">
<div id="left">
<div style = "margin:5px;">Лучшие статьи:</div>

<?php echo $this->action('index', 'articles'); ?>
<div id = "copy">(c) San <a href = "http://zendframework.ru">http://zendframework.ru</a></div>
</div>
<div id="content"><?php echo $this->layout()->content; ?></div>

</div>
</body>
</html>

Кроме двухэтапного представления Zend_Layout дает помощников. Это doctype, headTitle, headMeta, headLink, headScript. Эти помощники выручают если например на какой то особой странице вы захотите подключить особый css или js файл.

С помощью помощника partial можно подключать другие макеты - блоки, например в вышеприведенном коде так подключается меню. Ключевое отличие между отображением partial и обычного скрипта вида (render()) в том что partial скрипты имеют свою собственную область видимости. Они будут видеть только те переменные, что были переданы непосредственно им. Если же в этом нет необходимости, с точки зрения производительности, лучше использовать render(). Подробнее с помощниками вида вы можете ознакомиться в статье

Кроме того можно вызывать различные действия прямо из макета с помощью помощника action(). Это дает нам возможность разбить весь шаблон сайта на блоки. Таким образом, я подключаю блок "Лучшие статьи", и когда я захочу убрать его со всех страниц, я удалю только одну строчку, а если я захочу изменить его формат, я отредактирую всего один view скрипт. Однако я рекомендую для этих целей использовать собственные помощники вида которые будут напрямую обращаться к модели, в обход контроллера. Пример такого помощника можно найти по ссылке

Также отмечу помощник Zend_View_Helper_Url который используется для построения URL на основании маршрутов. Теперь вам не нужно жестко вписывать ваши адреса в шаблоны. Достаточно сделать вызов вроде: <?php echo $this->url(array('articleId' => $article['id']),'articles'); ?> и вы получите корректный адрес вашей статьи. И самое главное, когда вы захотите что либо изменить в ваших URL, например для улучшения SEO эфекта, вам не прийдется править все ваши шаблоны. А только настроить маршруты.

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

Заключение

Скачать код без библиотек Zend (17 kb)
Скачать код с библиотеками Zend (418 kb)

Для запуска кода необходимо:

  1. Не забыть что Zend Framework требует php 5.1.4 или выше
  2. Установить расширение PDO с поддержкой драйвера mysql (если оно не установлено)
  3. Скачать архив, разархивировать его, document root виртуального хоста должен указывать на папку public. Обязательно убедитесь что у вас установлен модуль mod_rewrite веб сервера apache, если он не установлен переходя по ссылкам вы будете получать 404 ошибку.
  4. Создать базу данных в кодировке UTF-8
  5. Выполнить sql dump расположенный в корне архива
  6. Отредактировать конфигурационный файл application/settings/config.php Необходимо указать название БД, имя пользователя и пароль

Если же у вас нет возможности создать отдельный виртуальный хост для сайта вы можете попробовать запустить сайт в папке. Для этого вам прийдется выполнить следующие действия:

  1. Разместите код в нужной папке;
  2. Отредактируйте applications/settings/config.php изменив $baseUrl = '/'; на $baseUrl = '/dir_name/public/'; с обязательным слешом в конце. dir_name это название вашей директории;
  3. После этих настроек сайт станет доступен по адресу /dir_name/public/

Результат работы разработанного сайта примера можно увидеть по адресу http://ilovezf.demo.zendframework.ru

Скриншот главной страницы сайта примера:

Внешний вид сайта на базе Zend Framework

Рис. 4. Внешний вид сайта-примера

P.S.
Весь вышеизложенный подход построения приложения на базе Zend Framework есть субъективным мнением автора и не претендует на полную объективность и оптимальность. Главной целью данной статьи было показать, как можно использовать Zend Framework для построения web приложения. Не весь код приведенный в статье присутствует именно в таком виде в архиве, в некоторых местах в статье он не существенно изменен, для лучшей наглядности. В общем не забывайте что у вас своя голова на плечах.

P.P.S.
Приношу благодарность Grisha Kostyuk aka naspeh за помощь в написании статьи.

P.P.P.S.
Если статья показалась вам полезной, вы можете помочь развитию русскоязычному сообществу zend framework, поставив ссылку на ресурс http://zendframework.ru. В следующей статье серии я рассмотрю работу с Zend_Form и связанных с нею компонент.

Обсуждение на форуме

Лучший способ следить за обновлениями сайта это подписаться на RSS
Если информация была полезной для вас, вы можете поддержать сайт.
Комментарии:
AlexHustas 28.10.2008 12:24 #
Спасибо за статью!
Все очень понятно :)

Этот join в исходных кодах примера надо закоментить :)

-join('users','users.id = articles.author_id',array('name'))

файл - applications/models/ArticlesModel.php
Ответить
progLamer 01.11.2008 00:26 #
Хорошая полезная статья. Давно использую зенд, но некоторые фишки не знал. Приму на вооружение. :)
Ответить
scanner 02.11.2008 23:51 #
Добротная статья - попробуй книгу толковую написать о ZEND думаю получится
Ответить
san 05.11.2008 11:32 #
Да, хорошая идея :)
Ответить
lcf 05.11.2008 10:10 #
Книгу надо на английском писать, иначе аудитория будет слишком мала, а так можно было бы конечно че-нить подумать.
Ответить
scif 10.11.2008 16:25 #
хорошая статейка
Ответить
trial 12.11.2008 15:28 #
Спасибо, очень полезно. Небольшое замечание: если в вашем примере набрать примерно такой урл "ilovezf.ru/articles" (без id) или "ilovezf.ru/articles/3" (несуществующий id, то получается интересный эффект ). Неплохо бы учесть в примерчике. Хотя это не так важно.
Ответить
Павел 13.11.2008 08:16 #
отличная статья. пример сайта не смотрел, но отдельные примеры хороши. особенно помогли примеры стандных хелперов doctype, headTitle, headMeta, headLink, headScript

еще бы добавил
$this-headScript()-appendFile('file.js');
чисто для примера
Ответить
rollor 26.11.2008 16:36 #
не совсем понял насчет partial('menu.tpl'); ?

Допустим, вставляем в шаблон эту строку. Но ведь menu.tpl это просто html шаблон, там не может быть вызовов контроллеров/моделей ? следовательно если заранее не вызвать модуль Menu в контроллере то переменные в шаблоне menu.tpl будут неинициализированы, то есть у нас есть уже _два_ места которые надо держать в соотвествие.

Или из шаблона все таки можно (в смысле чистоты MVC парадигмы) вызвать модуль?
Ответить
san 01.12.2008 10:07 #
В случае текущего кода меню состоит из статических пунктов прописанных в шаблоне. Поэтому ничего вызывать не надо. А вообще MVC не запрещает обращаться к модулям с целью получения данных.
Ответить
Zorg 29.11.2008 17:30 #
Спасибо за статью. Я только начинаю изучать ZF. Очень помогло.
Ответить
Алексей Качаев 10.01.2009 18:00 #
Исправьте ошибочку в листинге для Pages.php
....
$row = $this-fetchRow($select);

return $result;
....
Либо return $row, либо $result = $this-...
Ответить
Александр Махомет 10.01.2009 22:50 #
Спасибо, исправил
Ответить
z0rg 13.01.2009 09:09 #
Добрый день
Большая просьба написать туториал, как верно подключить к вашему примеру библиотеку jQuery-PHP. Помогите пожалуйста начинающим, мне в том числе.
С уважением, Александр
Ответить
Олег 13.01.2009 10:36 #
Спасибо. Пишу на ZF довольно давно, но многое в голове только сейчас прояснилось.
Ответить
Алексей 03.02.2009 17:29 #
Добрый день. У меня есть вопрос по статье. Я начинающий Zend программист. Поставил Вашу программу на локальный хост - все вроде работает (http://localhost/index/index/index... и так до бесконечности)а вот если я перенесу Ваш сайт в папку на локальном хосте и прописал $baseUrl = 'MyZendPrj/'; - то уже проблемы - 404 ошибка при http://localhost/myzendprj/index

Помогите пожалуйста.
Заранее благодарен!
Ответить
Александр Махомет 03.02.2009 22:39 #
Нужно обращаться по такому адресу http://localhost/myzendprj/public/index

Читайте внимательнее инструкции по установке.
Ответить
Алексей 04.02.2009 09:16 #
Дело в том, что у меня document root находится по маршруту localhost а в этой папке уже находится myzendprj. Файл index.php находится в myzendprj/index.php а не в public, тут же лежит myzendprj/.htaccess
Ответить
Алексей 04.02.2009 09:17 #
все пути к zendframework и к system и так далее я прописал правильно
Ответить
Алексей 04.02.2009 09:53 #
Я вычислил, на каком месте вылетает - когда прописываю
front - setBaseUrl($this-_config-url-base)

$this-_config-url-base = 'MyZendPrj/' и в ней же лежит Index.php

Если убираю front - setBaseUrl($this-_config-url-base) то все работает, так вот вопрос -
- для чего нужна эта строка (если без нее все работает)?
- или может в ней предпологался какойто другой путь?

Расскажите пожалуйста
Ответить
Александр Махомет 04.02.2009 10:49 #
задайте вопрос на форуме
Ответить
Антон 12.02.2009 21:22 #
Спасибо. Очень полезная статья.
Ответить
Андрей 18.02.2009 12:15 #
Спасибо за статью. Помогла.
Начал разбиратся с Zend Framework-ом и зашел в тупик, статья дала просвет в понимании идеи создания сайтов с помощью ZF. Спасибо.
Хотелось бы увидеть часть 3.
Ждем продолжения.
Ответить
sashas 24.02.2009 01:39 #
Спасибо, начинаю потиху понимать и вникать.
Очень хорошо написано:)
Ответить
kudesnik 24.02.2009 18:01 #
Спасибо за статью.

Для запуска кода необходимо:
Я бы добавил между 3 и 4 пунктами
3.1 проверить в httpd.conf включен ли mod_rewrite.

При отключенном модуле первая страница грузится, а ссылки не работают.
Ответить
Александр Махомет 24.02.2009 18:03 #
Да, хорошая идея, новички постоянно на этом спотыкаются
Ответить
Киндерсюрприз 26.02.2009 16:06 #
У меня Апач в xampp вешается при конекте к базе
Ответить
vs 02.03.2009 22:04 #
может у вас не раскоментированы строки

extension=pdo.so
extension=pdo_mysql.so

в php.ini
Ответить
AlexNews 26.02.2009 19:29 #
Наверное очень умная статья, у меня даже пример заработал c полпинка, но я не понимаю основ Zend. Подскажите, плз где можно найти совсем простенькое объяснение для людей особо 'одаренных', типа меня? Где разбирается написание проги, а не описание как оно работает. PHP я учил на примере написания базы данных, довольно просто и доходчиво, тут же куча терминов совсем мне не понятных.
Ответить
Diolen 08.03.2009 06:22 #
Спасибо Большое !!!
Пытаюсь перейти с Codeigniter на Zend, статья очень помогла.
На следующих своих проектах обязательно размещю ссылочку на ваш сайт.
Ответить
saric 09.03.2009 19:53 #
Всем привет

Блин нечего немогу понять скачал архив отредактировал comfig.php

и сразу при входе

Fatal error: Class 'PDO' not found in D:\application\settings\config.php on line 36
Ответить
Александр Махомет 09.03.2009 22:48 #
Читайте тему закрепленную за статьей.
Ответить
Илья 16.03.2009 01:40 #
Хорошая статья... Спасибо! Можно еще немного дополнить код, чтоб корректно обрабатывал ситуации, скажем, когда пользователь запросил статью с несуществующим индексом: /articles/3, а не вываливал кучу ошибок.
Ответить
WIPS 18.03.2009 02:46 #
Тут генерится список неких статей:

action('index', 'articles'); ?

Но теперь получается, что если пользователь наберет "http://mysite.com/acticles/index/", то ему покажется список этих статей. Что делать если эту информацию я не хочу показывать пользователю в таком виде?
Ответить
Александр Махомет 18.03.2009 07:54 #
Как вариант - создать запрещающий маршрут "articles/index" = "error/404"
Ответить
igor 31.03.2009 17:27 #
Ребята подскажите в чем проблема???
- Запускаеться default но нет переходи по ссылкам
- mod_rewrite включен
- Все находиться на localhost, при нажатии на ссылку есть http://localhost/pages/1 но не отображаеться страница "Невозможно найти страницу"
Ответить
Ден 26.09.2010 04:01 #
Apache игнорит .htaccess
причины (файл httpd.conf для Apache):
1. отсутствие AllowOverride All для директории с .htaccess
2. отсутствие строки AccessFileName .htaccess
Ответить
Xappy 05.04.2009 14:17 #
Изображения можно было бы сделать в лучшем качестве, png какой вместо jpeg.
Ответить
Сергей 10.04.2009 13:03 #
Здраствуйте, а скажите можно ли скопировать(зделать рерайт) вашу статью себе на блог с обратной сылкой на веш сайт естествено? просто статья очень хорошая..
Ответить
Александр Махомет 10.04.2009 13:11 #
Именно статьи туториала нельзя, и я уже вам объяснял почему. Я над ними много работаю, и не хочу чтобы по сети распространялись некачественные "рерайты"
Ответить
drcreazy 07.05.2009 13:41 #
Спасибо очень помогло. Возникли проблемы со строчкой

Notice: Zend_Loader::Zend_Loader::registerAutoload is deprecated as of 1.8.0 and will be removed with 2.0.0; use Zend_Loader_Autoloader instead in /www/zf-tutorial/library/Zend/Loader.php on line 207

исправляется в Boostrap.php

        // Запуск автозагрузки
        //Zend_Loader::registerAutoload();
require_once ('Zend/Loader/Autoloader.php');
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->setFallbackAutoloader(true);
Ответить
Александр Махомет 07.05.2009 13:44 #
Статья написана под Zend Framework 1.7.x. Под версию 1.8 которую вы используете статья еще не адаптирована
Ответить
Aleksey 17.05.2009 08:56 #
Начал изучать Zend, но не могу понять в чем различие между Zend_Layout и Zend_View? Когда нужно использовать Zend_View и когда Zend_Layout?
Ответить
Александр Махомет 17.05.2009 13:29 #
Их нужно использовать одновременно.
Во введении мануала по Zend_View довольно неплохо написано. http://framework.zend.com/manual/ru/zend.view.html. Про Zend_Layout я достаточно подробно расписал в этом туториале.
Ответить
merlex 20.05.2009 17:20 #
Статья хорошая. Но для квик старта не пойдет. Это уже как разгонная после квик старта.
Ответить
Сержио 05.06.2009 11:49 #
А можно привести пример приложения более сложного!? Допустим как будет выглядеть получение статей + авторов статей + рубрик статей!? Как получить статьи с 1 по ... или как получить статьи только "видимые"!? Очень полезно было бы увидеть такие примеры для всех.
Ответить
Сержио 05.06.2009 12:26 #
А можно привести пример приложения более сложного!? Допустим как будет выглядеть получение статей + авторов статей + рубрик статей!? Как получить статьи с 1 по ... или как получить статьи только "видимые"!? Очень полезно было бы увидеть такие примеры для всех.
Ответить
Алекс 22.06.2009 09:52 #
Спасибо нормальная статья!!!
Ответить
A 28.06.2009 22:43 #
$this->view->article
можно узнать как работает данная строка? я что-то не понимаю)
Ответить
A 28.06.2009 22:45 #
То есть к чему         $this->view->article = $article;
мы здесь обращаемся, ведь view нигде не прописано
Ответить
Александр Махомет 29.06.2009 11:03 #
В свойстве view находится объект Zend_View. Записывается он туда в "недрах фреймворка". Так происходит потому что контроллеры наследуются от Zend_Controller_Action
Ответить
Maks 09.07.2009 11:37 #
Спасибо, за статью!!! Конечно для начала не совсем все понятно, можно было бы некоторые моменты более подробно объяснить, но все равно спасибо!
Ответить
Андрей 28.07.2009 16:18 #
Отличная статья. Хороший работающий пример.
Отлично обобщено все то, что на большинстве ресурсов представлено непонятными кусками. Очень помогла статья.
Ответить
Артём Гетьман 11.08.2009 17:47 #
У меня пример не запускается. Выводит ошибку:

string(522) "ERROR: Invalid controller specified (public)
#0 Z:\home\Zend-test\www\library\Zend\Controller\Front.php(946): Zend_Controller_Dispatcher_Standard->dispatch(Object(Zend_Controller_Request_Http), Object(Zend_Controller_Response_Http))
#1 Z:\home\Zend-test\www\library\Zend\Controller\Front.php(212): Zend_Controller_Front->dispatch()
#2 Z:\home\Zend-test\www\application\system\Bootstrap.php(53): Zend_Controller_Front::run('Z:\home\Zend-te...')
#3 Z:\home\Zend-test\www\public\index.php(22): Bootstrap->run(Array)
#4 {main}"

Использую фреймворк версии 1.9. Инструкциям по адаптации к нему следовал. Что делать?
Ответить
Александр 13.08.2009 11:07 #
Упражняюсь на версии ZF 1.8 (stable с оф.сайта).
Скачал исходники статьи, покдрутил где надо под 1.8, создал базу и таблицы в ней.
Пока не было таблиц в БД, страничка показывала эксепшены, как положено (table users does not exist).

Но вот создал таблицы, и при обновлении странички вижу системную Windows-ошибку в приложении "Apache HTTP server" с кнопками Отладка и Закрыть.

Среда Xammp под WinXP SP3, Apache 2.2.11, PHP  5.2.8,
Zend Engine v2.2.0.

Кто нить сталкивался ? Удалось победить ?
Ответить
Александр 14.08.2009 09:39 #
Сам же и нашел ответ - признанный баг в сборке XAMPP, нужно подменить библиотеку libmysql.dll на ту, что живет например, в пакете обновления PHP :
php-5.2-win32-VC6-x86-latest.zip
Ответить
Александр 18.08.2009 17:54 #
у меня вот такая ошибка...

Fatal error: Undefined class constant 'MYSQL_ATTR_INIT_COMMAND' in E:\newwork\application\settings\config.php on line 36

не наю что делать, вроде пути все правильные...

чего-то не хватает
Ответить
Александр 18.08.2009 21:40 #
Вопрос снят
Кривой PHP был...
Ответить
Pikcher 14.09.2009 07:55 #
в файле application/views/scripts/menu.tpl сделал var_dump($this);
почему столько раз данные дублируются?
Ответить
Toha 17.09.2009 12:29 #
Здравствуйте!

Подскажите пожалуйста, в чём проблема? Установил всё в точности, как написано в инструкции. При заходе на сайт получаю вот такое:

Warning: require(bootstrap.php) [function.require]: failed to open stream: No such file or directory in /home_dir/www/index.php on line 28

Fatal error: require() [function.require]: Failed opening required 'bootstrap.php' (include_path='/home_dir/application/settings/home_dir/library/:/home_dir/application/settings/home_dir/application/models/:/home_dir/application/settings/home_dir/application/system/') in /home_dir/www/index.php on line 28

Line 28: require 'bootstrap.php';


В конфиге прописаны

$root .= '/home_dir/';
$rootPublic = $root . 'www/'; (провайдер называет паблик www, поэтому использую эту папку вместо public).

Заранее большое спасибо!
Ответить
Toha 17.09.2009 13:01 #
Я дичайше извиняюсь, вопрос снимается!
Затупил с конфигом: прописал там путь к корню вместо /../../
Ответить
Toha 17.09.2009 13:04 #
Сейчас возникла таже проблема что и у Артёма Гетьмана

http://zendframework.ru/articles/tutorial-building-basic-site-on-zend-framework-1-5#479

Артём, вы не разобрались?
Ответить
andrey 31.10.2009 17:57 #
Помогите, новичок. Все поставил, все запускается, но при переходе по ссылкам 404. Можете дать подробное руководство по установке mod rewrite. Делал так http://dig.org.ua/2008/01/26/mod-rewrite-on-apache2-in-ubuntu/ но все равно выдает 404
Ответить
SofT MANiAC 16.11.2009 06:50 #
Нафиг:

    // Пути по которым происходит поиск подключаемых файлов, это папка библиотек, моделей и системных файлов
    set_include_path($paths);

?????

это ведь перекрывает то, что уже прописано в конфиге пехопе..

set_include_path(get_include_path() . PATH_SEPARATOR . $paths);

так не перекроет, а приаппендит

Ответить
Андрей 10.12.2009 17:44 #
Вечер добрый. Начал недавно интересоваться Зендом...
Появились вопросы после статьи.

Вот по маршрутам

<?php

    $router = new Zend_Controller_Router_Rewrite();

    $router->addRoute('articles',
         new Zend_Controller_Router_Route('articles/:articleId',
         array('controller' => 'articles', 'action' => 'view'))
    );

    $router->addRoute('pages',
         new Zend_Controller_Router_Route('pages/:pageId',
         array('controller' => 'index', 'action' => 'page'))
    );

это дело в каком файлике то прописывать?

и про Виды.
<?php foreach ($this->articles as $article): ?>
здесь $this->articles обратится к  protected $_name = 'articles'; в классе Articles?

З.Ы, Статья полезна, но для старта сложновато имхо =\
Ответить
Андрей 10.12.2009 18:02 #
Эм...Есть лишь догадка.
$this->articles вызывает магический метод что ли? который определён...где?
Ответить
MAXakaWIZARD 30.03.2011 10:18 #
по маршрутам:
инициализация роутера делается в методе setRouter класса Bootstrap (application/system/Bootstrap.php), сами маршруты задаются в файле application/system/routes.php, его инклудит метод setRouter.

по видам:
внутри вида $this->articles соответствует переменной, переданной в него из контроллера:
$articles = $modelArticles->getArticles();
$this->view->articles = $articles;
Ответить
Zingan 14.12.2009 16:08 #
у меня Ваш пример при запуске выдаёт такое
подскажите пожалуйста где не прав....
string(505) "ERROR: Invalid controller specified (index.php)
#0 C:\zf_prj\zftask\library\Zend\Controller\Front.php(934): Zend_Controller_Dispatcher_Standard->dispatch(Object(Zend_Controller_Request_Http), Object(Zend_Controller_Response_Http))
#1 C:\zf_prj\zftask\library\Zend\Controller\Front.php(214): Zend_Controller_Front->dispatch()
#2 C:\zf_prj\zftask\application\system\Bootstrap.php(53): Zend_Controller_Front::run('C:\zf_prj\zftas...')
#3 C:\zf_prj\zftask\public\index.php(30): Bootstrap->run(Array)
#4 {main}"
Ответить
lasol 10.03.2010 14:45 #
библиотеку zend саму положили в папку libs?
путь на папку libs указали правильный?
Ответить
Евгений 18.06.2011 00:18 #
Проблема в том что по умолчанию front controller бросает исключение когда пытаются использовать неизвестный контроллер. Для того чтобы использовать контроллер по умолчанию нужно в вашем примере в Bootstrap.php после строки

            // Создание объекта front контроллера
            $front = Zend_Controller_Front::getInstance();

добавить строку            
      
            $front->setParam('useDefaultControllerAlways', true);
Ответить
Артем 28.12.2009 12:21 #
Спасибо за статью. Перехожу ко второй части туториала :-)
Ответить
Кирилл 09.02.2010 11:56 #
Если честно то статья ужасная, ни путей для файлов к которым код приведен, ни пояснений! Если не скачивать исходники, а пробовать делать самому, то не выйдет ровным счетом ни чего.
В с исходниками данная статья и не нужна вовсе, ибо с ними можно разобраться быстрей используя "Начинаем работу с Zend Framework". обидно ):
Ответить
Антон 21.02.2010 17:08 #
Код, который доступен для скачки, не работает(по крайней мере у меня). Скачиваю код с самим Zendom? закачиваю в папку. Загружаю и получаю:
string(494) "ERROR: Invalid controller specified (public)
#0 X:\home\zf\www\library\Zend\Controller\Front.php(934): Zend_Controller_Dispatcher_Standard->dispatch(Object(Zend_Controller_Request_Http), Object(Zend_Controller_Response_Http))
#1 X:\home\zf\www\library\Zend\Controller\Front.php(214): Zend_Controller_Front->dispatch()
#2 X:\home\zf\www\application\system\Bootstrap.php(53): Zend_Controller_Front::run('X:\home\zf\www\...')
#3 X:\home\zf\www\public\index.php(30): Bootstrap->run(Array)
#4 {main}".
Ничего не изменяя. Работаю на локальном хосте, mod_rewrite включен, pdo установлено. Вобщем не понятно
Ответить
lasol 10.03.2010 14:40 #
библиотеку zend саму положили в папку libs?
путь на папку libs указали правильный?
Ответить
Денис 23.02.2010 15:27 #
Отмечу что если вы используете Zend_Cache вам пригодится метод Zend_Db_Table_Abstract::setDefaultMetadataCache, с его помощью вы можете закешировать метаданные таблиц. Таким образом запрос describe table не будет выполнятся при каждом создании объекта Zend_Db_Table.

Zend_Controller_Router_Route_Regex
Zend_Controller_Router_Route_Static

Хотелось бы поподробнее об этом.

Еще одна отличная статья! У вас талант писать подобные статьи! :)

Все понятно.
Ответить
lasol 04.03.2010 20:49 #
подскажите пожалуйста, почему не работают классы.
в layout.tpl в head где мы подключаем css, аптана, например, не распознает команды пхп в том числе и echo.
Ответить
Yaro 25.03.2010 05:43 #
Спасибо )
Ответить
Jay 22.05.2010 03:11 #
Где узнать что такое контроллер, модель и другие хитрые термины статья написана явно не для начинающих. Я хотя и пишу давно классы на разных языках хотелось бы найти источник, где простым языком описана философия Zenda из статьи непонятно.
Ответить
ditrix 25.05.2010 14:22 #
Jay
http://ru.wikipedia.org/wiki/MVC

автору спасибо. статья, как отправная точка для отхода от hello world и работы "по-взрослому" )
Ответить
ap7 06.07.2010 11:29 #
Спасибо Вам Александр) Вы на 12 ст (ну это лично у меня так получилось при печати :) ) расписали четко и ясно то, что автор книги Web 2.0 Квентин Зервас мусолил 3 раздела) так что спасибо Вам еще раз)
Ответить
Александр Махомет 06.07.2010 13:42 #
Спасибо, приятно :)
Ответить
tazododu 14.07.2010 00:45 #
всё, нимагу больше, не получаецц!! буду просить помощи!!


Warning: require(Zend/Loader.php) [function.require]: failed to open stream: No such file or directory in Z:\home\ilovezf\application\system\Bootstrap.php on line 3

Fatal error: require() [function.require]: Failed opening required 'Zend/Loader.php' (include_path='Z:\home\ilovezf\application\settings/../../library/;Z:\home\ilovezf\application\settings/../../application/models/;Z:\home\ilovezf\application\settings/../../application/system/') in Z:\home\ilovezf\application\system\Bootstrap.php on line 3

менял и так и сяк конфиг, ставил и в
Z:\home\localhost\www\ilovezf
и в
Z:\home\ilovezf

ниче не работает((
Ответить
tazododu 14.07.2010 00:53 #
чудо чудестное!!!! обозвал папку libs -> library и все стало окей!!
Ответить
dnka 29.07.2010 00:33 #
Все конечно хорошо, только вы, как и большинство просто переводите с англ. статьи. Одно и тоже ...

Хотелось бы прочесть про лайоты и вьюхи подробнее. Чтобы действительно понять что к чему и откуда. Проблема зенда в нулевой документации...
Ответить
yAnTar 10.08.2010 00:47 #
Большое спасибо за проделанную работу. Как раз разбираюсь с Зендом, ваш сайт просто находка.
Ответить
erik 29.10.2010 16:21 #
Скачал код, получаю такую ошибку:

string(518) "ERROR: Invalid controller specified (public)
#0 Z:\home\test1.ru\www\library\Zend\Controller\Front.php(954): Zend_Controller_Dispatcher_Standard->dispatch(Object(Zend_Controller_Request_Http), Object(Zend_Controller_Response_Http))
#1 Z:\home\test1.ru\www\library\Zend\Controller\Front.php(212): Zend_Controller_Front->dispatch()
#2 Z:\home\test1.ru\www\application\system\Bootstrap.php(53): Zend_Controller_Front::run('Z:\home\test1.r...')
#3 Z:\home\test1.ru\www\public\index.php(30): Bootstrap->run(Array)
#4 {main}"

помогите...с чем связано?
Ответить
wa1 02.11.2010 14:10 #
Что-то мне кажется что это уже просто все устарело и выглядет по другому на самом деле.
Ответить
Иван 21.03.2011 12:55 #
Все запускается  , только не происходит перехода по страницам, все время остается как бы на index
Ответить
Максим 14.05.2011 16:09 #
хорошая статья,все работает,только начинаю познавать Zend Framework, использую версию 1.11, не знаю на сколько актуальна это статья,но в любом случае очень полезная,автору спасибо.
Ответить
hlx 30.05.2011 23:09 #
Например установка роутера :
$route = new Zend_Controller_Router_Route(
    'articles/:articleId',
    array(
        'controller' => 'articles',
        'action'     => 'view'
    )
);

а вы писали:
"будет доступно по параметру articleId"

как например в контроллере достать значение перменной articleId?
Ответить
oleg 29.09.2011 15:53 #
$this->request->getPrams();
Ответить
Oleg 12.06.2011 05:13 #
А при вводе неверного урла так и должно быть:string(560) "ERROR: Invalid controller specified (pa%d0%bfges)
#0 /home/zendfram/public_html/libraries/Zend/Controller/Front.php(934): Zend_Controller_Dispatcher_Standard->dispatch(Object(Zend_Controller_Request_Http), Object(Zend_Controller_Response_Http))
#1 /home/zendfram/public_html/libraries/Zend/Controller/Front.php(214): Zend_Controller_Front->dispatch()
#2 /home/zendfram/public_html/ilovezf/application/system/Bootstrap.php(53): Zend_Controller_Front::run('/home/zendfram/...')
#3 /home/zendfram/public_html/ilovezf/index.php(25): Bootstrap->run(Array)
#4 {main}"
?
или где-то в скрипте ошибка?
Ответить
Евгений 18.06.2011 00:19 #
Проблема в том что по умолчанию front controller бросает исключение когда пытаются использовать неизвестный контроллер. Для того чтобы использовать контроллер по умолчанию нужно в вашем примере в Bootstrap.php после строки

            // Создание объекта front контроллера
            $front = Zend_Controller_Front::getInstance();

добавить строку            
      
            $front->setParam('useDefaultControllerAlways', true);
Ответить
oleg 29.09.2011 11:13 #
безопаснее вот так..перехватить возможную ошибку
try
{
    require 'Bootstrap.php';
}
catch(Exception $e)
{
    // Оповещаем о ошибке
    // Можно также проверить константу APPLICATION_ENVONMENT
    // и вывести подробную ошибку если она development
}
Ответить
oleg 29.09.2011 11:19 #
Ну и больше спасибо за статью... Хорошей литературы по ЗФ на русском практически нет. Спасибо за ваш труд

  
Ответить
alex 08.11.2011 08:35 #
Для примера сделано?
http://ilovezf.demo.zendframework.ru/pages
гыыыыы
Ответить
Vladimir 09.12.2011 09:45 #
Сразу понять этот пример у меня не получилось, сначала советую посмотреть более простые примеры
http://web-mastery.pp.ua/videos
начиная со вторго урока
Ответить
Cadenzar 06.03.2012 15:50 #
Поднял пример на денвере, все работает отлично и решил перенести папки application и libs в рабочую директорию хоста, т.к. не все хостинги позволяют размещать файлы выше рабочей директории. Перенастроил все пути, главная страница запускается, но не отрабатывает кодировка в .htaccess и не работают внутренние ссылки (путь остается корректным) а на деле Not found.  В чем может быть проблема ?
Ответить
Cadenzar 06.03.2012 18:50 #
Вопрос снят... дело оказалось в том, что .htaccess корректно не обрабатывался из-за BOM кодировки
Ответить
Уважаемые пользователи. Комментарии не для того чтобы:
  1. Спрашивать почему у вас не работает код, для этого есть тема форума закрепленная за статьей.
  2. Спрашивать как реализовать ту или иную функциональность, для этого необходимо создать свою тему на форуме.

Комментарии для того чтобы: высказать свое аргументированное мнение о статье, указать какие участки вызывают непонимание, что нужно исправить/улучшить, просто сказать спасибо.

Комментарии имеют древовидную структуру.
Если вы хотите ответить на определенный комментарий - нажмите на ссылку "Ответить" возле этого комментария.

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