19 июля 2007 в 23:41

Введение в Zend Framework перевод

PHP*
Update (2014): Это статья 2007 года, которая, к моему удивлению, до сих пор пользуется спросом. По этой причине я обновил её в соответствии с новыми правилами оформления постов на Хабре, и добавил подсветку синтаксиса для примеров кода. Если кому-то захочется что-то добавить или исправить, исходник текста с хабра-разметкой выложен в открытый доступ: gist.github.com/dreikanter/2b4ee996d7a775e707d7

Аннотация от переводчика


PHP — один из самых широко распространенных языков разработки веб-приложений и при этом один из самых спорных. Я очень часто видел негативное отношение к этой технологии, да и недостатки, провоцирующие это отношение — не для кого не являются секретом. Тем не менее, PHP активно эволюционирует и во многих отношениях постепенно становитс лучше. Одним из серьезных шагов его развития, на мой взгляд, является появление MVC-фреймворков, призванных систематизировать процесс разработки веб-приложений и приучить к порядку разработчиков, которым зачастую здорово не хватает силы воли, чтобы при всей предоставляемой языком свободе, сохранить грамотную и красивую инфраструктуру разрабатываемого ПО (сразу уточню, что последнее утверждение субъективно и основано исключительно на виденном мной коде различных программных решений).

В последнее время я активно заинтересовался архитектурой MVC и сделал свою собственную реализацию фреймворка на этой концепции для PHP4. Совсем недавно на глаза попался первый официальный релиз Zend Framework, о котором я давно слышал, но все руки не доходили с ним поиграть. Для PHP существуют и другие подобный библиотеки, но в данном случае привлек бренд.

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

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

В завершение введения, небольшой дисклаймер. Уважаемые любители Ruby on Rails и Python on Django, я уважаю вашу религию :) Убедительная просьба не развивать в комментариях тему о том, какой фреймворк или язык лучше. Это совсем не относящаяся к топику данного поста тема. Мне и, вероятно, многим сейчас будет гораздо интереснее узнать об опыте реальных разработок ПО на Zend.

Автор: Роб Ален, akrabat.com
Оригинал: akrabat.com/zend-framework-tutorial
Перевод: Александр Мусаев, musayev.com

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

Архитектура Модель-Вид-Контроллер


PHP-приложение, написанное традиционным способом, может представлять собой некое подобие следующего примера:

<?php
include "common-libs.php";
include "config.php";
mysql_connect($hostname, $username, $password);
mysql_select_db($database);
?>
<?php include "header.php"; ?>
<h1>Home Page</h1>
<?php
$sql = "SELECT * FROM news";
$result = mysql_query($sql);
?>
<table>
<?php while ($row = mysql_fetch_assoc($result)) { ?>
<tr>
<td><?php echo $row['date_created']; ?></td>
<td><?php echo $row['title']; ?></td>
</tr>
<?php } ?>
</table>
<?php include "footer.php"; ?>


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

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

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

Системные требования


У Zend Framework следующие требования:

  • PHP версии 5.1.4 или выше;
  • Веб-сервер, поддерживающий mod_rewrite.

В данной статье используется сервер Apache.

Где скачать Zend Framework


Zend Framework доступен для свободного скачивания в виде ZIP или TAR.GZ архивов по адресу framework.zend.com/download/stable.

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


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

Для начала, создайте директорию zf-tutorial в корневом каталоге вашего тестового веб-сайта. Это будет означать, что URL этой директории примет вид localhost/zf-tutorial (адрес может варьироваться, в зависимости от настроек вашего сервера).

После этого дополнительно создайте следующую структуру каталогов для хранения файлов веб-приложения:

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

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

Для начала, разархивируйте скачанный файл ZendFramework-1.0.0.zip (или .tar.gz) во временную директорию. Все файлы внутри архива находятся в директории ZendFramework-1.0.0. Скопируйте содержимое library/Zend в zf-tutorial/library. Теперь ваша директория zf-tutorial/library должна содержать подкаталог Zend.

Начальная загрузка


Контроллер Zend_Controller из библиотеки Zend Framework спроектирован для поддержки сайтов с хорошо читаемыми («чистыми») URL. Для достижения этой цели, все запросы к серверу перенаправляются для обработки на специальный файл index.php, именуемый так же файлом начальной загрузки (bootstrapper). Такой подход обеспечивает централизованную организацию инфраструктуры приложения и гарантирует корректную для его функционирования настройку программного окружения. Это достигается благодаря использованию конфигурационного файла .htaccess, который находится в директории zf-tutorial.

zf-tutorial/.htaccess:

RewriteEngine on
RewriteRule .* index.php
php_flag magic_quotes_gpc off
php_flag register_globals off

Директивой RewriteRule задано очень простое правило перенаправления URL, которое может быть переведено на человеческий язык, как «использовать index.php вместо любого URL». Для обеспечения безопасности так же откорректированы некоторые настройки интерпретатора PHP. в принципе, они уже должны быть заданы соответствующим образом в конфигурационном файле php.ini любого грамотно настроенного сервера, но в нашем примере они дублируются локально для большей надежности. Обратите внимание на то, что директива php_flag внутри файла .htaccess может применяться только при использовании mod_php. Если вы используете PHP через CGI или FastCGI, необходимо удостовериться в правильной настройке php.ini.

Вопреки сказанному выше, запросы, относящиеся к графическим файлам, JavaScript и CSS, не должны быть перенаправлены на index.php. Учитывая, что все они хранятся в отдельной директории public, мы с легкостью можем настроить Apache, чтобы сервер отдавал их напрямую. Для этого необходимо создать еще один файл .htaccess в директории public и задать в нем соответствующую директиву.

zf-tutorial/public/.htaccess:

RewriteEngine off

Для повышения безопасности, можно создать дополнительные файлы .htaccess в директориях zf-tutorial/application и zf-tutorial/library, с одинаковым содержимым.

zf-tutorial/application /.htaccess, zf-tutorial/library/.htaccess:

Deny from all

Эта директива закроет доступ из web к содержимому указанных директорий. (Прим. переводчика: последние два файла можно не создавать вообще, если все, что находится вне директории public, заведомо закрыто глобальными настройками сервера).

Обратите внимание на то, что для использования файлов .htaccess, в настройках сервера Apache (httpd.conf) должна быть задана директива AllowOverride со значением All. Приведенная в данной статье идея использования файлов .htaccess принадлежит Джейсону Майнарду (Jayson Minard) и опубликована в статье «Схема построения PHP-приложений: начальная загрузка (Часть 2)» (http://devzone.zend.com/node/view/id/119). Начинающим разработчика стоит ознакомиться с обеими ее частями.

Файл начальной загрузки index.php


Файл начальной загрузки zf-tutorial/index.php содержит следующий код:

<?php

error_reporting(E_ALL|E_STRICT);
date_default_timezone_set('Europe/London');
set_include_path('.'.PATH_SEPARATOR . './library'
    .PATH_SEPARATOR.'./application/models/'
    .PATH_SEPARATOR.get_include_path());

include "Zend/Loader.php";
Zend_Loader::loadClass('Zend_Controller_Front');

// setup controller
$frontController = Zend_Controller_Front::getInstance();
$frontController->throwExceptions(true);
$frontController->setControllerDirectory('./application/controllers');

// run!
$frontController->dispatch();

Заметьте, что в конце файла отсутствует закрытие блока PHP кода ?>, т. к. в нем нет необходимости. Кроме того, наличие закрывающего тага может привести к появлению сложных для выявления ошибок при редиректе функцией header(), если в конце файла по недосмотру останутся лишние пробелы.

Рассмотрим код подробнее.

error_reporting(E_ALL|E_STRICT);
date_default_timezone_set('Europe/London');

Данные строки обеспечивают вывод интерпретатором всех сообщений о происходящих ошибках (подразумевается, что в конфигурационном файле php.ini параметру display_errors задано значение on). Вторая строка кода задает часовой пояс, согласно стандартному требованию PHP 5.1+. Приведенное в примере значение параметра следует заменить на соответствующее вашему географическому положению.

set_include_path('.'.PATH_SEPARATOR.'./library'
    .PATH_SEPARATOR.'./application/models/'
    .PATH_SEPARATOR.get_include_path());
include "Zend/Loader.php";

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

Файл Zend/Loader.php содержит класс Zend_Loader со статическими функциями, позволяющими подключать любой класс из Zend Framework.

Zend_Loader::loadClass('');

Метод Zend_Loader::loadClass() подключает класс с заданным именем. Для этого выполняется преобразование указанного имени в путь к соответствующему файлу: символы «_» заменяются на «/», а в конце получившейся строки добавляется расширение .php. Таким образом, Zend_Controller_Front преобразуется в Zend/Controller/Front.php. Если следовать аналогичной схеме построения имен для собственных библиотечных классов, то метод Zend_Loader::loadClass() можно будет использовать и с ними.

Класс, который понадобится нам прежде всего, — первичный контроллер. При его работе, в свою очередь, используется специальный класс-роутер, чья задача состоит в нахождении по заданному URL функции отображения соответствующей веб страницы. Для этого роутере должен быть определен базовый URL файла index.php, относительно которого он сможет выделять URI отдельных страниц.

Базовый URL может автоматически определяется с помощью объекта Request, а для того, чтобы применить его в нашем примере следует воспользоваться методом $frontController->setBaseUrl().

Далее нам понадобится сообщить первичному контроллеру о местоположении директории с другими контроллерами:

$frontController = Zend_Controller_Front::getInstance();
$frontController->setControllerDirectory('./application/controllers');
$frontController->throwExceptions(true);

Учитывая, что наша программа предназначена для образовательных целей и функционирует на тестовой системе, можно разрешить все исключения, которые могут происходить при ее работе. По-умолчанию, первичный контроллер будет перехватывать их все до одного и хранить в свойстве _exceptions своего объекта (данному объекту соответствует англоязычный термин Response object). Этот объект используется для хранения всей информации, возвращаемой при обращении к заданному URL, что включает HTTP-заголовок, содержимое веб-страницы и массив произошедших исключений.

Первичный контроллер автоматически выдает заголовок и контент страницы непосредственно перед окончанием своей работы. Тех, кто ранее не встречался с архитектурой веб-приложений, подобной Zend Framework, может привести в некоторое недоумение тот факт, что для отображения сообщений об исключительных ситуациях, их (исключения) необходимо повторно возбуждать. Эта особенность становится актуальной для серверов, работающих в своем штатном режиме, когда вывод сообщений об ошибках на страницах неуместен.

В итоге, после всех выполненных приготовлений, наше приложение может быть запущено:

// run!
$frontController->dispatch();

Если вы сейчас попытаетесь открыть страницу localhost/zf-tutorial, то увидите сообщение о фатальной ошибке, гласящее примерно следующее:
Fatal error: Uncaught exception 'Zend_Controller_Dispatcher_Exception' with message 'Invalid controller specified (index)' in...

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

Веб-сайт


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

Fieldname Type Null? Notes
id Integer No Primary key, Autoincrement
artist Varchar(100) No
title Varchar(100) No

Необходимые страницы

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

  • Начальная («домашняя») страница. Список альбомов со ссылками для их редактирования и удаления. На странице так же будет присутствовать ссылка для добавления новых дисков.
  • Добавить альбом. Страница с формой добавления нового диска в базу.
  • Редактировать альбом. Страница с формой для редактирования записи.
  • Удалить альбом. Страница для запроса пользовательского подтверждения перед удалением диска.

Организация страниц


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

Примечание переводчика. Небольшое пояснение терминологии. Англоязычным оригиналом используемого в данной статье термина «действие» является слово action. Приведенный перевод на данный момент еще не является устоявшимся понятием, и в некоторых текстах о модели MVC вместо него попадаются иные определения. Например, так же известна прямая (и режущая слух) транслитерация — «экшен».

Действия, в свою очередь, объединяются в специальные группы — «контроллеры». Например, для URL localhost/zf-tutorial/news/view контроллером будет news, а действием — view. Контроллеры предназначены для объединения родственных действий. Для упомянутого news, могут быть определены действия current, archived и view (соответственно для отображения последней новости, архива записей и новостной ленты).

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

В контроллерах Zend Framework существует понятие действия по-умолчанию, для которого зарезервировано имя index. Такие действия исполняются при обращении к URL вида localhost/zf-tutorial/news (в данном примере выполняется действие index контроллера news). Помимо исполняемых по-умолчанию действий, так же предусмотрены выбираемые по-умолчанию контроллеры с аналогичным именем — index. Это означает, что URL localhost/zf-tutorial будет соответствовать действию index контроллера index.

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

Страница Контроллер Действие
Начальная страница Index Index
Добавить альбом Index Add
Редактировать альбом Index Edit
Удалить альбом Index Delete


Настройка контроллера


Приступим к созданию нашего контроллера. в Zend Framework контроллер представляет собой класс с именем типа {Имя_контроллера}Controller. Класс должен быть описан внутри файла с именем {Имя_контроллера}Controller.php, в общей директории контроллеров. Стоит обратить внимание на важный нюанс: первая буква в имени класса-контроллера и имени его файла должна быть заглавной, а все остальные — строчными. Каждое действие должно быть открытой функцией класса-контроллера с именем типа {имя_действия}Action. в данном случае, имена действий должны начинаться со строчной буквы.

Таким образом, наш класс-контроллер будет носить имя IndexController и находиться в файле zf-tutorial/application/controllers/IndexController.php.

zf-tutorial/application/controllers/IndexController.php:

<?php

class IndexController extends Zend_Controller_Action
{
    function indexAction()
    {
        echo "<p>in IndexController::indexAction()</p>";
    }

    function addAction()
    {
        echo "<p>in IndexController::addAction()</p>";
    }

    function editAction()
    {
        echo "<p>in IndexController::editAction()</p>";
    }

    function deleteAction()
    {
        echo "<p>in IndexController::deleteAction()</p>";
    }
}

В данном макете контроллера каждое действие будет выводить свое имя. Это можно протестировать, задавая приведенные ниже URL:
URL Displayed text
localhost/zf-tutorial in IndexController::indexAction()
localhost/zf-tutorial/index/add in IndexController::addAction()
localhost/zf-tutorial/index/edit in IndexController::editAction()
localhost/zf-tutorial/index/delete in IndexController::deleteAction()

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

А теперь пришло время добавить в наше приложение новый вид.

Вид


Класс Zend Framework, на базе которого строится вид, называется просто и бесхитростно — Zend_View. Вид позволяет отделить код, отвечающий за отображение страницы, от кода функций-действий.

Простейший вариант использования Zend_View выглядит как показано ниже:

$view = new Zend_View();
$view->setScriptPath('/path/to/view_files');
echo $view->render('view.php');

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

Разработчики Zend Framework предусмотрели решение этой задачи и для ее решения создали так называемые «помощники действий» (action helpers). Класс Zend_Controller_Action_Helper_ViewRenderer инициализирует свойство view для нашего последующего использования ($this->view), а так же занимается отображением скриптов вида. Для рендеринга веб-страниц он использует объект Zend_View, который в свою очередь находит скрипты видов в файлах views/scripts/{имя_контроллера}/{имя_действия}.phtml (по-умолчанию они хранятся именно там, но при необходимости дислокацию скриптов можно менять).

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

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

Изменения внутри класса IndexController выделены жирным шрифтом.

zf-tutorial/application/contollers/IndexController.php:

<?php

class IndexController extends Zend_Controller_Action
{
    function indexAction()
    {
        $this->view->title = "My Albums";
    }

    function addAction()
    {
        $this->view->title = "Add New Album";
    }

    function editAction()
    {
        $this->view->title = "Edit Album";
    }

    function deleteAction()
    {
        $this->view->title = "Delete Album";
    }
}

Внутри каждой функции мы присваиваем значение переменной title свойства view. Заметьте, что при этом в действительности не происходит никакого отображения текста — это задача первичного контроллера, которая будет выполнена в самом конце работы системы.

Теперь нам понадобится добавить четыре файла для видов нашего веб-приложения.

zf-tutorial/application/views/scripts/index/index.phtml:

<html>
<head>
    <title><?php echo $this->escape($this->title); ?></title>
</head>
<body>
    <h1><?php echo $this->escape($this->title); ?></h1>
</body>
</html>

zf-tutorial/application/views/scripts/index/add.phtml:

<html>
<head>
    <title><?php echo $this->escape($this->title); ?></title>
</head>
<body>
    <h1><?php echo $this->escape($this->title); ?></h1>
</body>
</html>

zf-tutorial/application/views/scripts/index/edit.phtml:

<html>
<head>
    <title><?php echo $this->escape($this->title); ?></title>
</head>
<body>
    <h1><?php echo $this->escape($this->title); ?></h1>
</body>
</html>

zf-tutorial/application/views/scripts/index/delete.phtml:

<html>
<head>
    <title><?php echo $this->escape($this->title); ?></title>
</head>
<body>
    <h1><?php echo $this->escape($this->title); ?></h1>
</body>
</html>

При тестирование каждого из действий, должны быть отображены выделенные заголовки каждой из страниц.

Общий HTML-код

Уже сейчас становится заметно использование одинаковых фрагментов HTML кода в наших видах. Выделим идентичные для всех файлов части в два отдельных файла: header.phtml и footer.phtml, созданных внутри все той же директории со скриптами.

zf-tutorial/application/views/scripts/header.phtml:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.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" />
    <title><?php echo $this->escape($this->title); ?></title>
</head>
<body>
    <div id="content">

(Обратите внимание на изменения, добавленный в код.)

zf-tutorial/application/views/scripts/footer.phtml:

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

Файлы видов так же понадобится откорректировать.

zf-tutorial/application/views/scripts/index/index.phtml:

<?php echo $this->render('header.phtml'); ?>
<h1><?php echo $this->escape($this->title); ?></h1>
<?php echo $this->render('footer.phtml'); ?>

zf-tutorial/application/views/scripts/index/add.phtml:

<?php echo $this->render('header.phtml'); ?>
<h1><?php echo $this->escape($this->title); ?></h1>
<?php echo $this->render('footer.phtml'); ?>

zf-tutorial/application/views/scripts/index/edit.phtml:

<?php echo $this->render('header.phtml'); ?>
<h1><?php echo $this->escape($this->title); ?></h1>
<?php echo $this->render('footer.phtml'); ?>

zf-tutorial/application/views/scripts/index/delete.phtml:

<?php echo $this->render('header.phtml'); ?>
<h1><?php echo $this->escape($this->title); ?></h1>
<?php echo $this->render('footer.phtml'); ?>

Стилевое оформление

Для того, чтобы сделать наше веб-приложение визуально более привлекательным, используем CSS. На этом этапе возникает небольшая проблема, связанная с тем, что заранее неизвестен URL корневой директории, необходимый для ссылки на CSS-файл. Для разрешения этой задачи используется функция getBaseUrl() передаваемого в вид объекта Request. Она и предоставит нам неизвестный заранее фрагмент URL.

Это свойство становится доступным из любого действия, после выполнения IndexController::init().

zf-tutorial/application/controllers/IndexController.php:

...
class IndexController extends Zend_Controller_Action
{
    function init()
    {
        $this->view->baseUrl = $this->_request->getBaseUrl();
    }

    function indexAction()
    {
...

Ссылку на CSS-фалй понадобится добавить в секцию файла header.phtml:

zf-tutorial/application/views/scripts/header.phtml:

...
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
    <title><?php echo $this->escape($this->title); ?></title>
    <link rel="stylesheet" type="text/css" media="screen"
    href="<?php echo $this->baseUrl;?>/public/styles/site.css" />
</head>
...

В завершении, понадобится создать, собственно, сам стилевой файл.

zf-tutorial/public/styles/site.css:

body,html {
    font-size: 100%;
    margin: 0;
    font-family: Verdana, Arial, Helvetica, sans-serif;
    color: #000;
    background-color: #fff;
}

h1 {
    font-size:1.4em;
    color: #800000;
    background-color: transparent;
}

#content {
    width: 770px;
    margin: 0 auto;
}

label {
    width: 100px;
    display: block;
    float: left;
}

#formbutton {
    margin-left: 100px;
}

a {
    color: #800000;
}

Это заставит страницы выглядеть несколько приятнее.

Продолжение статьи
Автор оригинала: Rob Allen
Alex Musayev @dreikanter
карма
75,1
рейтинг 0,0
Похожие публикации
Самое читаемое Разработка

Комментарии (158)

  • +4
    Не каждый осилит такое, а посмотреть профиль dreikanter молодец :)

    Хорошо бы на хабре была подсветка кода, куда веселее читалось бы.
  • 0
    Не когда не использовал фреймфорки, так как боюсь что при большой посещаемости, они будут создавать лишнюю нагрузку. Всё ищу статью, которая переубедит меня, никакак не найду. :(
    • 0
      Вместо того, чтобы искать, интереснее написать тесты самому для нескольких развитых фреймворков и погонять под нагрузкой. Результат, кстати, многим был бы интересен.
      • 0
        Ну "ищу" я бы в кавычки поставил, точнее сказать "надеюсь" что увижу.
        А самому тесты некогда проводить. Ведь это нужно каждый фреймворк изучить, написать на нем не мало и потом погонять на крупном проекте. Не легкая задача...
        • 0
          "не ищу, а надеюсь". отличный подход :)
      • 0
        • 0
          я конечно извиняюсь, но как может быть адекватен hello world для тестирования фрэймворка? Я могу написать cgi которая будет выводить тоже самое в 5 раз быстрее но это не значит что это 5 раз круче. Тестировать надо на реальных задачах, где функционал используется по полной.
          • 0
            мы говорим о фреймворке, а там подразумевается (по крайней мере в современных) модель MVC, а просто выводить "hello world" можно и парой строчек
            • 0
              Вобще было бы не плохо тестировать такие вещи в человеко/часах потраченных на нормальную задачу =)
            • 0
              Вообще без участия интерпретаторов.
          • +1
            Я представляю какую работу огромную надо провести, чтобы протестировать все фреймворки в "реальных" приложениях с реальной нагрузкой, с разными условиями, разными задачами...
            Это задача для целой лаборатории, мой же тест позволяет оценить примерные позиции, так сказать для ознакомительных целей
      • 0
        А это первая часть
        http://www.alrond.com/ru/2007/jan/25/rez…
        • 0
          Спасибо за ссылку, интересные результаты.
      • +1
        Тестировал сначала для себя,пока искал, с чем работать, потом решил добавить еще побольше фреймворков и всем выложить.

        Вот такие фреймворки:
        - CodeIgniter,
        - Catalyst,
        - Django, с psyco и без
        - RubyOnRails,
        - Symfony,
        - Zend Framework,
        - Pylons,
        - CakePHP, с eAccelerator и без
        - Turbogears with Cheetah, Jinja, Genshi
        • +4
          Сударь, вам не кажеться это идиотизмом тестировать фреймворки на отображение Hello World. Они не для того созданы. Понятное дело, что лучше всего показатели будут у голого РНР. Тогда зачем нужны все эти Зенды, Симфони, Кейки и пр. Если вы хотите провести более-менее объективное тестирование, а не Hello World (вы много писали реальных проектов, которые выводили Hello World?), напишите полноценное веб-приложение. На всех этих фреймворках. Сравните ко всем время обучнения, время написания, количество написанных строчек и пр. Фреймворк ускоряет и упрощает процесс разработки, не дает эстетам вывести Hello World.

          В этом я полностью согласен с Фабиеном Потенсьером - разработчиком Симфони. Ссылку на его статью я уже тут выложил. Советую ознакомиться ;)
          • +3
            между делом, хочу запостить небольшой обзор скорости работы модуля Zend_Cache по разным адаптерам. кто бы поднял карму, чтоб я мог это сделать?
            • 0
              Вроде должно хватить. Оригинальный способ поднять карму ;)
          • 0
            Сударь, тесты были сделаны для тех, у кого есть голова на плечах и умеет делать выводы сам, а тех кто не понял целей всегда хватает.
            Делал для своего выбора, после учета всех факторов, выбор был сделан, так что далее сравнивать мне это не интересно, тем более что никто это не оплачивает.
          • 0
            Полностью согласен
    • +3
      Как правило там где большая нагрузка рулит кэш. И производительность фрэймворка уже не такой важный фактор.
      • 0
        Точно. Злой навороченный кэш.
    • 0
      Фрэймворк предоставляет дополнительные стандартные инструменты, которые позволяют значительно ускорить разработку проекта, систематизировать архитектуру, обеспечить отчуждаемость проекта. При этом среди дополнительных инструментов могут быть и те, которые ускоряют работу веб-прилоения, например, в ZF есть Zend_Cache, который, в свою очередь, предоставляет отличный API для работы с memcached и прочими бэкэндами кэша. Шустрая штука.
      • 0
        хм, неплохо
      • НЛО прилетело и опубликовало эту надпись здесь
    • 0
      Насчет использования фреймворков мне больше всего понравилась статья разработчика Symfony

      http://www.symfony-project.com/weblog/20…
      Кстати:
      "Yahoo! picked symfony for a 20 Million users application"
      • +1
        Из интервью:

        So for instance, you will not find this code in symfony:

        for ($i = 0; $i

        Простите, но это неправильный и правильный код, а не оптимизация!
        А гордиться, тем, что они додумались закэшировать размер массива в переменную перед итерацией по нему, это .... даже слова подбрать не могу.
    • –4
      +1. От себя добавлю, что пока для PHP не появится компилятор, я не собираюсь использовать "универсальные" решения, позволяющие ускорить цикл разработки.
      • 0
        почему?
        • 0
          никакая оптимизация, prefetch, memcache не смогут обогнать изначально переведенные с humad-readble в bytecode алгоритмы. Если бы это было не так, то все модули для того-же php можно было бы смело писать на php, ведь суть-то не в том что они на C написаны, а в том, что они уже скомпилированы, адекватным для несущей ОС способом. В классическом оффлайн программировании язык вообще вторичен, там рулят компиляторы, чей компилятор качественнее переводит, те приложения и быстрее работают. Я бы с удовольствием писал все на C, но workflow уже положен на PHP, как на web-ориентированое средство разработки, поэтому я надеюсь. Жду и надеюсь.

          P.S. Интересно за что столько минусов?
          • +1
            Ты б уже на ассемблере писал. Для веб-программирования важна скорость разработки. Всё-таки программисты дороже, чем железо сервера
            • –1
              asm использовать нерационально. код вообще нечитаемый. Железо сервера безусловно дороже, но еще дороже scalability проекта, а это настолько индивидуальная вещь, что использование Framework может привести к проблемам.
              Я думаю, никому из читающих не надо напоминать какие крупные проекты переживали кризис и переписывались с нуля из за непродуманной scalability. Я не против framework-ов, когда потолок посетителей ясен. Но если размер аудитории отсюда до завтрашнего утра, то я за фреймворк, подогнанный под задачи проекта.

              Time-critical места в ресурсоемких приложениях или играх по прежнему пишутся на C или даже ASM.

              PHP изначально появился как framework для перла. А теперь мы накручиваем на и без того толковый каркас еще какие-то? Зачем? Каких функций в PHP не хватает для разработки бизнес-логики?

              Чем дороже программист, тем выше его квалификация по идее. Значит UML диаграммы, которая потом в каркас PHP-приложения построится будет достаточно для реализации.
              • +1
                Эти крупные проекты к тому времени успевали заработать либо кармы либо деньжат на свое переписывание.
                Начни из делать изначально под высокие нагрузки - и не стали бы они крупными, потому что просто сил бы их доделать до вида, пригодного для использования, не хватило.
                • –1
                  то есть подумать о нагрузке изначально - дороже, чем думать о ней опосля?
                  • +2
                    Все зависит от того, сколько есть изначально ресурсов. И сколько наработок.
                    Но для многих проектов важно сначала проверить идею, если она оказалась востребована - можно найти ресурсы на рефакторинг, повышение производительности, новое железо и т.д.
                  • +3
                    есть такое понятие, как premature optimization
                    перефразируя - о нагрузке надо думать когда начнет припекать.
                    запущенное в продакшн веб приложение покажет все затыки само по себе, оптимизация же заранее подобна борьбе с ветряными мельницами.
                  • 0
                    Если люди придумали что-то хорошее для пользователей, а у них мало денег и времени? Им ничего не остается как можно быстрее и легче написать приложение, работающее хотя бы для тысячи пользователей, а потом уже на его основе привлечь деньги и человеческие ресурсы. Конечно в целом они потратят больше денег и времени на переработку, но изначально увы у них нет друго пути
                    • 0
                      Я бы с удовольствием подисскутировал на эту тему еще. Очень интересно послушать разнообразные мнения, но на публику работать я не хочу, и + и - просто отвлекают от вникания в аргументы. Я просто не понимаю смысла оценки, согласен - хорошо, не согласен - оппонируй. К тому-же на хабре есть группа, которая минусует меня по причинам, не относящимся к моим постам и комментам. Всем спасибо за полилог. На сем откланяюсь.
                      • 0
                        Честно не минусовал. Просто написал коммент.
              • +1
                Фреймворк так или иначе постоянно дописывается(тот же zf позволяет почти везде это сделать) под конкретный проект. В общем то это основной путь развития любого фреймворка, так как его создатели не могут изначально определить все прецеденты.

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

                А ведь некоторые не рисуют подробных UML-диаграмм, только наброски (XP, TDD) =)
                • 0

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

                  Теперь ты знаешь одного.
      • 0
        положите opcode в кеш "на века"
    • +3
      Если есть руки - любой фреймворк можно "разогнать". Причём особых усилий для этого не нужно. Различными ухищрениями я умудрился разогнать зенд в 4 раза (с 20 до 80 req/s). Это и кеширование explain таблиц, кеширования frontcontroller состояние которого между запусками, даже на разных страницах в общем-то не меняется, кеширование. При этом у меня результаты бизнес-логики не кешируются вовсе. Кеш - в shmem (apc || xcache).

      При этом ГОТОВЫЙ проект на Xeon 2.4GHz DualCore (4 CPU, 8 Cores) выдает 480 req/s. Т.е. приблизительно 50 req/s на ядро. Или 0.02 сек на запрос. Я нахожу это отличным результатом ;). Удобство разработки на фреймворке стоит куда дороже.
      • 0
        интересен один вопрос: сколько понадобилось на это времени и стоило ли оно того, если фреймворк нужен "здесь и сейчас"?
  • 0
    Спасибо за перевод!
  • +1
    Выглядит довольно просто, но как то не закончено. Возможно потому, что статья еще не вся :-). Реализация MVC стандартная и схожа со многими фремворками. Интересно знать на сколько он закончен и применим не только для блогов.

    Сейчас активно интересуюсь Symfony. В основном, по причине хорошой документации. В принципе неплохо реализовали MVC. Активно используют конвенции. Настройки на yaml, но можно и xml.
    ORM Propel и абстракция базы Creole.
    Для рутинных операций (создание структуры папок, создание базовых классы моделей,CRUD)используются скрипты генерации.

    Может у кого есть опыт реализации на Symfony приложений типа стандартного магазина с допустим купонами и афилейтами, комъюнити сайта (блог, форум, социальная сеть, приватные сообщения, личная галерея фоток, личное расписание, какая - нибудь тематическая начинка)?
    • 0
      Плаигны к Симфони сейчас активно пишуться, а так... Пока РНР-фреймворки достаточно молодые и к ним нету нужного количества модулей.

      Могу посоветовать Seagull PHP Framework. К нему написано гораздо больше модулей, и например, галерея, блог и ЛСки там есть. Советую глянуть.
      • 0
        Готовые решения не проблема. Я имел ввиду насколько эффективно при решении таких задач использовать symfony. По мне так лучше написать самому законченое приложение, чем подстраивать чужое. Всегда есть ньюансы, которые нужно доделать ручками.
        Несколько лет пишу на собственном фреймворке, но что то он стал уже не модным :-) и захотелось что-нибудь эдакое с ORM, c генерацией и т.п.
        Был короткий опыт работы с eZ, по моему норвежцы создали какого-то монстра.
        • 0
          Ну фреймворки без ORM уже действительно не воспринимаются. Я определяю так: если нужны стандартные элементы сайта, такие как: навигация, управление пользователями, управление блоками, CMS, галерея, блог, но при этом чтоб архитектура сайта была полноценным MVC-фреймворком (с поддержкой ORM), то я выберу Сигал. Если это приложение, которое практически не использует стандартный функционал сайта ( например, веб-сервисы), то я избрал бы Симфони.
        • 0
          Работали с eZ Publish или eZ Framework ? По поводу второго интересуют мнения.
    • 0
      Вторая половина статьи скоро будет :)
    • НЛО прилетело и опубликовало эту надпись здесь
  • 0
    А сейчас обязательно припрется фанат Ruby/Java/Python и начнется очередной холивор :)
    Пойду запасаться попкорном
    • +1
      django is much better and faster!!

      кошу под европейца. Суровая реальность.
  • 0
    А чем Zend Framework лучше остальных, например CodeIgniter или CakePHP? Какие у него отличительные черты, преемущества?
    • 0
      Команда разработчиков и PHP5 only.
  • +1
    Спасибо за перевод, из-за отсутствия именно туториала он довольно полезен.
    Кстати, почему на устах не упоминается Seagull в списке фреймворков? :)
    http://seagullproject.org/
    Это все было сделано там еще 2-3 года назад, если не больше - отличная реализация паттерна MVC, контроллеры, экшины, валидаторы и т.д. Не знаю насколько проект развивается и поддерживается сейчас, но посмотреть на качественный код стоит.

    А как с библиотеками классов у ZF - может кто знает? Абстракции это хорошо, но на одной модели не проживешь. Это дело времени конечно, просто не хотелось бы снова использовать PEAR.
    • НЛО прилетело и опубликовало эту надпись здесь
      • 0
        Примеры там есть. Изначально там в ядре около 10 модулей на Сигале написано. Туториалы и доки, да, есть затыки. Но учитывая, что на нем уже много чего написано, хватает примеров. А учитывая то, что Сигал юзает PEAR, то библиотечные функции там общие.
        • НЛО прилетело и опубликовало эту надпись здесь
  • +3
    В зенде есть минус, который достаточно трудно лечится ввиду концепции системы - использование схемы "один-класс-на-файл" и в результате - более 100-150 require-ных файлов во время работы. Из которых обычно процентов 90% вообще каждый запрос (!) таскаются. Даже при использовании opcode-кеширования на это уходит ~0.02сек на celeron 2.4ghz. На в-два-раза-более-шустром компе двухкратного преимущества в скорости при этом не будет ;). Даже отключением проверки изменений файлов в opcode-кешере проблема не решается.

    Как вариант - для production собирать "особенный" билд проекта, впихнув в один файл, например, все зендовские классы которые грузятся каждый запрос. У меня получается 4.5-мб файлик с 12 тысячами строк %). При этом первый его require выходит в те же 0.02сек, а вот последующие (уже собранный из opcode-кеша) - 0.003сек, что уже вовсе не является критичным.

    При создании такого зендовского файлика-библиотеки нельзя запихать туда весь зенд - иначе размер файла будет более 80мб и работать с ним нереально. При этом нужно высматривать процент загрузок на запрос, просматривая данные о кешах apd, xcache и тп. Вырезать из всех зендовских файлов комментарии и require_once (там их полно, особенно - на эксепшены). При определённом стечении обстоятельств - работает %).

    Надо попробовать написать нормальный инструмент. Вообще хоть кто-нибудь сталкивался с проблемой скорости при использовании zend framework?
    • НЛО прилетело и опубликовало эту надпись здесь
      • 0
        они игнорируются интерпретатором ещё на стадии парсинга - поэтому влияние настолько мало, что лучше о нём и не думать :). Просто если что-то генерировать автоматически - то лучше обрезать всё что не нужно.
        • 0
          А если это настолько мало умножить на... скажем 1000(10000?) запросов в секунду? Просто, я видел презентацию Ольшанецкого по оптимизации, и там насчет этого было посоветовано вырезать комментарии. Тем более, в некоторых Zend-овских файлах программного кода 5 строк, а зато комментов аж под 20!
          • 0
            если используется кешер байткода (APC, Xcache, etc.) - то он хранит байткод в котором УЖЕ нет комментариев.
      • 0
        комментарии больше влияют на читабельность кода. если в файле строк кода очень много, легко запутаться. понятно что если критичен размер файла (тот же javascript код) то его лучше оптимизировать программой. уберет лишние символы пробелов, перевода строк и табуляции и уберет комментарии.
      • 0
        Я проводил тест для PHP4 и получил разницу во времени исполнения большого скрипта с комментариями и без около 15%. То-есть разница есть, и из тех скриптов, которые будут работать на production-сурверах лучше автоматически вычищать все комментарии и пустые строки.
        • 0
          если использовать какой-нить APC, то коменты не роляют.
    • 0
      да, сталкивался

      я активно использовался __autoload вместе с Zend::loadClass ещё на старой версии, и ещё много неособо приятных вещей, когда занялся тестами скорости по началу был в диком ужасе )

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

      кстати в последних релизах разработчики зенда и сами начали коечего кешировать,
      теже схемы базы в Zend_Db, из ваших слов я понял вам пришлось делать это руками
      • 0
        зенд зендом, но я добрую половину переписал/дописал. ООП сила, брат.
        тем не менее, очень радуюсь когда что-то такое же как и самописное имплементируют зендовцы :). Я с ним дружу с 0.4 версии и уже неоднократно это было. Только что глянул в Zend_Db, действительно кеш метадаты там теперь есть. Почти зеркальная копия моего :-P
        • 0
          я тоже давно использую фреймворк ) практически с первых релизов, очень интересно было наблюдать за его эволюцией, порою многие вещи люди просто кординально переделывали

          например я только сделал реализацию валидаторов под себя, в ледующем релизе появились очень приятные изменения в этом пакете )

          а ООП да, сила, но как любая сила, должна использоватся с умом =)
    • 0
      Кстати, а вышеупомянутый Seagull Framework умеет автоматически собирать все нужные библиотеки в единый файл. Может и в Зенде до такого додумаются...
    • 0
      Такая схема уже давно реализована во многих проектах. Взгляните на Doctrine или TYPO3.
      • 0
        Смысл не в том, что собрать тяжело, а в том, что не все собирать надо.
        • 0
          угу. если собрать всё - в скорости почти 100%-но будет проигрыш. А в памяти - вообще полный ПЭ
    • 0
      да, меня самого удручает скорость работы ZF. Решение проблемы тут: Сборка инклюдов в один файл
  • 0
    А возможно ли юзать шаблониаторы, к примеру SMARTY ?
    • +1
      Да, разработчики зенд много пишут о том как использовать другие шаблонизаторы в представлениях
      суть решения в разработке своего обёртки под smarty, реализующей интерфейс Zend_View

      почтитать можно
      devzone и документация к зенду
      • +1
        черт, первый :)
        • 0
          :D
      • 0
        Спасибо :)
    • 0
      да, легко.
      нужно разве что будет написать свой класс View, имплементируя методы Zend_View_Interface. В мануале зенда об этом рассказано.
  • 0
    Лучшее сравнение фрэймворков из тех что я видел

    http://video.google.com/videoplay?docid=6297126166376226181
    Сравниваются:
    - J2EE (Java)
    - Ruby on Rails (Rubin)
    - Zope/Plone (Python)
    - Turbogears (Python)
    - Django (Python)
    Извините если баян
    • 0
      ему 100 лет. Если что.
  • 0
    Спасибо за перевод!
    Неплохое руководство-описание ZendFramework (и не только) можно найти еще тут
  • 0
    .. "не для кого не являются секртеом" .. секртеом - секретом // опечатка
    • 0
      Спасибо, исправил.
      • 0
        Надо посмотреть.
  • 0
    и во многих отношениях постепенно становитс лучше.

    оперчаточка, становится
  • +1
    хммм, все эти тесты, все эти выиграшы в секундах... кому они нужны? главное чтобы человеку было удобно работать в фреймворке. я очень нехотя и со скрипом перелез на rebyonrails, но когда немного в всём разобрался был счастлив до безумия, и многие вещи поражают до сих пор, и плагины появляются очень быстро, вобщем я сильно уменьшил время на разработку какого либо приложения. теперь когда я проно уселся на рельсах, появилось очень много, черезвычайно хороших фреймворков для php. вывод только один, кто кодит на пхп, тому нет смысла перелезать на руби, это займёто больше времени, проще разобраться в фреймворке...

    на а как сильно эти фреймворки грузят проц.... с каждым годом процесорные мощности всё больше, хостинг всё дешевле, да и вообще вы, что яндексы собрались писать?)
    • 0
      стартапы стартапы стартапы :]
    • 0
      вы просто не писали HA-приложения. А это - большие бабки и высокий порог входа для стартапов (боже упаси писать их на PHP и на ROR... :))
      • 0
        ну и не пишите...тут обсуждение людей другой категории, которые не пишут такие приложения... но всегда найдётся очень крутой человек, влезет и скажет, что всё это отстой.
        • 0
          а с какой стати вы высказываетесь от имени всех?
  • 0
    Приведенные примеры были протестирован на Zend Framework версии 1.0.0. Вероятнее всего, они так же будут работать с более поздними версиями, но не с более ранние.


    Вероятнее всего -> Скорее всего
    так же — просто выкинуть!
    с более -> и с более
    ранние -> ранними
  • НЛО прилетело и опубликовало эту надпись здесь
    • 0
      согласен
  • НЛО прилетело и опубликовало эту надпись здесь
  • 0
    Вероятнее всего, они так же будут работать с более поздними версиями, но не с более ранние.

    Правильно, кажется, ранними
  • 0
    Обязательно сегодня вечером почитаю, рад, что наконец кто-то заговорил про MVC.
  • 0
    огромное спасибо за статью. давно искал
  • 0
    Будет ли во второй части рассказано про роутинг внутри приложения?
    • 0
      Про устройство роутинга запросов в общих чертах рассказано в первой части. Во второй будет рассказано о моделях и работе с БД.
  • НЛО прилетело и опубликовало эту надпись здесь
  • +1
    Хоть я недолюбливаю PHP, но аффтару Респект!
    Сразу предложу материал для дальнейшего развития фреймворка:

    1. Желательно вынести конфигурацию сайта и page-flow за пределы кода в конфигурационный файл и немного отделить декларативную часть от имплементации.
    2. Весчь, которой не хватает в Struts и которая есть в JSF: events. Отличаются от экшнов тем, что только меняют состояние активной страницы, но при этом не осуществляют перехода на другую и не делают никаких значимых действий. Например если у меня на странице есть компонент типа дерева, с динамической подгрузкой scopes, открытие юзером поддерева делает рефреш страницы и посылает контроллеру событие. Контроллер вытаскивает из модели необходимые для поддерева данные и страница рендерится заново с новыми изменениями.
    3. Помимо View ввести понятие компонента, который имеет свой рендерер, контроллер и модель, и преставляет собой отдельный (reusable) элемент интерфейса (но более сложный, чем стандартные html). Одни и те же компоненты могут использоваться в различных Views. Экшн-контроллер может принимать события от компонента, а также ессно обмениваться с ним данными. Изменение состояния компонента может осуществляться либо через JavaScript, либо через refresh страницы, либо используя Ajax.
    4. Ajax-интеграция для компонентов.
    5. Библиотека стандартных компонентов (элементов интерфейса) была бы только плюсом.

    Хороший пример подобной библиотеки лежит здесь: http://myfaces.apache.org/tomahawk/
    • +1
      1. очень легко реализуется на Zend_Config. Поддерживаются namespaces
      2,3,4. Не очень хороший пример насчет событий, т.к. я бы, например, использовал AJAX :) А вообще событийная модель пока слишком "высокая" фича для ZF. Не все сразу, слишком высокие требования к коду. Вот только сейчас до composite view добрались.
      5. Уже есть - Zend_View_Helper
    • 0
      Вот-вот. Визуальные компоненты нужны... с event'ами...
      В разработке "личного фреймворка" этим сейчас занимаюсь.

      Жалко лишь что box-модель в html/css такая уродливая... чтобы боксы вели себя так, как принято в нормальных программных интерфейсных библиотеках - нужно извращатся дай боже.
  • +1
    Я сейчас участвую в разработке новой версии одного из самых посещаемых в Германии порталов. Решили использовать Зенд Фреймворк, расширив его основательно. В ходе разработки все больше родных библиотек Зенда выпадают из-за того, что содержат много лишнего ненужного оверхеда или попросту не подходят для решения конкретных задач.

    немного оффтоп: К нам недавно приезжали из Зенда, рекламировать свои продукты. кроме всего прочего всучили альфа версию Зенд Студии Неон, которая основывается на Еклипсе теперь. Пока ничего конкретного сказать не могу - много удобных вещей, но и зависла уже пару раз. При использовании Зенд Платформы мне кажется незаменима.
    • 0
      Любой фреймворк это основа, и при постоянном развитии его постепенная замена своим кодом неизбежна. Чем лучше фреймворк, тем дольше он будет удовлетворять потребностям, и тем меньше будет "сковывать" разработчиков. Узкозаточенный код (с малым количеством абстракций) всегда работает лучше гибкого. Он правится хуже, и пишется дольше.
      Вы согласны?
      • 0
        абсолютно. только такое чувство, что в конце концов останется всего пара разрозненных библиотек, которые можно было использовать и из PEAR'a просто :)
        • 0
          Неее, в конце останется изменённый http-сервер ;)
    • 0
      Очень интересно было бы увидеть обзор со скринщотами.
      • 0
        я вот думаю, если я его расшарю меня расстреляют :)?
        • 0
          Если не узнают, кто расшарил, то не расстреляют ;)
  • 0
    вообще есть куча проблем/вопросов по ZF, где их лучше всего задать ?

    может кто поделится кодом "приложения" на ZF ? Жутко интересно как другие реализовывают, например, авторизацию...
    • 0
      Выше в камментариях есть два примера. На самом деле в ZF вникнуть и освоится действительно не очень просто. Да можно прочитать этот tutorial, но дальше снова дело идет не очень хорошо. К примеру чтобы написать обработку несуществующего контроллера и выдать страницу вроде "404 Извините, неверный урл." нужно обрабатывать исключения. Чтобы сделать урлы не /контроллер/действие/параметры, а просто /действие/параметры нужно серьезно ковырятся в роутере. И так все время идет наследование зендовских классов под свои задачи. В итоге получается не слишком удобная разработка, пока не образуется некая собсвенная надстройка над ZF. И производительность от всего этого тоже немного страдает. В тот же cakephp гараздо проще войти, может быть он не такой гибкий, но он более интуитивно понятный. Или в zf паттерны более привычные например java-разработчикам? Может быть просто дело привычки?
  • +1
    Неплохо перевели. Только жалко, блин, я этот туториал я уже на английском изучил.

    Можно и я тоже ляпну свое?

    Вот это функция позволяет не вызывать постоянно Zend_Loader

    function __autoload($class) {
    Zend_Loader::autoload($class);
    }


    Прописываем ее в index.php, а потом можно сразу создавать классы, не подключая их.
    • 0
      доброе утро :)

      Zend_Loader::registerAutoload();


      :-) будьте внимательны
      • 0
        Доброe. :)

        У меня и так работает.
        • 0
          а зачем вы ZendFramework используете? :)
          • 0
            Я не вижу разницы между двумя методами(класса), если результат и цель одни и те же.
            • 0
              а если посмотреть чуть глубже и сообразить, что если в версии выше 1.0 они что-то переделают, то и способ подставки в autoload тоже переделают. А вам придётся постоянно дублировать их функциональность. Я уже не говорю о стандартизации и удобном понимании вашего кода другими разработчиками знакомыми с ZendFramework :).
        • 0
          У меня это работало до той поры пока я не начал использовать модульную структуру проекта, у меня __autoload почему-то сlass News_IndexController искал в дефолтном каталоге а не в каталоге news. Zend_Loader::registerAutoload(); - решило проблему
    • 0
      да, кстати. Работая с Зендом всегда нужно иметь ввиду - если возникает какая-то идея по поводу реализации какой-то фичи, то в 90% случаев это уже есть в зенде либо скоро будет. По крайней мере ленится и периодически заглядывать в сёрсы зенды (поучится хотя бы :)) явно не нужно.
      • 0
        т.е. ленится не нужно :Р
  • 0
    Огромное спасибо за статью. Как раз собирался найти что-нибудь подобное по ZF, и тут как гром с неба! :)
  • 0
    Вообще Zend_Db_Table очень удобная вещь. Настраивается намного легче чем Hibernate. Для постгрес добавить sequence только одна строка. Вот только не знаю, что из них быстрее работает. Никто не делал тестов?

    И еще, что выступает в роли pconnect-a, т.е пула?
    • 0
      быстрее чем что? пула в зенде своего нет и не будет ибо это не осуществимо :)
      он может-таки использовать pconnect в mysql библиотеке, в pdo и тп. Через driver_options в конфиге у фабрики Zend_Db
  • +1
    Я сейчас нахожусь в поиске простого и гибкого фреймворка для создания несложных сайтов с интуитивной и простой админкой, где использование Друпала не совсем оправдано.

    Zend Framework отталкивает своим размером, и "многословностью", столь любимой некоторыми ярыми приверженцами ООП (я говорю про названия типа Zend_Framework_My_Super_Mega_Class_For_Validation, 1 file = 1 class, размером в 15 мегов!) как-то все это тяжело воспринять после милого сердцу Drupal'a..

    Посмотрел CakePHP, оттолкнул ORM и automagic, гибкости не хватило на примитивнейший пример где в таблицу для many-to-many связи надо было воткнуть дополнительное поле - для этого пришлось копаться и мучаться.(Было это полгода назад примерно, может сейчас cakePHP такое и умеет, но пример характерный) Вообще я ORM не верю, даже Django имеет какие-то "детские" проблемы типа не поддерживаемой агрегации. Я конечно понимаю что все можно "дописать" - но мне не нравится ощущение, что какой-то большой кусок кода не справляется с такой простой задачей и лежит мертвым грузом в моем приложении.

    Посмотрел CodeIgniter - понравилось больше, работает очень быстро, есть scaffolding и нет orm, подключает только те файлы, которые нужны, простые вещи не усложняет практически. ActiveRecord мне противен, но пусть уж будет, можно забить и юзать старый добрый sql везде. Насторожило то, что фреймворк попал под владение Ellis Labs, и судя по всему это несколько затормозило разработку - это повело за собой почкование Kohana, based on CI платформы, разработкой которого вроде как должно заниматься коммунити. Из-за некоторых непонятных и неоднозначных вещей, которые мне открылись ( http://codeigniter.com/forums/viewthread… ) - я пожалуй и от этого фреймворка откажусь.

    Вчера посмотрел Symfony - понравился yaml, очень понравилась уже готовая система валидации, но не понравились вещи типа усложненного создания проекта, массивности, низкой скорости (хотя автору в вышеупомянутой статье про скорость системы склонен верить)

    Короче хотелось чего-то простого, элегантного и мощного, надеюсь на что-то, но, видимо, буду дописывать свое, своровав идеи с валидацией у CI и symfony... надо Seagull ради интереса еще поглядеть
    • 0
      Хоть этот коммент писался год назад, но для меня он крайне актуален сейчас.

      На чем вы остановили свой выбор по фреймворкам? Что посоветуете?

      Я пока присмотрелся к Limb3 (отличная документация + красивое использование шаблонов проектирования).
      Что вы думаете по поводу Limb3?

  • 0
    Про Cake не совсем понял. Подробнее не объясните?
  • 0
    когда дошел о того места где надо добавить

    $album = new Album();
    $this->view->albums = $album->fetchAll();

    вылезает ошибка

    Fatal error: Uncaught exception 'Zend_Db_Adapter_Exception' with message 'The PDO extension is required for this adapter but not loaded' in z:\home\zf\www\zf-tutorial\library\Zend\Db\Adapter\Pdo\Abstract.php:95 Stack trace: #0 z:\home\zf\www\zf-tutorial\library\Zend\Db\Adapter\Abstract.php(246): Zend_Db_Adapter_Pdo_Abstract->_connect() #1 z:\home\zf\www\zf-tutorial\library\Zend\Db\Adapter\Pdo\Abstract.php(206): Zend_Db_Adapter_Abstract->query('DESCRIBE `album...', Array) #2 z:\home\zf\www\zf-tutorial\library\Zend\Db\Adapter\Pdo\Mysql.php(88): Zend_Db_Adapter_Pdo_Abstract->query('DESCRIBE `album...') #3 z:\home\zf\www\zf-tutorial\library\Zend\Db\Table\Abstract.php(595): Zend_Db_Adapter_Pdo_Mysql->describeTable('album', NULL) #4 z:\home\zf\www\zf-tutorial\library\Zend\Db\Table\Abstract.php(528): Zend_Db_Table_Abstract->_setupMetadata() #5 z:\home\zf\www\zf-tutorial\library\Zend\Db\Table\Abstract.php(264): Zend_Db_Table_Abstract->_setup() #6 z:\home\zf\www\zf-tutorial\application\controllers\IndexController.php(12): Zend_Db_ in z:\home\zf\www\zf-tutorial\library\Zend\Db\Adapter\Pdo\Abstract.php on line 95
    • НЛО прилетело и опубликовало эту надпись здесь
    • +1
      Та же ерунда ( Что делать?
      • 0
        Пол ночи сидел, но разобрался. ДУмаю кому-нибудь пригодится знать, что всё дело в версии ПХП, а точнее в его комплектации. Просто поставьте версию поновее и всё будет ок
      • 0
        Я забил....и перешел на СакеРНР.....
        только не надо учить Саке используя материалы с Хабра.....т.к. они только отпугивают чеорвека от Саке.
        лучше учите с Cakephp
        • +1
          я решил остаться на Зенде. Пока всё устраивает. Этого материала очень хватило для начала. Уже пишу цмску, на пути много преград, но справлюсь =)

          Спасибо за статью =)
          • 0
            спасибо. но я уже разобрался. надо раскомментировать расширение PDO
    • 0
      Поставить расширение PDO для PHP =)
      • 0
        Спасибо. Но с этой проблемо я давно уже спавился. а с Зенда отазался.
    • 0
      в коде примера ошибка:

      set_include_path('.'.PATH_SEPARATOR. './library'
      заменить на
      set_include_path('.'.PATH_SEPARATOR. './application/library'

  • 0
    Спасибо за перевод, интересно!

    Опечатка:
    >>закрытие блока PHP кода ?<
    &lt; меняем на &gt;
    • 0
      Опечатку исправил, спасибо.
  • 0
    >> У Zend Framework следующие требования:
    >> PHP версии 5.1.4 или выше;
    >> Веб-сервер, поддерживающий mod_rewrite.

    Роб, ты неправ...
    Mod_rewrite не является необходимым, он лишь добавляет удобства
  • 0
    если уж использовать PHP в качестве html-шаблонизатора..( то лучшие вместо

    render('header.phtml'); ?>
    escape($this->title); ?>
    render('footer.phtml'); ?>

    использовать более компактные конструкции языка:

    render('header.phtml') ?>
    escape($this->title) ?>
    render('footer.phtml') ?>
  • 0
    Помогите пожалуйста нубу.

    Вот это:
    render('header.phtml'); ?>
    escape($this->title); ?>
    render('footer.phtml'); ?>

    повторяется в 4 файлах. Как можно это сократить до одного файла?

    И в каком файле вообще собирать все части сайта?

    Допустим у меня есть блок авторизации и блок новостей. Соответственно в виде авторизации я хочу добавить только авторизацию, а в новостях новости без всяких " ..."

    Затем это всё скрепить воедино. Где?
    • 0
      В общем вопрос в том как сделать общий каркас для всех страниц и чтобы в него уже вставлять отдельные визуалные компоненты?
      • 0
        И вообще я немного не понял. В примере рассмотрен случай, когда у нас на странице страница выполняющая конкретное действие. Добавить/удалить/обновить/посмотреть. А как быть с теми модулями, которые должны присутствовать на всех страницах? Причём эти модули должны тоже выполнять какой-то php-код и тупо пихать в каждый Вид не выгодно.

        Прочитав продолжение ответ так и не нашёл ( помогите пожалуйста разобраться. Впринципе все мои три коммента об одном и том же
    • 0
      Я использовал вот этот класс: http://my.opera.com/zomg/blog/2007/09/14…
      "Каркасы" называются обычно Layout-ами, файлами задающими общий вид страницы, в них можно воткнуть несколько "модулей", оформленных в виде хелперов. Есть и другие способы ( http://akrabat.com/2007/07/11/two-step-v… ), но я пока не заморачивался.
  • 0
    У вас неправильно отформатирована структура каталогов.
    library/ и public/ должны быть на одном уровне с application/.
    • 0
      в рот мне ноги, все комменты засрали холиварами и прочим говном, а я полночи искал правду… Структуру подсмотрел в оригинале статьи, и только утром нашел коммент, которого искал полночи =))

      Прошу прощения, что некрокомменчу =)
  • 0
    Это не единственная ошибка в статье. Также после создания контроллера предлагается протестировать задавая адреса http://localhost/zf-tutorial/ и.т.д в оригинале же написано:
    We have now set up the four actions that we want to use. They won’t work yet until we set up
    the views. То есть пока не будут готовы views эти адреса работать не будут.
  • 0
    Спасибо за статью, получилось конечно все не сразу, но эта статья очень помогла мне)))
    больше всего мучался с поддержкой mysql, так что если у кого из новичков, как я, возникнут вопросы на эту тему -обращайтесь..)
  • 0
    Исправь структуру каталога. Там выходит что все находится в папка application. application, library, public - должны находится в одной директории. Я понимаю, что каждый пишет как ему удобно. Но так, как ты пишешь начальным пользователям, которые явно будут пользоватся мануалом на офф сайте, то ИМХО лучше придерживаться структуры, которую дают там.
    • 0
      не заметил, что указали ошибку выше(
  • 0
    Ошибка: «Приведенные примеры были протестирован» — надо — протестированы.
    • 0
      Fixed.
      • 0
        Спасибо Вам, отличная статья для тех, кому не хватает знания английского для чтения оригинала и quickstart-а (для меня в частности :)).
  • 0
    Статья уже сильно устарела. Очень хотелось бы увидеть какой нибудь пример приложения, разработанный на зенде > 1.9.

Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.