Автор: Rob Allen,
Также доступна устаревшая версия руководства, ориентированная на старые версии Zend Framework.

Это руководство предназначено для введения в использование Zend Framework для создания простых приложений с использованием БД с использованием парадигмы . Оно было переписано для версии фреймворка 1.8 и использует все преимущества скриптов командной строки Zend_Tool и Zend_Application для бутстраппинга. Используются другие компоненты, включая Zend_Controller, Zend_View, Zend_Db_Table и Zend_Form.

Замечание: Это руководство было тестировано на Zend Framework версии 1.10. Есть хорошие шансы, что оно будет работать с более поздними версиями ветки 1.*, но оно гарантированно не будет работать с версиями ранее 1.10.
Если вы получаете ошибки 404 когда открываете любую страницу, кроме главной, убедитесь, что директива AllowOverride в конфигурационном файле Apache установлена в значение All и включено расширение mod_rewrite.
Если вы развёртываете “пользовательский” сайт (например, http://localhost/~rob), вам необходимо использовать строку RewriteBase в файле .htaccess, например: RewriteBase /~rob/zf-tutorial/public/.

Исходный код

Исходный код руководства доступен в виде .

Требования

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

  • PHP 5.2.4 (или выше)
  • Веб-сервер с поддержкой mod_rewrite или аналогичного функционала.

Условности

Предполагается, что у вас запущен PHP 5.2.4 с веб-сервером Apache. Ваш Apache должен иметь установленное и настроенное расширение mod_rewrite.
Также вы должны быть уверены, что Apache настроен для поддержки файлов .htaccess. Обычно для этого достаточно изменить параметр:
AllowOverride None
на
AllowOverride All
в вашем файле httpd.conf. За деталями обратитесь к документации веб-сервера. Вам не будет доступна ни одна страница на вашем сайте, кроме главной, если mod_rewrite и .htaccess не будут корректно настроены.

Получение Zend Framework

Загрузить Zend Framework вы можете в виде архивов .zip и .tar.gz.

Настройка Zend_Tool

Zend_Tool для Windows

  • Создайте новую директорию в Program Files и назовите её ZendFrameworkCli
  • Откройте скачанный архив.
  • Скопируйте папки bin и library из архива в папку C:\Program Files\ZendFrameworkCli. Папка должна иметь две подпапки: bin и library.
  • Добавьте директорию bin в переменную окружения “Path”:
    • Откройте окно “Система” в панели управления
    • Выберите вкладку дополнительно нажмите на кнопку “Переменные среды”
    • В списке “Системные переменные” найдите переменную “Path” и дважды кликните по ней.
    • Добавьте “;C:\Program Files\ZendFrameworkCli\bin” в конец поля воода и нажмите “OK”. (точка с запятой обязательны!)
    • Перезагрузитесь

Zend_Tool для OS X (Аналогично для Linux)

  • Распакуйте скачанный архив,, ZendFramework-1.8.0-minimal.zip в вашу папку загрузок и откройте его.
  • Скопируйте содержимое в /usr/local/ZendFrameworkCli, выполнив в консоли команду:
    sudo cp -r ~/Downloads/ZendFramework-1.8.0-minimal /usr/local/ZendFrameworkCli
  • Отредактируйте ваш bash-профиль для создания alias’а
    • В консоли наберите: open ~/.bash_profile
    • В конец файла добавьте: alias zf=/usr/local/ZendFrameworkCli/bin/zf.sh
    • Сохраните и закройте текстовый редактор
    • Закройте терминал

Тестирование Zend_Tool

Вы можете проверить, корректно ли установлен Zend_Tool, набрав в консоли (командной строке) следующее:

1
zf show version

Если всё работает, вы увидите следующее:

1
Zend Framework Version: 1.8.0

Если нет, проверьте, верно ли вы указали путь и существует ли директория bin в каталоге ZendFrameworkCli. Если Zend_Tool работает, вы можете увидеть все доступные команды при помощи “zf –help”

Что мы будем делать?

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

Главная страница Будет выводить список альбомов и ссылки для редактирования и удаления их. Также будет доступна ссылка для добавления нового альбома
Добавление нового альбома На странице будет отображаться форма для добавления нового альбома
Редактирование альбома Форма для редактирования альбома
Удаление альбома Страница будет запрашивать подтверждение на удаление альбома, с последующим удалением

Также нам понадобится хранилище наших данных в БД. Создадим таблицу со следующими полями:

Название поля Тип Null? Дополнительно
id integer No Primary key, auto increment
artist varchar(100) No
title varchar(100) No

Начинаем наше приложение

Пришло время начать разработку. Где возможно, мы будем использовать утилиту командной строки ZF, т.к. это значительно экономит наше время и силы. Первая задача – создать скелет проекта, состоящий из файлов и каталогов.
Откройте консоль или командную строку и измените каталог на корневой вашего веб-сервера, используя команду cd. Убедитесь, что у вас достаточно прав для создания файлов в этом каталоге. Введите:

1
zf create project zf-tutorial

Утилита ZF создаст директорию с именем zf-tutorial и наполнит её рекомендуемой структурой директорий. Эта структура предполагает, что конфигурация Apache позволяет вам хранить многие файлы вне публичного каталога сервера. Вы должны увидеть следующие файлы и каталоги:
Структура каталогов Zend Framework
(здесь не отображён скрытый файл .htaccess в каталоге public)
В каталоге /application расположен исходный код вашего веб-сайта. Как вы можете наблюдать, мы имеем раздельные каталоги для файлов моделей, вида и контроллеров вашего приложения. Каталог /public является публично-доступным корневым каталогом сайта, который будет открываться по URL http://localhost/zf-tutorial/public/. Таким образом, большая часть файлов вашего приложения не будет доступна напрямую через Apache, что обеспечивает большую безопасность.
Замечание: Для живого веб-сайта вам надо будет создать VirtualHost и направить DocumentRoot напрямую на каталог /public. Например, вы можете создать VirtualHost с именем zf-tutorial.localhost, и он будет выглядеть похоже на это:

1
2
3
4
5
6
7
<VirtualHost *:80>
    ServerName zf-tutorial.localhost
    DocumentRoot /var/www/html/z-ftutorial/public
    <Directory "/var/www/html/zf-tutorial/public">
        AllowOverride All
    </Directory>
</VirtualHost>

Сайт будет доступен по URL http://zf-tutorial.localhost/ (для этого вам следует обновить файл /etc/hosts или c:\windows\system32\drivers\etc\hosts, направив zf-tutorial.localhost на 127.0.0.1). Мы не делаем этого в нашем руководстве потому, что это так же просто, как и использование подкаталога для тестирования.
Изображения, JavaScript и CSS-файлы храните в раздельных директориях внутри /public. Скачанный Zend Framework будет расположен в директории /library. Если вам понадобится использовать другие библиотеки, вы можете также разместить их там.
Скопируйте директорию /library/Zend из скачанного архива в ваш zf-tutorial/library/ таким образом, чтобы ваш zf-tutorial/library/ имел подкаталог Zend/.
Теперь вы можете проверить, всё ли в порядке, открыв URL http://localhost/zftutorial/public. Вы должны увидеть что-то вроде этого:
Главная страница Zend Framework

Бутстраппинг

Контроллер Zend Framework’а использует паттерн проектирования Front Controller и направляет все запросы через один файл – index.php. Это гарантирует, что окружение корректно настроено для запуска приложения (процесс также известен как бутстраппинг). Мы используем файл .htaccess в каталоге /zf-tutorial/public, который был сгенерирован при помощи Zend_Tool. Он направляет все запросы на файл index.php, который, в свою очередь, тоже сгенерирован Zend_Tool.
Файл index.php является стартовым пунктом в нашем приложении и используется для создания экземпляра Zend_Application, который, в свою очередь, инициализирует наше приложение и запускает его. Файл также определяет две константы: APPLICATION_PATH и APPLICATION_ENV, которые определяют путь к директории application/ и режим работы приложения соответственно. Режим указывается в .htaccess и по умолчанию имеет значение development.
Компонент Zend_Application используется для запуска приложения и настраивается при помощи конфигурационного файла: application/config/application.ini. Этот файл также генерируется автоматически.
Класс бутстраппинга наследует Zend_Application_Bootstrap_Bootstrap и расположен в application/Bootstrap.php. Он может использоваться для выполнения любого специфичного кода при запуске приложения.
Файл application.ini, который хранится в каталоге application/configs, загружается с помощью компонента Zend_Config_Ini. В этом файле допустимо использование наследования секций:

1
[staging : production]

Это значит, что секция staging наследует все параметры секции production. Константа APPLICATION_ENV определяет, какая секция будет загружена. Во время разработки лучше всего использовать секцию development, а для уже запущенного приложения – секцию production.

Редактирование файла application.ini

Несмотря на то, что Zend_Tool создаёт работоспособный конфигурационный файл, мы можем добавить в наше приложение специфичные настройки. Отредактируйте application/configs/application.ini и добавьте:

1
phpSettings.date.timezone = "Europe/Moscow"

Добавить это надо после всех значений phpSettings в секцию [production]. Здесь вам следует написать свой часовой пояс. Теперь мы готовы к написанию специфичного кода нашего приложения.

Специфичный код приложения

Прежде чем мы будем настраивать наши файлы, важно понять, как в Zend Framework организованы страницы. Каждая страница приложения является Действием (action), и действия сгруппированы в Контроллеры (controllers). Для URL формата http://localhost/zf-tutorial/public/news/view будет использоваться контроллер News и действие view. Это позволяет группировать схожие действия по смыслу. Например, контроллер news имеет действия list, archived и view. MVC в Zend Framework поддерживает модули для группировки контроллеров вместе, но это приложение не настолько большое, чтобы беспокоиться об этом.
Также следует заметить, что если имя контроллера или действия не указано, используется имя index. Таким образом, URL http://localhost/zf-tutorial/public/ выполнит действие index контроллера index.
Так как это базовое руководство, мы не будем осваивать “продвинутые” вещи, наподобие аутентификации. Об этом написано (или читайте об этом в книге ).
Мы имеем четыре страницы для управления альбомами, мы сгруппируем их в один контроллер и четыре действия. Мы будем использовать контроллер по умолчанию и четыре действия:

Страница Controller Action
Главная страница index index
Добавление нового альбома index add
Редактирование альбома index edit
Удаление альбома index delete

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

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

Теперь мы готовы к настройке нашего контроллера. В Zend Framework контроллер это класс, который должен называться {Controller name}Controller. Заметьте, что {Controller name} должен начинаться с заглавной буквы. Файл, который будет содержать этот класс, должен быть назван {Controller name}Controller.php и распологаться в директории application/controllers. Каждое действие – это публичный метод в классе контроллера с именем {action name}Action. В этом случае {action name} должен начинаться с маленькой буквы, и все последующие буквы тоже должны быть в нижнем регистре. Смешанный регистр символов в именах контроллеров и действий разрешён, но он обрабатывается по специальным правилам, которые вам следует понять, прежде чем их использовать. В первую очередь, просмотрите документацию.
Наш класс контроллера называется IndexController, который определён в application/controllers/IndexController.php и был автоматически сгенерирован при помощи Zend_Tool. Нам надо лишь добавить дополнительные действия.
Добавление дополнительных действий контроллера производится при помощи утилиты командной строки zf. Откройте командную строку и измените директорию на ваш каталог zf-tutorial/. После выполните следующие команды:

1
2
3
zf create action add index
zf create action edit index
zf create action delete index

Эти команды создают три метода: addAction, editAction, deleteAction в IndexController и соответствующие им скрипты вида, которые нам понадобятся позже. Сейчас мы имеем четыре настроеных и готовых к использованию действия.
URL’ы действий следующие:

URL Класс и метод
http://localhost/zf-tutorial/public IndexController::indexAction()
http://localhost/zf-tutorial/public/index/add IndexController::addAction()
http://localhost/zf-tutorial/public/index/edit IndexController::editAction()
http://localhost/zf-tutorial/public/index/delete IndexController::deleteAction()

Вы можете протестировать их и должны увидеть следующую надпись:

1
View script for controller index and script/action name add

Замечание: Если вы получаете ошибку 404, значит ваш Apache или модуль mod_rewrite не настроен должным образом, или параметр AllowOverride в вашем Apache не позволяет использовать .htaccess в каталоге public/.

База данных

Сейчас мы имеем скелет приложения с методами действий контроллера и файлы вида, самое время взглянуть на секцию “модель” нашего приложения. Запомните, что модель содержит код ядра нашего приложения и, в нашем случае, код взаимодействия с БД. Мы будем использовать класс Zend_Db_Table, который используется для поиска, вставки, обновления и удаления строк из БД.

Конфигурирование БД

Для использования Zend_Db_Table нам необходимо сообщить с какой БД мы будем работать, имя пользователя и пароль. Чтобы не прописывать это жёстко в нашем приложении мы будем использовать файл конфигурации для хранения этой информации. Компонент Zend_Application имеет ресурс для работы с БД, поэтому нам достаточно лишь указать данные в файле configs/application.ini.
Откройте файл configs/application.ini и добавить следующие строки в конец секции [production] (т.е. перед секцией [staging]):

1
2
3
4
5
resources.db.adapter = PDO_MYSQL
resources.db.params.host = localhost
resources.db.params.username = rob
resources.db.params.password = 123456
resources.db.params.dbname = zf-tutorial

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

Создание таблицы БД

Как мы изначально планировали, будем использовать БД для хранения данных о наших альбомах. Я использую MySQL и соответствующее SQL-выражение для создания таблицы:

1
2
3
4
5
6
CREATE TABLE albums (
id INT(11) NOT NULL AUTO_INCREMENT,
artist VARCHAR(100) NOT NULL,
title VARCHAR(100) NOT NULL,
PRIMARY KEY (id)
);

Запустите это выражение в MySQL-клиенте (например, phpMyAdmin) или стандартной командной строке MySQL.

Вставка тестовых альбомов

Сейчас нам нужно вставить несколько строк в таблицу, чтобы мы могли видеть функциональность нашего приложения.
Я возьму несколько топовых CD из магазина Amazon UK. Запустите следующий код в вашем MySQL-клиенте:

1
2
3
4
5
6
7
INSERT INTO albums (artist, title)
VALUES
('Paolo Nutine', 'Sunny Side Up'),
('Florence + The Machine', 'Lungs'),
('Massive Attack', 'Heligoland'),
('Andre Rieu', 'Forever Vienna'),
('Sade', 'Soldier of Love');

Теперь у нас есть некоторые данные в БД и мы можем писать очень простые модели для них.

Модель

позволяет вам самим решить, как она должна работать. Есть много компонентов, которые вы можете использовать для этого по мере необходимости. Один подход заключается в том, чтобы представить каждую сущность в вашем приложении и использовать объекты-мапперы, чтобы извлечь или сохранить данные в БД. Этот подход описан в Zend Framework QuickStart здесь:
В этом руководстве мы будем создавать модели, наследующие Zend_Db_Table и использующие Zend_Db_Table_Row. Zend Framework предоставляет компонент Zend_Db_Table, который реализует паттерн проектирования для взаимодействия с данными в таблице БД. Имейте в виду, что паттерн Table Data Gateway может начать ограничивать вас при разработке больших систем. Также возникает соблазн оставить код доступа к БД в методах действий (action) контроллера как голый Zend_Db_Table.
Zend_Db_Table_Abstract – это абстрактный класс, на базе которого мы создаём наш класс для управления альбомами. Не имеет значения, как мы назовём наш класс, но разумно будет назвать его именем таблицы БД. Наш проект имеет загрузчик по умолчанию, который создаётся при помощи Zend_Application, который находит классы ресурсов модуля внутри указанного каталога. Для основных каталогов application/ мы используем префикс Application_.
Автозагрузчик ищет ресурсы в каталогах согласно следующей таблице:

Префикс Каталог
Form forms
Model models
Model_DbTable models/DbTable
Model_Mapper models/mappers
Plugin plugins
Service services
View_Filter view/filters
View_Helper view/helpers

Для работы с нашими альбомами мы создаём класс, наследующий Zend_Db_Table_Abstract с именем Application_Model_DbTable_Albums, размещаться он будет по следующему пути: applications/models/DbTable/Albums.php
Чтобы указать, какую таблицу БД следует использовать, используйте protected-свойство класса $_name, в котором должно храниться имя таблицы. Также Zend_Db_Table преполагает, что ваша таблица имеет auto-increment первичный ключ с именем id. Имя поля может быть изменено при необходимости.
Создайте файл и введите следующий код:
zf-tutorial/application/models/DbTable/Albums.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?php

class Application_Model_DbTable_Albums extends Zend_Db_Table_Abstract
{
    protected $_name = 'albums';

    public function getAlbum($id)
    {
        $id = (int)$id;
        $row = $this->fetchRow('id = ' . $id);
        if (!$row) {
            throw new Exception("Count not find row $id");
        }
        return $row->toArray();
    }

    public function addAlbum($artist, $title)
    {
        $data = (
            'artist' => $artist,
            'title' => $title,
        );
        $this->insert($data);
    }

    public function updateAlbum($id, $artist, $title)
    {
        $data = (
            'artist' => $artist,
            'title' => $title,
        );
        $this->update($data, 'id = '. (int)$id);
    }

    public function deleteAlbum($id)
    {
        $this->delete('id =' . (int)$id);
    }
}

Мы создаём четыре метода-помощника, которые будут использоваться в нашем приложении как интерфейс к таблице БД. getAlbum() достаёт из БД одну запись в виде массива, addAlbum создаёт новую запись в БД, updateAlbum() обновляет запись альбома и deleteAlbum() удаляет запись совсем. Код каждого из этих методов сам отлично объясняет себя. Также возможны связи таблиц и выбора связанных данных из БД, но в этом руководстве мы об этом говорить не будет.
Нам необходимо получить в контроллерах данные из моделей и получить скрипты вида для отображения их. Но, прежде чем мы это сделаем, нам необходимо понять как работает система отображения в Zend Framework.

Макеты и виды

Компонент вида Zend Framework, как и следовало ожидать, называется Zend_View. Он позволит нам отделить код отображения страницы от кода действий.
Базовое использование Zend_View такое:

1
2
3
$view = new Zend_View();
$view->setScriptPath('/path/to/scripts');
echo $view->render('script.php');

Очень легко писать этот код в каждом нашем действии, но повторение кода – не лучший подход. Мы будем инициализировать отображение по-другому и предоставлять доступ к объекту вида в каждом методе действия. Zend Framework предоставляет для этой цели помощник вида (Action Helper) под названием ViewRenderer. Он берёт на себя задачу инициализации вида, записывает его в свойство класса контроллера ($this->view) для использования его и выводит скрипт вида после выполнения действия.
Для вывода скриптов вида ViewRenderer настраивает Zend_View для поиска скриптов вида в каталоге “views/scripts/{controller name}” с расширением phtml. Таким образом, скрипт вида имеет путь “views/scripts/{controller name}/{action name}.phtml”, содержимое его передаётся в объект ответа для вывода на экран. Объект ответа (Response) используется для объединения вместе HTTP-заголовков, тела ответа и исключений, сгенерированных MVC-системой. Front Controller автоматически отправляет заголовки и тело ответа по завершении процесса диспатчинга.
Всё это настраивает для нас Zend_Tool, когда мы создаём проект и добавляем контроллеры и действия с использованием команд “zf create controller” и “zf create action”.

Общий HTML-код: Макеты

Очень быстро становится ясно, что некоторые части HTML-кода дублируются. Например, “шапка” и “подвал”, “сайдбар” или даже два. Это не новая проблема, и для её решения предназначен компонент Zend_Layout. Мы перемещаем “шапку”, “подвал” и другой код в скрипт вида макета (layout), и уже туда подключаем скрипт вида выполняемого действия.
По умолчанию наши макеты хранятся в каталоге application/layouts/. Также доступен ресурс для Zend_Application, который настраивает Zend_Layout. Мы используем Zend_Tool, чтобы создать скрипт вида макета и обновить application.ini для его применения. Откройте терминал или командную строку и введите следующую команду, находясь в корневом каталоге вашего проекта:

1
zf enable layout

Zend_Tool создал каталог application/layouts/scripts и поместил в него скрипт вида layout.phtml. Также был обновлён application.ini, в секцию [production] добавлена следующая строка:

1
resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts/"

В конце цикла диспатчинга, после выполнения действий контроллера, Zend_Layout выведет наш макет (layout). Zend_Tool создал очень простой файл макета, который только выводит нам содержимое скрипта вида выполняемого действия. Дополним его необходимым вебсайту HTML-кодом. Откройте layout.phtml и замените его код на следующий:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
$this->headMeta()->appendHttpEquiv('Content-Type', 'text/html;charset=utf-8');
$this->headTitle()->setSeparator(' - ');
$this->headTitle('Zend Framework Tutorial');
echo $this->doctype(); ?>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    <head>
        <?php echo $this->headMeta(); ?>
        <?php echo $this->headTitle(); ?>
    </head>
    <body>
        <div id="content">
            <h1><?php echo $this->escape($this->title); ?></h1>
            <?php echo $this->layout()->content; ?>
        </div>
    </body>
</html>

Файл макета содержит “внешний” HTML-код, который соответствует HTML-стандарту. Так как это нормальный PHP-файл, мы можем использовать в нём PHP, доступна переменная $this, которая содержит экземпляр объекта вида, который был создан во время бутстраппинга. Мы можем использовать его для передачи данных в скрипт вида и вызывать методы. Методы, известные как помощники вида (view helpers), возвращают строку, которую мы можем вывести.
В первую очередь, мы настраиваем некоторые помощники вида для head-секции веб-страницы и также для вывода корректного doctype. Внутри секции мы создаём div, содержащий <h1> заголовок страницы. Для получения скрипта вида выполняемого действия мы выводим содержимое placeholder’а с использованием помощника вида layout():

1
echo $this->layout()->content;

Это значит, что скрипт вида действия выполняется раньше, чем скрипт вида макета.
Нам необходимо указать doctype для веб-страницы прежде, чем мы выведем любой скрипт вида. Скрипт вида действия выполняется раньше и может возникнуть необходимость узнать, какой doctype используется. В особенности, это может понадобится для Zend_Form. Чтобы указать doctype, мы добавляем следующую строку в application.ini, секция [production]:

1
resources.view.doctype = "XHTML1_STRICT"

Помощник вида doctype() выведет корректное определение doctype, и компоненты вроде Zend_Form будут генерировать совместимый HTML-код.

Стилизация

Даже несмотря на то, что это “всего лишь” руководство, нам понадобится CSS-файл для того, чтобы сделать приложение более приятным глазу!
Сложность в том, что мы не знаем полный путь к CSS-файлам, т.к. наше приложение может находится не в корневом каталоге сайта, а в подкаталоге. К счастью, доступен помощник вида baseUrl(), который получает необходимую нам информацию из объекта запроса (Zend_Controller_Request) и передаёт нам URL, который мы не знали.
Теперь мы можем добавить CSS-файл в секцию файла application/layouts/layout.phtml. Сделаем мы это при помощи помощника вида headLink():

1
2
3
4
5
6
7
...
<head>
<?php echo $this->headMeta(); ?>
<?php echo $this->headTitle(); ?>
<?php echo $this->headLink()->prependStylesheet($this->baseUrl().'/css/site.css'); ?>
</head>
...

Используя метод appendStylesheet() помощника headLink(), мы можем добавить дополнительные, более специфичные CSS-файлы в скриптах вида контроллера, которые будут выведены в секции после site.css.
И, наконец, мы добавим некоторые необходимые CSS-стили. Создайте подкаталог css в каталоге public/ и добавьте туда site.css, содержащий следующий код:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
body,html {
    margin: 0 5px;
    font-family: Verdana,sans-serif;
}
h1 {
    font-size: 1.4em;
    color: #008000;
}
a {
    color: #008000;
}

/* Table */
th {
    text-align: left;
}
td, th {
    padding-right: 5px;
}

/* style form */
form dt {
    width: 100px;
    display: block;
    float: left;
    clear: left;
}
form dd {
    margin-left: 0;
    float: left;
}
form #submitbutton {
    margin-left: 100px;
}

Это должно сделать наше приложение более приятным, но, как вы могли заметить, что я не дизайнер!
Мы имеем четыре скрипта действия, которые были автоматически сгенерированы и готовы к наполнению. Перейдём к пустым файлам index.phtml, add.phtml, edit.phtml, delete.phtml, которые, как вы помните, расположены в каталоге application/views/scripts/index.

Вывод альбомов

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

1
2
3
4
5
6
7
8
9
10
...
function indexAction()
{
    $this->view->title = "My Albums";
    $this->view->headTitle($this->view->title);
   
    $albums = new Application_Model_DbTable_Albums();
    $this->view->albums = $albums->fetchAll();
}
...

Прежде всего, мы указываем заголовок (title) страницы, который будет выведен в секции и отображён в заголовке браузера. Метод fetchAll() возвращает zend_Db_Table_Rowset, который позволит нам обойти все полученные строки в скрипте вида.
Теперь наполним скрипт вида, application/views/scripts/index/index.phtml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<p><a href="<?php echo $this->url(('controller' => 'index', 'action' => 'add')) ?>">Добавить новый альбом</a></p>
<table>
    <tr>
        <th>Title</th>
        <th>Artist</th>
        <th> </th>
    </tr>
    <?php foreach($this->albums as $album) : ?>
        <tr>
            <td><?php echo $this->escape($album->title) ?></td>
            <td><?php echo $this->escape($album->artist) ?></td>
            <td>
                <a href="<?php echo $this->url(('controller' => 'index', 'action' => 'edit', 'id' => $album->id)) ?>">Редактировать</a>
                <a href="<?php echo $this->url(('controller' => 'index', 'action' => 'delete', 'id' => $album->id)) ?>">Удалить</a>
            </td>
        </tr>
    <?php endforeach; ?>
</table>

Первое, на что обратим внимание, это создание ссылки для добавления альбома. Помощник вида (view helper) url() предоставлен фреймворком и помогает создавать ссылки. Мы просто передаём необходимые параметры в виде массива.
Также мы создали HTML-таблицу для вывода заголовка и автора каждого альбома, со ссылками на редактирование и удаление записи. Стандартный цикл foreach используется для вывода альбомов, в данном случае мы используем его альтернативный синтаксис, включающий двоеточие и endforeach – он проще для восприятия в скриптах вида. Опять же, сылки на редактирование и удаление записи мы формируем при помощи помощника вида url().
Если вы откроете страницу http://localhost/zf-tutorial/public/ (или другую, если вы расположили приложение в другом месте), вы увидите список альбомов, как здесь:
Мои альбомы

Добавление новых альбомов

Теперь мы можем создать функционал для добавления новых альбомов. Он состоит из двух частей:

  • Вывод формы ввода для пользователя
  • Процесс отправки формы и запись данных в БД

Для этого мы будем использовать Zend_Form. Этот компонент позволяет нам создать форму и провести валидацию данных. Мы создаём новый класс Form_Album, который расширяет Zend_Form определяет нашу форму. Так как форма – ресурс нашего приложения, мы расположим класс в файле Album.php в директории форм. Для создания формы воспользуйтесь командной строкой:

1
zf create form Album

Эта команда создаст файл Album.php в application/forms. В версии ZF 1.10.0 и ниже, имя класса будет некорректное. Замените содержимое файла следующим кодом:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?php
class Application_Form_Album extends Zend_Form
{
    public function __construct($options = null)
    {
        parent::__construct($options);
        $this->setName('album');

        $id = new Zend_Form_Element_Hidden('id');
        $id->addFilter('Int');

        $artist = new Zend_Form_Element_Text('artist');
        $artist->setLabel('Музыкант')
            ->setRequired(true)
            ->addFilter('StripTags')
            ->addFilter('StringTrim')
            ->addValidator('NotEmpty');

        $title = new Zend_Form_Element_Text('title');
        $title->setLabel('Название')
            ->setRequired(true)
            ->addFilter('StripTags')
            ->addFilter('StringTrim')
            ->addValidator('NotEmpty');

        $submit = new Zend_Form_Element_Submit('submit');
        $submit->setAttrib('id', 'submitbutton');

        $this->addElements(($id, $artist, $title, $submit));
    }
}

В конструкторе Application_Form_Album мы создаём четыре элемента формы для ID, музыканта, названия альбома и кнопки submit. Для каждого из них мы указываем атрибуты, в том числе label для заголовка поля. В случае с ID мы уверены, что он может быть только integer, для предотвращения потенциальных SQL-инъекций мы используем фильтр Int.
Для текстовых элементов мы добавляем два фильтра, StripTags и StringTrim для удаления нежелательного HTML-кода и лишних пробелов. Также мы добавили валидатор NotEmpty чтобы быть уверенными, что пользователь ввёл необходимые данные.
Теперь нам нужно получить форму для вывода и подготовить её отправку. Делается это при помощи следующего кода в IndexController addAction():

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
function addAction()
{
    $this->view->title = "Add new album";
    $this->view->headTitle($this->view->title);

    $form = new Application_Form_Album();
    $form->submit->setLabel('Добавить');
    $this->view->form = $form;

    if ($this->getRequest()->isPost()) {
        $formData = $this->getRequest()->getPost();
        if ($form->isValid($formData)) {
            $artist = $form->getValue('artist');
            $title = $form->getValue('title');
            $albums = new Application_Model_DbTable_Albums();
            $albums->addAlbum($artist, $title);

            $this->_helper->redirector('index');
        } else {
            $form->populate($formData);
        }
    }
}
...

Немного пояснений по коду.

1
2
3
$form = new Application_Form_Album();
$form->submit->setLabel('Добавить');
$this->view->form = $form;

При помощи этого кода мы инстанцируем форму, указываем label для кнопки отправки, после чего передаём форму в скрипт вида для вывода.

1
2
3
if ($this->getRequest()->isPost()) {
    $formData = $this->getRequest()->getPost();
    if ($form->isValid($formData)) {

Если метод isPost() объекта запроса (request) возвращает true, значит форма была отправлена. В таком случае, мы получаем данные при помощи метода getPost() и проверяем их валидность при помощи метода isValid().

1
2
3
4
$artist = $form->getValue('artist');
$title = $form->getValue('title');
$albums = new Application_Model_DbTable_Albums();
$albums->addAlbum($artist, $title);

Если форма валидна, мы инстанцируем класс модели Application_Model_DbTable_Albums и используем созданный ранее метод addAlbum() для создания новой записи в БД.

1
$this->_helper->redirector('index');

После того, как данные были сохранены, мы используем помощник действия (action helper) Redirector для возвращения обратно к действию index (т.е. на главную страницу).

1
2
3
} else {
    $form->populate($formData);
}

Если форма не валидна, мы заполняем элементы формы введёнными пользователем значениями и повторно её выводим.

Теперь нам надо сделать вывод формы в скрипте вида add.phtml

1
<?php echo $this->form ?>

Как видите, вывод формы очень прост благодаря тому, что форма знает, как выводить саму себя. Теперь вы можете использовать ссылку “Добавить новый альбом” на главной странице приложения для добавления нового альбома.

Редактирование альбома

Редактирование альбома очень похоже на добавление:
zf-tutorial/application/controllers/IndexController.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
...
function editAction()
{
    $this->view->title = "Edit album";
    $this->view->headTitle($this->view->title);

    $form = new Application_Form_Album();
    $form->submit->setLabel('Save');
    $this->view->form = $form;

    if ($this->getRequest()->isPost()) {
        $formData = $this->getRequest()->getPost();
        if ($form->isValid($formData)) {
            $id = (int)$form->getValue('id');
            $artist = $form->getValue('artist');
            $title = $form->getValue('title');
            $albums = new Application_Model_DbTable_Albums();
            $albums->updateAlbum($id, $artist, $title);

            $this->_helper->redirector('index');
        } else {
            $form->populate($formData);
        }
    } else {
        $id = $this->_getParam('id', 0);
        if ($id > 0) {
            $albums = new Application_Model_DbTable_Albums();
            $form->populate($albums->getAlbum($id));
        }
    }
}
...

Разберём различия с добавлением альбома. Во-первых, перед выводом формы нам необходимо извлечь текущие значения полей “Музыкант” и “Название альбома” из БД и наполнить ими элементы формы. Делается это следующим образом:

1
2
3
4
5
$id = $this->_getParam('id', 0);
if ($id > 0) {
    $albums = new Application_Model_DbTable_Albums();
    $form->populate($albums->getAlbum($id));
}

Заметьте, что это происходит в случае, если POST-данные не были отправлены. Мы получаем id из объекта запроса используя метод _getParam(). Далее мы при помощи модели извлекаем запись из БД с соответствующим ID и наполняем форму полученными значениями (как вы уже знаете, что метод модели getAlbum() возвращает массив).
После валидации формы, нам необходимо сохранить изменённые данные в БД. Для этого мы используем метод модели updateAlbum():

1
2
3
4
5
$id = $form->getValue('id');
$artist = $form->getValue('artist');
$title = $form->getValue('title');
$albums = new Application_Model_DbTable_Albums();
$albums->updateAlbum($id, $artist, $title);

Скрипт вида выглядит так же:
zf-tutorial/application/views/scripts/index/edit.phtml

1
<?php echo $this->form ;?>

Теперь вы можете редактировать альбомы.

Удаление альбома

Чтобы функционал приложения был полным, нам необходимо добавить удаление. У нас уже есть ссылка “Удалить” для каждого альбома. Чтобы избежать случайного удаления, мы будем отображать форму подтверждения и удалять альбом только когда пользователь нажмёт кнопку “Да”. Так как это тривиальная форма, мы напишем её код напрямую в скрипте вида (можете использовать Zend_Form, если хотите).
Начнём с кода действия IndexController::deleteAction():

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
public function deleteAction()
{
    $this->view->title = "Delete album";
    $this->view->headTitle($this->view->title);

    if ($this->getRequest()->isPost()) {
        $del = $this->getRequest()->getPost('del');
        if ($del == 'Да') {
            $id = $this->getRequest()->getPost('id');
            $albums = new Application_Model_DbTable_Albums();
            $albums->deleteAlbum($id);
        }
        $this->_helper->redirector('index');
    } else {
        $id = $this->_getParam('id', 0);
        $albums = new Application_Model_DbTable_Albums();
        $this->view->album = $albums->getAlbum($id);
    }
}
...

Как и в добавлении и редактировании, мы используем метод isPost() объекта запроса для определения, следует ли выводить форму подтверждения, или надо удалить альбом. Мы используем модель Application_Model_DbTable_Albums для удаления записи, используя метод deleteAlbum(). Если POST-запрос не был отправлен, мы получаем ID альбома, достаём соответствующую запись из БД и передаём её в скрипт вида.
Скрипт вида представляет собой простую форму:
zf-tutorial/application/views/scripts/index/delete.phtml

1
2
3
4
5
6
7
8
9
10
11
<p>Are you sure that you want to delete
    '<?php echo $this->escape($this->album['title']); ?>' by
    '<?php echo $this->escape($this->album['artist']); ?>'?
</p>
<form action="<?php echo $this->url(('action'=>'delete')); ?>" method="post">
    <div>
        <input type="hidden" name="id" value="<?php echo $this->album['id']; ?>" />
        <input type="submit" name="del" value="Да" />
        <input type="submit" name="del" value="Нет" />
    </div>
</form>

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

Вот и всё. Теперь мы имеем полностью работающее приложение.

Заключение

Мы научились собирать простое, но функциональное MVC-приложение с использованием Zend Framework. Я надеюсь, это руководство было интересным и информативным. Если вы обнаружите ошибку, пожалуйста, пишите на e-mail автора rob@akrabat.com (или переводчика sergeymitr@gmail.com).
Это руководство охватывает лишь базовое использование фреймворка, существует множество других компонентов для изучения. Сайт автора содержит много статей о Zend Framework, также рекомендую прочесть руководство . Если вы предпочитаете печатный текст, Rob Allen написал книгу под названием “Zend Framework in Action”, которая доступна для заказа на сайте .
Всего доброго!

269 Comments

  1. Anton says:

    Zend Framework in Action выпущена в 2007-м. Она не сильно устарела с момента выпуска?

  2. Anton says:

    Вопрос по существу:
    Попробовал под WinXP запустить
    zf configure db-adapter
    , как написано здесь

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

  3. Сергей Митрошин says:

    ZF in Action слегка устарела, но ещё актуальна.
    Что за ошибку вы получили?

  4. Anton says:

    An Error Has Occurred The config already has a db resource configured in section production.

  5. Сергей Митрошин says:

    Дело не в системе (windows/linux), в вашем application.ini уже настроен db-адаптер. Возможно, вы сделали это вручную.

  6. Anton says:

    Спасибо. Я уже и забыл об этом. А что утилита просто вставляет строки в application.ini? Одна строка содержит ссылку на файл guestbook.db. Я ни где не нашел этого файла. Это нормально?

  7. Сергей Митрошин says:

    Приведите, пожалуйста, полный текст ссылки на guestbook.db
    Да, утилита просто вставляет строки в application.ini. Можно сделать это вручную.

  8. Anton says:

    Это я разбирал этот туториал:
    Там используется php_pdo_sqlite, поэтому dbname у них выглядит так:
    resources.db.params.dbname = “APPLICATION_PATH /../data/db/guestbook.db”

  9. Сергей Митрошин says:

    Изначально файл этот, насколько я помню, не нужен, но следует создать в нём таблицы.

  10. darkasha says:

    public function deleteAction()
    на 11 строчке баг —–> $albums = new Model_DbTable_Albums();

    $albums = new Application_Model_DbTable_Albums();

  11. Сергей Митрошин says:

    darkasha: спасибо, исправлено

  12. Ирина says:

    Все сделала, перезагрузилась, ввожу zf show version
    Получаю: “”php.exe”" не является внутренней или внешней командой,исполняемой программой или командным файлом.

  13. h3kir says:

    Ирина, чтобы такого не было исправте путь в Zf.bat с php.exe
    на C:\WebServers\usr\local\php5\php.exe разумеется WebService это название моей папки куда установен апатч.у вас это наверняка другая.

  14. Ирина says:

    Вот здесь: SET PHP_DIR=C:\Server\PHP\ ?
    Если там, то исправила, правда это ничего не изменило. Или опять перезагружаться надо?

  15. Ирина says:

    О! Сработало! Спасибо!!! надо было изменить
    SET PHP_BIN=C:\Server\PHP\php.exe

  16. Ирина says:

    Теперь вы можете проверить, всё ли в порядке, открыв URL .
    У меня: Fatal error: Call to a member function getDefaultModule() on a non-object in D:\www\zf-tutorial\library\Zend\Application\Bootstrap\Bootstrap.php on line 69

  17. Anton says:

    localhost
    Гы-гы

  18. Ирина says:

    Че гы-гы, это цитата :)

  19. Anton says:

    localhost – это локальное имя вашей системы. В интернете такого имени не существует.

  20. Ирина says:

    Я в курсе! Я не говорю про то, что не знаю, куда заходить, а говорю про то, что у меня ошибка, вместо красивой картинки. Если у кого была такая же, расскажите, как решили проблему! :)

  21. Сергей Митрошин says:

    Ирина, похоже на баг ZF. Никогда не получал такую ошибку.
    Попробуйте обновить ZF до последней версии.

  22. Ирина says:

    Баг ZF, но версия у меня 1.9.6.

  23. Ирина says:

    Думаю, что все-таки что-то в настройках апача…

  24. Anton says:

    как сохранить переменную, сгенерированную в одной функции, что бы потом можно было использовать её в другой?

    Я конечно понимаю что глобальные переменные давно не используются, но все же?
    чем можно в Zend это сделать?
    Пробовал Zend_Registry, но то-ли у меня руки кривые и я не понял, или там задать значение перемененной можно только в Bootstap?… ну да, для хранения переменных базы и конфиг файла супер… но а как быть с теми переменными которые создаются в самом контроллере, и нужны фактически только на некоторое время, но разных функциях.

    плиз, подскажите тугодуму…

  25. Сергей Митрошин says:

    Если это ваши пользовательские функции, передавайте значения через аргументы функции.

  26. Anton says:

    Это мои пользовательские функции, но они вызываются не последовательно, и к тому же вызываются через AJAX
    примерно так

    1 функция: форма -> сохранение в базу, в результате получаем ID
    2 функция: обработка данных
    3 функция: обработка данных

    вот во второй и в третей функциях, мне нужны эти переменные.

  27. Сергей Митрошин says:

    Почему не получается передать их как аргументы функции?

  28. Anton says:

    Потому, что функция в которой генерируется переменная, вызывается через jquery.form
    а jquery.form возвращает только или ошибку или код 200.
    и я бы передел легко, переменную, если бы она мне вернулась после отправки формы…

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

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

  29. Сергей Митрошин says:

    Разумеется, в таком случае не будет работать Zend_Registry.
    Но при помощи jquery.form можно получить данные с сервера при помощи параметра success.

  30. Anton says:

    да, данные из формы, но не результат работы функции, по крайней мере я не нашел как бы это сделать.

  31. Zyava says:

    Храните в сессии свою переменную, ее туда так же легко поместить, как и в Zend_Registry:

  32. chitozzz says:

    начал осваивать zf по вашей статье…все сделал, вроде работает, но не работает удаление и редактирование… в чем дело не пойму… из базы читает а изменять и удалять не хочет…

  33. chitozzz says:

    все разобрался… спасибо за знокомство с zf

  34. Dmitry says:

    Здравствуйте, у меня в пункте “Вывод альбомов”, вместо списка альбомов появляется следующее:

    My Albums
    An error occurred
    Application error

    Подскажите пожауйста, где может быть ошибка?

  35. Сергей Митрошин says:

    Вам надо добавить следующую строку в нужную секцию файла application.ini:
    resources.frontController.throwExceptions = 1
    После этого вы увидите сам текст ошибки.

  36. Dmitry says:

    Добавил в секцию [production], и к сожалению ничего не изменилось.. Может что-то с Apache?

  37. Сергей Митрошин says:

    В .htaccess у вас какой прописан APPLICATION_ENV?
    А сайт недвижимости больше не прописывайте, я его всё равно удаляю.

  38. Dmitry says:

    в public/index.php:

    // Define application environment
    defined(‘APPLICATION_ENV’)
    || define(‘APPLICATION_ENV’, (getenv(‘APPLICATION_ENV’) ? getenv(‘APPLICATION_ENV’) : ‘production’));

    a .htaccess только:

    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} -s [OR]
    RewriteCond %{REQUEST_FILENAME} -l [OR]
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule ^.*$ – [NC,L]
    RewriteRule ^.*$ index.php [NC,L]

  39. Dmitry says:

    Установил в .htaccess

    SetEnv APPLICATION_ENV production, результат не изменился

  40. kapals says:

    Dmitry, пробуй так:

    defined(‘APPLICATION_ENV’)
    || define(‘APPLICATION_ENV’, (getenv(‘APPLICATION_ENV’) ? getenv(‘APPLICATION_ENV’) : ‘development’));

    и

    resources.frontController.throwExceptions = 1

    ставим в application.ini ниже
    [development : production]

  41. kapals says:

    Или скорее всего откоменти в php.ini строку
    extension=php_pdo_mysql.dll

  42. Dmitry says:

    Да, действительно extension=php_pdo_mysql.dll был закоментрован в php.ini, теперь все работает,
    Большое спасибо!

  43. kapals says:

    Рад помочь:)

  44. chitozzz says:

    подскажите пожалуйста как подключить к этому сайту авторизацию? … все почитал что смог найти по этой теме но все решения как я понимаю для старых версий zf…

  45. Сергей Митрошин says:

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

  46. Elena says:

    Здравствуйте :) Помогите, пожалуйста,разобраться!
    Создала в корневом каталоге C:\WebServers\home новый проект :
    zf create project pages

    Перешла в каталог проекта:
    C:\Users\lenko>cd c:\webservers\home\pages
    При попытке создать новые действия контроллера, получаю ошибку:
    c:\WebServers\home\pages>zf create action add index
    “zf” не является внутренней или внешней
    командой, исполняемой программой или пакетным файлом.

  47. Dark Smoke says:

    Скажите мне, от куда берется albums?

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

  48. Dark Smoke says:

    Elena
    В самом начале статьи есть тема Настройка Zend Tools прочти ее еще раз и сделай как там написано.

  49. Oldman says:

    Бьюсь вторую неделю
    Элементарно не могу все установить.
    Ставлю под винду, denwer.
    Подскажите что делать с этим?

    Warning: require_once(Zend/Application.php) [function.require-once]: failed to open stream: No such file or directory in Z:\home\localhost\public\index.php on line 18

    Fatal error: require_once() [function.require]: Failed opening required ‘Zend/Application.php’ (include_path=’Z:\home\localhost\library;.;/usr/local/php5/PEAR’) in Z:\home\localhost\public\index.php on line 18

  50. chitozzz says:

    я тоже парился не получается… на семерке… я поставил zend server (почто тоже что и денвер), и там сразу заработала эта тулза…

  51. wr120 says:

    подскажите что делать ошибка такая
    Fatal error: Uncaught exception ‘Zend_Config_Exception’ with message ‘Section ‘APPLICATION_ENV’ cannot be found in Z:\home\localhost\www\zf-tutorial\application/configs/application.ini’ in Z:\home\localhost\www\zf-tutorial\library\Zend\Config\Ini.php:150 Stack trace: #0 Z:\home\localhost\www\zf-tutorial\library\Zend\Application.php(383): Zend_Config_Ini->__construct(‘Z:\home\localho…’, ‘APPLICATION_ENV’) #1 Z:\home\localhost\www\zf-tutorial\library\Zend\Application.php(85): Zend_Application->_loadConfig(‘Z:\home\localho…’) #2 Z:\home\localhost\www\zf-tutorial\public\index.php(24): Zend_Application->__construct(‘APPLICATION_ENV’, ‘Z:\home\localho…’) #3 {main} thrown in Z:\home\localhost\www\zf-tutorial\library\Zend\Config\Ini.php on line 150

  52. JHT says:

    при наборе в консоле: zf show version – выдает – “”php.exe”" Не является внутренней или внешней командой.
    как наладить?

  53. Oldman says:

    с настройками таки разобрался, автору спасибо за урок.
    будет ли продолжение?
    что-нибудь посложнее, например, урок по созданию реального приложения.
    (как вариант блога или простенького “сообщества по интересам”)

  54. Oldman says:

    Ошибка в коде
    function indexAction()
    {
    $this->view->title = “My Albums”;
    $this->view->headTitle($this->view->title);

    $albums = new Application_Model_DbTable_Albums();
    $this->view->albums = $albums->fetchAll();
    }

    Fatal error: Class ‘Application_Model_DbTable_Albums’ not found in Z:\home\zf-tutorial\application\controllers\IndexController.php on line 16

  55. Сергей Митрошин says:

    to wr120:
    Видимо, в .htaccess пропущена строка “SetEnv APPLICATION_ENV development”

    to JHT:
    Необходимо добавить php.exe в переменные окружения системы, в гугле есть подробные описания.

    to Oldman:
    Автору, действительно, спасибо. Я лишь перевёл.
    Продолжение действительно стоит написать. Буду заниматься.
    По поводу ошибки – в статье всё правильно и класс должен быть определён. Возможно, вы используете старую версию ZF? Если дело не в этом – отпишите, пожалуйста, буду фиксить.

  56. Oldman says:

    у меня ZendFramework-1.10.2.
    не могу понять почему не находит этот класс.

    Пробовал разные варианты переименовывал файлы и менял путь
    Application_Model_DbTable_Albums – не работает
    Application_Models_DbTable_Albums – не работает
    Model_DbTable_Albums – не работает
    Models_DbTable_Albums – не работает

  57. Oldman says:

    Еще с формами тоже не порядок

    Отсутствуют лейблы и надпись на кнопке

  58. kapals says:

    Сохрани скрипт в утф-8

  59. Shadow_Of_iRBIS says:

    После добавления
    resources.view.doctype = “XHTML1_STRICT”
    пропадает хидер “My Albums” почему-то. т.е. в layout.phtml $this->title пустой. В чем может быть проблема?

  60. oleg hodil says:

    я идиот

  61. Tirei says:

    Warning: require_once(Zend/Application.php) [function.require-once]: failed to open stream: No such file or directory in Z:\home\localhost\www\zf-tutorial\public\index.php on line 18

    Fatal error: require_once() [function.require]: Failed opening required ‘Zend/Application.php’ (include_path=’Z:\home\localhost\www\zf-tutorial\library;.;/usr/local/php5/PEAR’) in Z:\home\localhost\www\zf-tutorial\public\index.php on line 18

    То же самя ошибка, как ее исправить не могу понять

  62. Tirei says:

    блин я идиот, все там рассписано!

  63. lavren says:

    Спасибо за статью! Испытал с помощью zend server & Zend framework 1.10.5, проблем не было!
    После прочтения статьи многое стало понятно!

    Кому интерсно … мой выбор данной системы (zf), обусловлен выбором CMS на ZF,
    PimCore (pimcore.org)

  64. Anton says:

    PimCore интересно, да. Только по нему на русском вообще ни чего нет…

  65. lavren says:

    Молодой ещё … (PimCore)! Сейчас основы zend fr.. изучу, то и займусь PimCore поплотнее…

  66. Anton says:

    lavren, если захотите поделиться опытом по PimCore, кидайте ссылку…

  67. Oldman says:

    PimCore я поставил ради интереса. Тормозная какая-то она. Страницы долго грузятся (и в админки и в самом тестовом сайте). В админке при беглом просмотре не обнаружил нормальной системы назначения ролей пользователям. Зато много (на мой взгляд) лишнего и непонятного в админке.

  68. lavren says:

    У меня на домашнем сервере (windows-zendserver), летает! Но вы правы – работы ещё непочатый край…

  69. Oldman says:

    Если у кого-то были проблемы с кодировкой (Denwer).
    Замените строчку в AddDefaultCharset windows-1251 на AddDefaultCharset utf-8
    и перезапустите Аpache

  70. Oldman says:

    мне нужно чтоб в адресной строке в конце стояло .html как быстро а главное правильно реализовать ?
    (localhost/controller/metod.html)

  71. Denis says:

    Добрый день, подскажите, пожалуйста, ответы на два вопроса.
    1. Как сделать свой дизайн для форм создания и редактирования записи в альбоме? Хочется, чтобы и возможности предоставляемые Zend_Form, Zend_Form_Element_Hidden, Zend_Form_Element_Text… остались, но при этом дизайн был свой.
    2. Как можно на одной странице сделать несколько логических, независимых друг от друга блоков? Например, на каждой странице должен выводиться блок последний новостей, независимо от основного функционала страницы.

  72. Denis says:

    P.S. О декораторах я почитал. Но, ИМХО, их использование далеко, от удобного. Получается что уже имеющуюся верстку надо перелопатить в команды формирования (методы декораторов). Все это будет плохо читаемо, сложно к исправлению ошибок и еще более сложно к изменению, если таковое потребуется. Интересуют более наглядные методы задания своего дизайна для форм.

  73. ZA says:

    Здравствуйте!
    Скажите, пожалуйста, почему может отрабатывать ветка Default контроллера ErrorController (на странице появляется сообщение Application Error) при выполнении команды
    $this->view->users = $users->fetchAll();
    контроллера IndexController?
    users практически ничем не отличается от Albums. логин/пароль, записанные в application.ini соответствуют существующему в БД пользователю.

  74. ZA says:

    вопрос снят. Прочитала самые первые комментарии про установку
    resources.frontController.params.displayExceptions = 1
    в application.ini

  75. Roman says:

    Статья хорошая, но обнаружил следующий глюк. При использовании команд типа
    zf create action имя_метода index
    зачем-то переформатируется весь файл, причем последовательность из нескольких фигурных скобок заменяется одной. То есть вместо }}} получаем } со всеми вытекающими последствиями. Если вместо }}} в файле стоит };};} то все нормально, но все равно зачем то меняются отступы по непонятной логике.
    Вопрос такой если не пользоваться командной строкой, а все добавлять вручную возникнут ли впоследствии проблемы ?

  76. 1111111 says:

    Здравствуйте.
    Пробую написать свой маршрутизатор и не могу пока понять почему при перенаправлении на файл не загружает стили()”обычным” способом. И вообще это довольно актуальная тема для отдельного поста: “Как написать свой framework”? Только этот вопрос приведет пачку новых посетителей не говоря уже о большем.

  77. 1111111 says:

    таким вот способом:
    link href=”image/style.css” rel=”stylesheet” type=”text/css”

  78. kolorimage says:

    У меня XAMPP. И при попытке посетить
    “Access forbidden!

    You don’t have permission to access the requested directory. There is either no index document or the directory is read-protected.

    If you think this is a server error, please contact the webmaster.”

  79. Zabi says:

    Подскажите плс, встал на шаге после создания экшенов, неработают ссылки типа

    но заходит с необходимым результатом на ссылки типа

    теперь на шаге создания динамичных ссылок echo $this->url(array(‘controller’ => ‘index’, ‘action’ => ‘add’)) немогу сгенерировать необходимые ссылки, перерыл кучу инфы но не могу найти ответ на вопрос: как сделать так чтобы не нужно было писать в адресе index.php, или написать функцию для создания правильных ссылок.

    в httpd.conf AllowOverride All прописано и LoadModule rewrite_module modules/mod_rewrite.so раскомментировано

  80. Feo says:

    При установке лучше не копировать library/Zend в наш проект, а сделать символьную ссылку, к основному пакету /usr/local/ZendFrameworkCli/library/Zend

  81. Sunnesoft says:

    Возникла проблема как у Oldman’a. Только решил ее редактированием файла View\Abstract: $_encoding=’нужная кодировка’.

  82. neman says:

    У меня возникла такая проблем, когда я передаю значение на русском языке в метод setLable класса Zend_Form_Element_Text(‘artist’), то ничего в браузере не отображается, а на английском – все нормально. И такая же проблема с headTitle. Что делать?)))

  83. Oldman says:

    neman: проблема с кодировкой, читай коментарии

  84. neman says:

    Изменил в httpd.conf строчку AddDefaultCharset windows-1251 на AddDefaultCharset utf-8 и все равно не отображается кириллица хотя и в layout.phtml прописана кодировка utf-8

  85. Oldman says:

    а перезагружал сервак? )
    пора форума создавать, однако

  86. Anton says:

    Oldman. Поддерживаю. Много вопросов, в одну ветку все не укладывается…

  87. Фам says:

    Обнаружил интересный баг, но поскольку только недавно начал учиться работать в Zend Framework’е, не знаю, как его исправить…
    Собственно, его описаниние:
    Когда неправильно заполняешь какой-нибудь input в форме и валидатор начинает ругаться, становится невозможно обновить страницу браузера до тех пор, пока не заполнишь правильно – выскакивает окно с надписью: “Чтобы отобразить эту страницу, Firefox должен отправить информацию, которая повторит любое ранее произведённое действие (например, запрос на поиск или онлайн-покупка).” и кнопками “Отправить” и “Отмена”, причем последняя не помогает… Не могли бы вы подсказать, в чем дело?

  88. Фам says:

    ыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыыы

  89. Фам says:

    Простите за предыдущее сообщение!.. Хотел посмотреть кое-что))

  90. Anton says:

    А почему “ы” ?

  91. Сергей Митрошин says:

    Попытка дефейса?

  92. Сергей Митрошин says:

    По поводу “Firefox должен отправить информацию…” – так и должно быть, он хочет повторно послать POST-данные.

  93. Anton says:

    Стандартное поведение браузеров. Когда жмешь F5, он повторно отсылает запрос, вызвавший обновляемую страницу.

  94. Фам says:

    А нельзя никак этого избежать?

  95. Anton says:

    Используй другие способы обновить страницу. Уверен они есть…

  96. Фам says:

    Просто я на основе этого руководства делаю гостевую книгу (просто так в качестве тренировки) и, мне кажется, что если бы это было реально приложение, то его пользователям не сильно хотелось бы искать другой способ обновить страницу…

  97. Anton says:

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

  98. kroosnik says:

    Warning: Invalid argument supplied for foreach() in C:\xampp\htdocs\zf-tutorial\application\views\scripts\index\index.phtml on line 8

    подскажите пожалуйста, что я сделал не так?

  99. Сергей Митрошин says:

    Пытаетесь сделать foreach не по массиву.

  100. kroosnik says:

    я делал все по статье

    <a href="url(array(‘controller’ => ‘index’, ‘action’ => ‘add’)) ?>”>Добавить новый альбом</

    albums as $album) : ?>

    но почему-то именно на этой строке все остановилось и не работает (

  101. kroosnik says:

    albums as $album) : ?>

  102. dnka says:

    Народ, подскажите плиз такое дело: я хочу развернуть приложение на хостинге. Но там все лежит в папке www\имя_сайта . Как мне прописывать настройки, чтобы автоматически корневой дирикторией была \имя_сайта\public\

    Спасибо большое

  103. Сергей Митрошин says:

    Описание процесса:

  104. dnka says:

    Огромное спасибо, Сергей Митрошин !!! 2 минуты – и все работает :)

  105. skyder says:

    Такая проблема: если в БД данные записаны кириллицей, на странице они отображаются вопросиками… как поменять кодировку?

  106. skyder says:

    С кодировкой разобрался… При создании БД нужно сравнение ставить utf-8…

  107. Иван says:

    У меня не отображается русские буквы!!! Все файлы поменял на utf-8: результата никого!!!

  108. DendyFan says:

    Тоже проблема с кодировками…
    Все файлы в UTF8
    meta в layout тоже utf8
    Все сравнения в таблице utf8_unicode_ci, сопоставление соединения mysql Тоже utf8_unicode_ci
    В конфиге resources.db.charset = “utf8″

    И все равно ???? вместо русских букв…

  109. Rostislav says:

    Ребята, подскжите пожалуйста по такому вопросу
    можно ли как то задать ошибку общюю для формы
    не связанную с конкретным полем.
    ну скажем чтоб например если не прошёл логин выдавало какое-то общее сообщение над списком полей
    и чтоб это всё отобразилось просто при echo $form;

  110. Rostislav says:

    Это был вопрос по Zend_Form

  111. CoDy says:

    Спасибо за статью.
    Собрал у себя на локальном сервере вышеописанное приложение.
    Хоть приложение и очень простое, но сервер нагружает довольно сильно.
    Есть ли методы ускорить работу приложений на базе ZF? В частности хотелось бы узнать о таком расширении ка Zend Optimizer – это просто дешифратор или в нем есть задатки php акселератора???

  112. Kinko says:

    Не могли бы Вы осветить использование Dojo.

  113. Constantine says:

    спасибо за статью! у меня есть вопрос
    я сделал все, как написано до пункта, где мы создаем обьект $albums нашего класса для альбомов.
    на строчке $albums = new Application_Model_DbTable_Albums();
    мне выдается ошибка
    Fatal error: Class ‘Application_Model_DbTable_Albums’ not found in (путь к папке сайта)\application\controllers\IndexController.php on line 16

    хотя сам класс лежит именно там, где должен, тоесть в (путь к папке сайта)\application\models\DbTable\Albums.php
    не могли бы вы помочь?

  114. Constantine says:

    проблему решил! вот ответ из офф мануала (инетерсно будет всем, у кого не работает ZF Tool на сервере с xampp):
    To all those who couldn’t make ‘zf’ commands work (eg: zf enable layout).

    The path to the Zend framework installation should be registered with the system.
    Eg: In Windows a path variable should be set in the Environment Variables in the Advanced tab of System Properties in Control Panel. (eg: Control Panel->System->Advanced->Environment Variables in XP).

    I’m using XAMPP. There is a small caveat in there which I’ll share with my fellow XAMPP users. XAMPP has already has some logic by which all the folders inside it knows the existence of others. So If you go look inside it you can see there is already a Zend folder in the PEAR directory inside php folder. So all we need to add as a path variable is up to the php folder (eg: C:\xampp\php) and all will be well.

    Check by typing “zf show version”. It will print out the version of the Zend libraries inside the PEAR folder. (Whenever there is a new version of ZF is available I change the content inside this folder and everything is up to date).

  115. Oldman says:

    ! C:\Documents and Settings\fuckoff\Рабочий стол\zf-tutorial-160.zip: Архив повреждён или имеет неизвестный формат

  116. Сергей Митрошин says:

    Oldman, спасибо. Заменил ссылку на архив.

  117. Oldman says:

    Режим указывается в .htaccess и по умолчанию имеет значение development.
    вроде в application.ini

  118. foreach says:

    Кто нибудь может объяснить на пальцах по поводу ошибки:
    FataError:Class ‘Application_Model_DbTable_Albums’ not found in ‘Z:\localhost\zfapp\www\application\controllers\IndexController.php’ on line 18
    Почему не найден класс?Все же делал по статье.

  119. phpstarter says:

    Остановился на шаге там где через zf tool добавляют дополнительные действия в контроллер

    Так вот в командной строке захожу в папку zf-tutorial

    и ввожу как написано в статье следующюю команду.
    zf create action add index

    в ответ получаю такую ошибку….
    “Fatal error: Cannot redeclare class Zend_Loader in E:\xampp\htdocs\zf-tutorial\library\Zend\Loader.php on line 31

    подскажите что делать ?

  120. Сергей Митрошин says:

    Надо закомментировать в application.ini следующую строку: includePaths.library = APPLICATION_PATH “/../library”
    Комментарий обозначается символом “;”

  121. phpstarter says:

    спасибо ! сработало :) а после всего наверно потом надо будет раскоментировать ту строчку обратно ?

  122. Сергей Митрошин says:

    Не обязательно, и без неё работает.

  123. phpstarter says:

    большое спасибо :) я пока новичек, как я понял если делать свой серьезный проэкт то лучше делать его на ZF чем самому писать. Пролистал кучу сайтов по ZF но везде както через одно место было написано, а тут все вроде идеально получается ! Большое спасибо за проделанную работу ! А также за внимание к коментариям :)

  124. Сергей Митрошин says:

    Пожалуйста :)
    Пишите, если что.

  125. phpstarter says:

    Внимание для тех у кого возникнут следующие проблемы.
    Если вы используете веб сервер xampp, и вы начали на его базе делать этот проэкт и у вас произошло следующее…
    1. При вводе в командной строке команды zf show version и вам выводится “Zend Framework Version: 1.9.6″ , хотя вы знаете что скачали более свежую версию.
    2. При вводе в командной строке команды zf enable layout вы получаете “An Error Has Occured”
    “Action ‘enable’ is not a valid action

    Итак если у вас произошло читаем ниже

    Объяснение…..
    Дело в том что у xampp тоже есть встроенная Zend библиотека и она подключается к работе , а так как она стара отсюда и старая версия при запросе а также откза подключать layout.

    Действия……..
    заходим в /xampp/php/PEAR там есть папка Zend. Берем из архива скачанного фрейморка туже папку и перезаписываем туда куда я указал. После этого тутже можно проверять. Описанные выше проблемы изчезнут.

  126. phpstarter says:

    Сергей выручайте пожалуйста :)

    Дошел до вывода албомов.

    Проделав шаги указанные там

    смотрю . у меня все точно также построенно но вместо того что должно выйти пишет “Fatal error: Class ‘Application_Model_DbTable_Albums’ not found in E:\xampp\htdocs\zf-tutorial\application\controllers\IndexController.php on line 17″

    Я так понимаю IndexController без понятия кто такой класс Application_Model_DbTable_Albums. Если не ошибаюсь , объявляли мы его в Albums.php . Я пока все пытаюсь вслепую сделать, так что мало соображаю, но наверно IndexController Должен был както получить доступ к содержимому Album.php но сюдя по всему он не брал от туда инфу и потому не знает что такой класс создан. Пожалуйста помогите советом :)

  127. Сергей Митрошин says:

    Попробуйте заменить имя класса в обоих случаях на Model_DbTable_Albums.

  128. phpstarter says:

    После изменения Application_Model_DbTable_Albums на Model_DbTable_Albums в указанных ниже строчках

    albums.php
    class Model_DbTable_Albums extends Zend_Db_Table_Abstract

    IndexController.php
    $albums = new Model_DbTable_Albums();

    ответ тотже
    Fatal error: Class ‘Model_DbTable_Albums’ not found in E:\xampp\htdocs\zf-tutorial\application\controllers\IndexController.php on line 17

  129. phpstarter says:

    Сергей. покопавшись тут я нашел ответ в 43ем коментарии…

    человек по имени Sensi решил эту проблему добавив следующий код в Bootstrap.php

    protected function _initFoo()
    {

    $loader = new Zend_Loader_Autoloader_Resource (array (
    ‘basePath’ => APPLICATION_PATH,
    ‘namespace’ => ‘Application’,
    ));

    $loader->addResourceType( ‘model’, ‘models’, ‘Model’);
    }

    Проделав это у меня вышло но только после того как я переименовал класс в исходных вариант тоесть с заглавием Application.

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

    заранее спасибо :)

  130. phpstarter says:

    новая проблема

    команда zf create form Album
    отказывается работать.

    Fatal error: Call to a member function search() on a non-object in E:\xampp\php\PEAR\Zend\Tool\Project\Provider\Form.php on line 70

    Заранее говорю что по этому пути как и в program files установлена последняя версия zf. 1.10.8

    Как решить данную проблему ?

  131. Сергей Митрошин says:

    В указанном коде происходит добавление моделей в список ресурсов для автозагрузки. По какой-то причине это не произошло автоматически. Надо разбираться.
    По поводу zf create form – вы всё делаете правильно, видимо, баг в ZF. Попробуйте откатиться до прежних версий.

  132. phpstarter says:

    не стал откатываться так как тогда не работали бы другие функции..
    сделал формы ручками, благо не настолько кривые :)

    вобщем спасибо за перевод, даннйо статьи. Все собрал. Все работает :) Теперь хочу это дело нормально переварить и на базе этого сварганить чтонить свое :)

    Еще раз спасибо за проделаную работу :)

  133. Сергей Митрошин says:

    Пожалуйста.
    Удачи с изучением :)

  134. Oldman says:

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

  135. Anton says:

    Объясните, кто-нибудь, как отправить файл на сервер методами Zend_Http_Client

  136. Pavlushka66 says:

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

  137. Сергей Митрошин says:

    А просто так ничего не даётся. Хочешь использовать Zend Framework – приходится напрягаться.

  138. Antomus says:

    Спасибо за хороший перевод отличного туториала :)

  139. ананас says:

    Я сегодня скачал и установил последнюю версию zend вместе с сервером (zend server), настроил при установке, чтобы сервером был апач, а не ISS, но у меня совсем другая структура каталогов, не такая, как в этой статье. главная страница открывается по адресу , то есть, как я понял, каталог ZendServer здесь вместо zf-tutorial, но реальная файловая структура до файлов контроллеров имеет вид C:\Program Files\Zend\ZendServer\GUI\application\CE\controllers, то есть здесь еще есть какие-то каталоги GUI и CE. Каталог C:\Program Files\Zend\ZendServer\GUI содержит папки application, html, library и utils , причем , как я понял, каталог html заменяет описанный в статье public, так как файл index.php расположен именно в html. Каталог application тоже имеет некоторые другие папки. В общем, у меня 1-й вопрос: почему у меня другая структура каталогов? И главный вопрос, как мне теперь выполнить команды “zf create action add index” и другие, так как выполнение этих команд приводит к ошибке “An error has occured. A project profile was not found”, я так подозреваю, что именно из-за такой странной структуры каталогов.

  140. ANDR says:

    An error occurred
    Application error
    Есть еще сопсобы решения этой ошибки??? Вышеописанное все перепробовал, намучался просто жуть (((( Помогите.

  141. metya says:

    An Error Has Occurred
    Provider ‘layout’ is not a valid provider

    указанный выше способ пробовал,не помогло.
    Подскажите как решить данную проблему.

  142. metya says:

    По поводу ошибки Fatal error: Class ‘Model_DbTable_Albums’ not found in E:\xampp\htdocs\zf-tutorial\application\controllers\IndexController.php on line 17

    Решил добавить так как описаное ранее не помогло
    еще одно решение,добавить в Bootstrap.php

    protected function _initAutoload() {
    $moduleLoader = new Zend_Application_Module_Autoloader(array(
    ‘namespace’ => ‘Application’,
    ‘basePath’ => APPLICATION_PATH));

    /** auto load */
    $autoloader = Zend_Loader_Autoloader::getInstance();
    $autoloader->setFallbackAutoloader(true);
    return $moduleLoader;
    }

    найдено на 100 коментарий

  143. Константин says:

    По кодировки тоже проблема.
    Если на кириллице в базу все заливать, то на страницу не выводится. Если убираем escape в выводе, то на страницу все выводится.
    Как с этим справиться?

  144. serg says:

    Привет!
    Проблема, рештл разобраться с зендом, начал делать всё как по статье, но остановился на создании контроллеров. Чего то я не пойму, как правильно их создать. Там написано что – “Откройте командную строку и измените директорию на ваш каталог …”, но как это сделать? Если можно на примере, что надо вбить в командную строку.

  145. serg says:

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

  146. serg says:

    Мля…, не одно так другое. Теперь мне выдаёт что контроллер не найден, хотя нахожусь в корневой директории, то есть в zf-tutorial/
    Пробовал и просто вводить index, и Index, и IndexController. Пишет что не находит и выводит информацию как типа правильно задавать – “zf create action name controller-name[=index] view-include[=1] module”
    Подскажите что не так?

  147. Alex says:

    Не подскажите в чём проблема?
    Warning: include_once(Zend\Config\Ini.php) [function.include-once]: failed to open stream: No such file or directory in C:\apache\zend.com\www\library\Zend\Loader.php on line 146

    Warning: include_once() [function.include]: Failed opening ‘Zend\Config\Ini.php’ for inclusion (include_path=’C:\apache\zend.com\www\library;.;c:\php\includes’) in C:\apache\zend.com\www\library\Zend\Loader.php on line 146

    Fatal error: Class ‘Zend_Config_Ini’ not found in C:\apache\zend.com\www\library\Zend\Application.php on line 383

  148. wa1 says:

    Все работает. Единственное на форме “добавить альбом” нету лейблов. Но это не так уж и важно.

    Не понравилось только выражение “я – не дизайнер!1″, программисты часто правошарные и у них получается все в дизайне, то что предполагает MVC не значит что обязательно программисты и дизайнеры – это два параллельных мира, их множества пересекаются. Тем более все равно в файлы вида добавляются разные foreach, и задача не решена.

  149. Flyer says:

    Очень полезная статья, спасибо.

    НО не могли бы вы еще ее развить, путем добавление к этому всему делу админ панели с авторизацией?

  150. Flyer says:

    В статье описан случай когда у контролера относительно мало экшенов.

    Но предположим какой то контролер имеет очень много экшенов и хочется их сгруппировать.
    Например members/transactions/add(edit|delete)/, те есть контроллер пользователь у которого есть свой функционал по транзакциям(которые хочется сгруппировать). Как тогда быть в таком случае, как будет выглядеть контроллер и экшены?

    Заранее спасибо!

  151. wa1 says:

    Если я правильно понимаю просто пишешь роутер, копаешь в сторону Zend_Controller_Router_Route_Regex

  152. Сергей Митрошин says:

    Flyer, контроллеры можно группировать в модули. В вашем случае будет так: members module, transactions controller, add action.

  153. wa1 says:

    А тогда да конечно, необходимо фронт контроллере указать папку для модулей, и название папку модуля по умолчанию, я просто думал ему надо сгруппировать в пределе одного контроллера действия, как здесь он написал, /add(edit|delete)/, извините за оплошность

  154. Flyer says:

    Спасибо всем за ответы. Собственно мне понравилось совместное решение модулей с роутерами, буду копать, но пока это завтрашний день.

    Но вышел следующий вопрос при модульной структуре.

    Возьмем за основу то что расписал Сергей и модифицируем в структуру вида:
    *config
    –application.ini
    *application
    –default
    —-controllers
    —-forms
    —-layouts
    —-models
    —-views
    –somemodule
    —-controllers
    —-forms
    —-layouts
    —-models
    —-views
    *library
    –Zend
    —- и т.д.
    *public
    –index.php

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

    В application.ini у меня:
    ==========================
    includePaths.library = APPLICATION_PATH “/../library”

    bootstrap.path = APPLICATION_PATH “/Bootstrap.php”
    bootstrap.class = “Bootstrap”

    appnamespace = “Application”

    resources.frontController.controllerDirectory = APPLICATION_PATH
    resources.frontController.params.displayExceptions = 0
    resources.frontController.moduleDirectory = APPLICATION_PATH

    resources.modules[] = “”

    resources.layout.layoutPath = APPLICATION_PATH
    ==========================
    В public/index.php подрехтовал путь до application.ini

    т.е. я изменил пути к контроллерам и модулям.

    Проект стал выбивать ошибку:
    Fatal error: Class ‘Application_Model_DbTable_Albums’ not found in B:\www\myproject\application\default\controllers\IndexController.php on line 16
    Те как я понимаю он не видит или не подгружает файл с моделью. И тут то я не могу не как разобраться с этой проблемой, ввиду не хватки знаний в зенде. Буду благодарен за помощь.

  155. Flyer says:

    В статье есть такое предложение по моделям:
    “Наш проект имеет загрузчик по умолчанию, который создаётся при помощи Zend_Application, который находит классы ресурсов модуля внутри указанного каталога.”

    Может нужно как то этому загрузчику указать что изменилась структура каталогов в ини файле?

    Да и кстати все эти изменения в структуре я сделал не через консоль, а в ручную создавал папки и покидал туда файлы. Или при работе через консоль еще что то куда то в движек прописывается помимо создания самих файлов?

  156. wa1 says:

    >resources.frontController.controllerDirectory = APPLICATION_PATH
    >resources.frontController.params.displayExceptions = 0
    >resources.frontController.moduleDirectory = APPLICATION_PATH

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

    $front->setControllerDirectory(‘/application/default’=>’default’,
    ‘/application/somemodule’=>’somemodule’);

    Потом папка модулей:

    $front->addModuleDirectory(‘/application’);

    И есть еще пространства имен :D все имена классов из модуля должны начинаться с “Somemodule_”.
    Для дефолтного модуля не обязательно.

    И с помощью SetDefaultModule и SetDefaultController можно указывать какие контроллеры и модули используются по умолчанию
    :D

  157. Flyer says:

    Wa1, а где указывать директории? Судя по тому, что вы привели php код, то не в ini файле.

    Ну контроллер в default у меня срабатывает, там пространства имен не изменились, так что по идее должно работать. Но вот модель не подгружает и все …

  158. wa1 says:

    Можно и в инифайле а можно в бутстрапе, например в _init*()функции пишешь:

    $this->bootstrap(‘FrontController’);
    $front = $this->getResource(‘FrontController’);

    берешь экземпляр.

    $front->setControllerDirectory(‘/application/default’=>’default’,
    ‘/application/somemodule’=>’somemodule’);
    $front->addModuleDirectory(‘/application’);

    указываешь директории.

    Для автозагрузчика ресурсов надо указывать пространства имен например в config’е:

    autoloadernamespaces[] = “Namespace_” ;

    Если тебе надо загрузить такой класс автоматически:
    class Namespace_Model1_NameModel{}

    Он должен сидеть в такой директории:
    application/Namespace/Model1/NameModel.php.

    У тебя же много модулей… правильно? Зачем в каждой папке модели?

  159. MMg says:

    На этапе создания бд, если заменить строчку (например 2) на русский текст:

    INSERT INTO albums (artist, title)
    VALUES
    (‘Paolo Nutine’, ‘Sunny Side Up’),
    (‘Кровосток’, ‘Людоед’),
    (‘Massive Attack’, ‘Heligoland’),
    (‘Andre Rieu’, ‘Forever Vienna’),
    (‘Sade’, ‘Soldier of Love’);

    на странице главной странице не выводит русские названия
    т.е. вот так выглядит:
    Sunny Side Up Paolo Nutine Редактировать Удалить
    Lungs Florence + The Machine Редактировать Удалить
    Редактировать Удалить
    Forever Vienna Andre Rieu Редактировать Удалить
    Soldier of Love Sade Редактировать Удалить

    Выставил utf8 для БД, для таблицы, в настройка сервера AddDefaultCharset utf-8

    Где еще нужно добавить? Чтоб подружить с русскими буквами?

  160. MMg says:

    Вопрос с бд вроде решился. Спасибо
    нужно добавить строчку в application.ini
    resources.db.params.charset = “UTF8″

    Почему не выводятся лейблы в форме (у меня тоже не выводятся) ? Уже задавали этот вопрос выше, ответа нет пока.

  161. MMg says:

    Автору спасибо за статью (за перевод).
    Но любой английский текст, нужно адаптировать для НАС.
    т.к. автор-американец, наверно, даже не занет про существование других кодировок, у него по умолчанию utf8 и все работает. У нас же дополнительные проблемы из-за того, что скрипты открываются в 1251, что по умолчанию в Denwer тоже не utf8 и т.д.
    Также на месте владельца сего блога почистил бы комментарии. Удалив лишние (и это в том числе), и сделал бы FAQ по основным вопросам к этой статье.
    Сделайте так и будет вам жирная ссылка от меня. Спасибо

  162. MMg says:

    Черт, и лейблы стали отображаться после того как поменял в редакторе кодировку на utf8 для файла application/forms/Albums.php

    Вопрос снимается… )

  163. wa1 says:

    Flyer

    кстати , вообще-то достаточно просто файл с классом создать в папке модуля.
    class someModule_Bootstrap extends Zend_Application_Module_Bootstrap
    {
    }
    И в конфиге написать
    resources.frontController.moduleDirectory = APPLICATION_PATH “/modules”
    resources.modules[] =
    Я сам недавно просто начал изучать эти все модуля:)

  164. MMg says:

    У меня не работает
    View script for controller index and script/action name add
    “View” не является внутренней или внешней командой, исполняемой программой или пакетным файлом.

    Опечатки по тексту:
    1) приложения (процесстакже известен
    2) все последующие буквы тоже должны мыть в нижнем

    Тут неверно указан файл:
    Режим указывается в .htaccess и по умолчанию имеет значение development.

  165. MMg says:

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

  166. MMg says:

    еще опечатка:
    deleteAlbum() удалён запись совсем

  167. MMg says:

    еще опечатка:
    ля объединения вместе HTTP-загловков,

  168. 5atplus says:

    Отличная статья для начинающих! Автор – спасибо.

  169. Paradox says:

    MMg, скажи пожалуйста, где именно ты поменял кодировку на utf8 после чего лейблы появились на русском?

  170. MMg says:

    тут: application/forms/Albums.php
    а вообще все php-файлы из папки application должны быть в utf8, можное еще в папке public поменять.

    Пользуюсь там внизу в стоке состояния меняется кодировка с ANSI на UTF8.

  171. Paradox says:

    Спасибо, буду разбираться, а то я перевел кодировку так, чтобы отображались русские буквы из таблицы с названиями, а после этого кнопки “редактировать” “удалить” и “добавить новый альбом” пропали (вместо них квадраты)…

  172. Paradox says:

    MMg, еще раз большое спасибо!При помощи этого редактора перевел в utf8 и все заработало как надо!

  173. MMg says:

    Paradox: пожалуйста

  174. Владимир says:

    Здравствуйте, пытаюсь установить zf на ubuntu 10.4
    сервер – Zend server ce

    После команды zf show version
    Выдает ошибку
    /usr/local/ZendFrameworkCli/bin/zf.sh: 44: php: not found

    С чем это может быть связано ?
    Делал все по инструкции…

    Помогите пожалуйста.

  175. Drex says:

    Пытаюсь выполнить все что говорит автор, получил такую ошибку
    Fatal error: Uncaught exception ‘Zend_Application_Bootstrap_Exception’ with message ‘No default controller directory registered with front controller’ in C:\myweb\localhost\pro\library\Zend\Application\Bootstrap\Bootstrap.php:91 Stack trace: #0 C:\myweb\localhost\pro\library\Zend\Application.php(366): Zend_Application_Bootstrap_Bootstrap->run() #1 C:\myweb\localhost\pro\public\index.php(26): Zend_Application->run() #2 {main} thrown in C:\myweb\localhost\pro\library\Zend\Application\Bootstrap\Bootstrap.php on line 91
    может кто подскажет в чем проблема?

  176. Drex says:

    ошибку убрал, но теперь страница
    вообще не отображается опера пишет что Удаленный сервер или файл не найден
    может кто то подсказать в чем проблема?

  177. Drex says:

    ковырял ковырял в итоге пришел к такой ошибке
    Fatal error: Uncaught exception ‘Zend_Db_Adapter_Exception’ with message ‘The PDO extension is required for this adapter but the extension is not loaded’ in C:\myweb\localhost\zf-tutorial\library\Zend\Db\Adapter\Pdo\Abstract.php:342 Stack trace: #0 C:\myweb\localhost\zf-tutorial\library\Zend\Db\Adapter\Abstract.php(247): Zend_Db_Adapter_Pdo_Abstract->setFetchMode(2) #1 C:\myweb\localhost\zf-tutorial\library\Zend\Db.php(270): Zend_Db_Adapter_Abstract->__construct(Array) #2 C:\myweb\localhost\zf-tutorial\library\Zend\Application\Resource\Db.php(142): Zend_Db::factory(‘PDO_MYSQL’, Array) #3 C:\myweb\localhost\zf-tutorial\library\Zend\Application\Resource\Db.php(154): Zend_Application_Resource_Db->getDbAdapter() #4 C:\myweb\localhost\zf-tutorial\library\Zend\Application\Bootstrap\BootstrapAbstract.php(680): Zend_Application_Resource_Db->init() #5 C:\myweb\localhost\zf-tutorial\library\Zend\Application\Bootstrap\BootstrapAbstract.php(623): Zend_Application_Bootstrap_BootstrapAbstract->_executeResource(‘db’) #6 C:\myweb\localho in C:\myweb\localhost\zf-tutorial\library\Zend\Db\Adapter\Pdo\Abstract.php on line 342

  178. Drex says:

    Я так понял у меня проблема с адаптером PDO, возможно ли это из-за того что уменя стоит ZendFramework-1.11.0 а ПХП 5.2 ? или с 5.2 работает норм?
    в php.ini добавил такие строчки extension=php_pdo.dll
    extension=php_pdo_mysql.dll но всеравно не помогает.
    Может кто то подскажет в чем проблема?

  179. Сергей Митрошин says:

    MMg спасибо, исправлено
    Drex дело не в версии PHP. По какой-то причине не подключается PDO-extension. Не забыл перезапустить Apache после изменения php.ini?

  180. Drex says:

    Пришел с работы домой установил php 5.3, получилась таже ошибка при наличии этой строки resources.db.adapter = PDO_MYSQL в файле application.ini страница очень долго грузится и в итоге просто ничего не загружается, тоесть опера выдает ошибку. При коментировании resources.db.adapter = PDO_MYSQL поясляется следующее
    My Albums
    An error occurred
    Application error
    ну тут мне как бы понятно что конекта с БД нет.
    phpinfo() выдает следующее
    PDOPDO support enabled
    PDO drivers mysql, odbc, sqlite
    будте добры подскажите в чем проблема?

  181. Сергей Митрошин says:

    Прежде всего, надо разобраться – это проблема ZF или сервера.
    Попробуй подключиться к mysql через PDO напрямую, без ZF-адаптера. Если сработает, попробуй обновить ZF. Не сработает – значит надо разбираться с сервером.

  182. Drex says:

    действительно проблема не в zf, отдельно от zf создал пхп файлик с таким текстом
    getMessage();
    }
    ?>
    получил такую ошибку
    Warning: PDO::__construct(): [2002] Попытка установить соединение была безуспешной, т.к. от другого (trying to connect via tcp://localhost:3306) in Z:\www\localhost\index.php on line 7 Fatal error: Maximum execution time of 30 seconds exceeded in Z:\www\localhost\index.php on line 7
    Сергей, подскажите где можно полечить PDO?

  183. Drex says:

    try {
    $dbh = new PDO(“mysql:host=$hostname;dbname=mysql”, $username, $password);
    echo “Соединение установлено”;
    }
    catch(PDOException $e)
    {
    echo $e->getMessage();
    }

  184. Сергей Митрошин says:

    Похоже, проблема с MySQL

  185. Drex says:

    как то можно это исправить? да и странно как то и дома и на работе таже проблема

  186. Сергей Митрошин says:

    Понятия не имею, если честно. Попробуй погуглить эту проблему

  187. Drex says:

    На работе и правда как вы говорили не был перезапущен апач после изменения php.ini, теперь все норм заработало, а дома прийдется поискать проблему. Сергей, огромное спасибо за помощь

  188. Drex says:

    Возник еще одни вопрос по использованию ajax и zend. Я хочу следать на ajax редактирование таблици ‘на лету’ тоесть при клике мышкой по названию должно открыватся окошко редактирования, и соответственно после сохранения данные передвались в базу. Я решил использовать prototype.js scriptaculous.js, но почему-то мои javascriptы не стабатывают на странице \application\views\scripts\index\index.phtml
    сергей, прочитал вашу статью по использованию ajax но не совсем понял что к чему, могли бы вы подсказать как можно осущестивить это редактирование?

  189. Drex says:

    все это редактирование на ajax у меня отдельно от zendа работает, я не могу понять как мне совместить мой работающий ajax с zend?

  190. Drex says:

    На вас последняя надежда. поставлю вопрос более конкретно. Прочитав статью по подключению ajax я понял что у меня еще не доходит дело до передачи данных. У меня на странице сначала с помощью javascript сщздается элемент, но он почему то не работает, ниже приведу код (я взял ваш пример только использовал другую БД)\application\views\scripts\index\index.phtml, подскажите что я делаю не так, может пити к файлам js указываю не правельно, или может вообще так делать нельзя? и где про это почитать можно? толком ничего и не нагуглил

  191. Drex says:

    <a href="url(array(‘controller’ => ‘index’, ‘action’ => ‘add’)) ?>”>Add new person

    Name
    Second Name
    Email
    Phone
    Date

    persons as $person) :
    $i++;
    ?>

    <div class='itemValue' onclick="closeOtherEditors()” id=”itemId_escape($person->id); ?>”>escape($person->name) ?>
    escape($person->second_name) ?>
    escape($person->email) ?>
    escape($person->phone) ?>
    escape($person->date) ?>
    escape($person->photo) ?>

    <a href="url(array(‘controller’ => ‘index’, ‘action’ => ‘edit’, ‘id’ => $person->id)) ?>”>Edit
    <a href="url(array(‘controller’ => ‘index’, ‘action’ => ‘delete’, ‘id’ => $person->id)) ?>”>Delete

    editors.push(addEditor(“itemId_escape($person->id);?>”,
    “escape($person->id);?>”));

  192. Drex says:

    как здесь по человечески код вставить?

  193. Drex says:

    немного разобрался, но столкнулся с проблемой у меня на странице \application\views\scripts\index\index.phtml срабатывает java функция
    function addEditor(item, id) {
    return new Ajax.InPlaceEditor(item,
    “../application/controllers/IndexController.php”,
    {
    formId: “listForm”,
    okText: “Update”,
    cancelText: “Cancel”,
    highlightcolor: “#ffffff”,
    size: “30″,
    savingText: “Saving…”,
    callback: function(form, name) {
    return “name=” + name + “&id=” + id;
    }
    });
    }
    которая методом post передает данные на стр. IndexController.php. В обработчике indexAction() я обрабатываю эти данные
    if ($this->getRequest()->isPost()) {
    $formData = $this->getRequest()->getPost();
    $form->isValid($formData);
    $id = (int)$form->getValue(‘id’);
    $name = $form->getValue(‘name’);
    $persons = new Application_Model_DbTable_Persons();
    $persons->updateName($id, $name);}
    но получаю такую ошибку
    Fatal error: Class ‘Zend_Controller_Action’ not found in C:\myweb\localhost\people\application\controllers\IndexController.php on line 3
    подскажите что я делаю не так?

  194. Drex says:

    хелпер в public function init() я активировал
    $this->_helper->AjaxContext()->addActionContext(‘index’, ‘json’)->initContext(‘json’);

  195. Drex says:

    Возник еще один вопрос по поводу формы, локально мой скрипт работает норм, а вот когда я его развернул на другом сервере закачав файлы по ФТП, при нажатии на “add” или “edit” форма перестала отображатся
    выдает такую ошибку
    Add new album
    An error occurred
    Application error
    полдскажите в чем может быть проблема?

  196. ivanych says:

    Поставил по вашей статье ZF 1.11.1, получил приветствие ZF, создал три дополнительных действия и скрипты создались сами. Но при попытке тестировать в браузере ошибка 404.
    Apach рабочий, на нём хорошо тестируется мой php сайт, сто раз проверил рекомендуемые настройки httpd.conf, вроде всё правильно.
    Конечно я имею очень мало опыта, этими вопросами занимаюсь меньше года, а ZF только начал, да и возраст уже за 60, но очень интересно.
    Если возможно помогите пожалуйста.
    Спасибо.

  197. wa1 says:

    ОЛОЛО, вам не больше 18, судя по пунктуации.

  198. Сергей Митрошин says:

    ivanych, похоже, некорректно работает mod_rewrite – он должен все запросы, кроме статичных файлов (картинок, стилей и т.п.) перенаправлять на index.php

  199. safonoff says:

    Не подскажете, как внутри контролера преобразовать строку вида:
    $url = ‘http://localhost/public/index/about’
    в массив вида:
    Array
    (
    [controller] => index
    [action] => about
    [module] => default
    )
    ?
    Кода делаю так:
    $request = new Zend_Controller_Request_Http($url);
    print_r($request->getParams());
    , поучаю пустой массив.
    Спасибо

  200. Ольга says:

    Автору огромное спасибо! Делаю первые шаги в ZF
    Помогите решить вопрос!
    Если в данном примере в названиях альбомов и исполнителей использовать русский текст в браузерах Opera и Mozilla в конце русских слов появляется ненужный символ (квадрат или знак вопроса)
    База данных в utf8_general_ci.
    Если не использовать escape, то символ не появляется, но я как понимаю это не совсем решение вопроса.
    Может кто подскажет почему появляется этот символ и как от него избавится?

  201. ivanych says:

    Ольга, почитайте здесь:
    и всё станет на свои места

  202. Сергей says:

    Здравствуйте, у меня вопрос по редактированию альбомов, а именно про заполнение формы:
    $form->populate($albums->getAlbum($id));
    Насколько я понимаю метод populate объекта $form должен принимать одномерный массив, в котором ключи это названия полей, а значения, это значения этих полей, а $albums->getAlbum($id) возвращает двумерный массив:
    Array
    (
    [0] => Array
    (
    [id] => 1
    [artist] => Paolo Nutine
    [title] => Sunny Side Up
    )

    )
    Т.е. наверное правильно будет написать так:
    $album = $albums->getAlbum($id)
    $form->populate($album[0]);

  203. Сергей says:

    Поправочка, ошибся…
    $album = $albums->getAlbum($id);
    Не поставил точку с запятой.

  204. Сергей says:

    Так же у меня еще вопрос, зачем в файле формы нужно писать так:
    public function __construct($options = null)
    {
    parent::__construct($options);
    если можно использовать стандартную запись созданную Zend Tool.
    public function init()
    {

  205. Сергей says:

    При удалении такая же проблема как и при редактировании:
    $this->view->albums = $albums->getAlbum($id);
    работать не будет, так как передает многомерный массив, пишу так:
    $album = $albums->getAlbum($id);
    $this->view->albums = $album[0];

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

  206. Сергей says:

    Извиняюсь за свою невнимательность, в модели заместь $row = $this->fetchRow(‘id = ‘ . $id); написал $row = $this->fetchAll(‘id = ‘ . $id);
    Все работает как нужно, большое спасибо автору за хороший материал.

  207. Андрей says:

    Я бы для начинающих поставил бы в application.ini эту строку так
    resources.frontController.params.displayExceptions = 1
    Мне это помогло выявить ошибку подключения к БД! А до этого долго мучился.
    Хотелось бы что бы все примеры zf сопровождались бы какими то наглядными примерами без использования zf хотя бы теоретическими. Для меня визуальное сравнение дает большее понимание структуры приложения

  208. Андрей says:

    Что значит в тексте “инстанцируем”?
    Спасибо

  209. Андрей says:

    Помогите начинающему. Все сделал как написано выше, но работает только удалить. Добавить и редактировать не работают. Подскажите где копать и как отлавливать ошибки?
    Заранее спасибо

  210. Андрей says:

    Все получилось, только фигня все это.
    Как можно писать туториал для начинающих когда написано одно, а в zip архиве другое(album.php – поправьте как в zip-архиве). Оно ведь так нихрена не работает и главное непонятно почему.
    Жаль потерянного дня. Нельзя так делать.

  211. Владимир says:

    Спасибо за статью!

  212. Сергей says:

    Категорически не согласен с Андреем, сам по невнимательности понаписывал кучу коментов, автор все сделал правильно. Статья супер, от автора ждем продолжения!
    P.S. Андреем почитайте про ООП в PHP и только потом начинайте изучать Zend Framework. Хочу посоветовать сначала попробовать освоить CodeIgniter, он и проще в изучении и больше документации на русском, да и в ООП и MVC освоитесь.

  213. Андрей says:

    Сергею: ООП я читал, но я начинающий и смотрю со стороны начинающего. Поэтому мои проблемы больше понятны начинающим, а не таким как вы. Если, как вы говорите автор сделал все правильно(наверное), то объясните мне почему листинг кода в статье относящийся к album.php отличается от содержимого что в zip архиве. А из-за этого и не работает и в статье нет обьяснения того какие изменения сделаны и главное зачем.
    Ну да ладно, это все к делу не относится. Zend Framework тяжел в изучении.
    Код мне например понятен, то какие методы вызываются, какие члены обьекта получают значения, а вот почему это происходит не совсем ясно. Проще надо бы писать, да и пояснения прямо в коде лично мне более понятны.
    Ну да ладно, это все скулеж начинающего, разберемся сами не берите в голову !!!!

  214. empty says:

    Познакомился с ZF с помощью вашего этого руководства, все работает. Несколько сложно для первого опыта, но надеюсь скоро это преодолею. Спасибо!

  215. wr120 says:

    headLink()->prependStylesheet($this->baseUrl().’/css/site.css’); ?>
    Используя метод appendStylesheet() помощника headLink(), мы можем добавить дополнительные, более специфичные CSS-файлы в скриптах вида контроллера, которые будут выведены в секции после site.css.

    Нестыковочка

  216. oldman says:

    кто как заменяет стандартные сообщения Валидаторов в Zend_Form ?
    например если поле в форме не заполнено, получим сообщение: Value is required and can’t be empty
    хочу заменить, например на: “Не заполнено поле”
    Хотелось бы увидеть самое простое решение, но правильное с точки зрения идеологии ZF )

  217. oldman says:

    например, такой валидатор для фамилии:
    ‘validators’ => array(
    array(‘regex’, false, ‘/^([a-zA-Z\x80-\xFF]+)(\-{0,1})([a-zA-Z\x80-\xFF]+)$/i’)
    )

    ну, для чего показывать сообщение, если он ошибся
    ‘Иванов6′ does not match against pattern ‘/^([a-zA-Z\x80-\xFF]+)(\-{0,1})([a-zA-Z\x80-\xFF]+)$/i’
    ??

    пользователь получит травму психологическую 100%

  218. Oldman says:

    Спасибо автору статьи, подсказал.
    Look at “Messages” option for addElement

    $validator = new Zend_Validate_Regex(‘/^([a-zA-Z\x80-\xFF]+)(\-{0,1})([a-zA-Z\x80-\xFF]+)$/i’);
    $validator->setMessage(
    ‘Покайтесь!’,
    Zend_Validate_Regex::NOT_MATCH
    );

  219. Laz says:

    Помогите разобратся!!!?
    Fatal error: Uncaught exception ‘Zend_Db_Table_Exception’ with message ‘No adapter found for Application_Model_DbTable_Albums

  220. Fastto says:

    В подразделе “Добавление новых альбомов” ошибка – “…который расширяИт…”, правильно “расширяет”

  221. namelesscoder says:

    Строка
    $this->setName(‘album’);
    вызывает ошибку Only form elements and groups may
    be overloaded; variable of type “string” provided.
    корректынй вариант записи выглядит так:
    $this->setAttrib(‘Name’,'album’);
    версия Zend 1.11.4

  222. deex_iv says:

    Спасибо, помогло разобраться.

  223. CyberKatze says:

    Спасибо за статью! Объяснено более менее хорошо. После пары кружек кофе все встало на свои места!.

    Единственное для автора…
    Не могли бы вы, дабы избежать большого кол-ва комментариев, добавить исправления и дополнения к статье, такие как добавка/раскомментирование pdo_mysql.dll в php.ini файл и некоторые другие исправления внесенные комментаторами!

    Спасибо!

  224. Jimmy Mohito says:

    Спасибо за статью.

    Единственное, заметил ошибочку, сначала вы говорите, что файл layout.phtml лежит в папке applications/layouts/scripts, а потом, когда говорите про стилизацию, он у Вас уже лежит в папке applications/layouts. Здесь пропущена папка scripts

    А так, получилось =) Правда, тоже с автолоадером помучался. Было бы неплохо дополнить статью более конкретными примерами работы автолоадера и размещения + именования файлов

  225. ML says:

    Да, статья хороша.

    А подскажите пожалуйста как сделать многостраничную форму на Zend Framework ?
    то есть:
    - заполняем поля на первой странице, нажимаем кнопку “Далее” (при этом поля проверяются на валидность)
    - заполняем форму на второй странице (аналогично проверяются)
    - и заполняется поля на 3-й последней странице. И если всё ок – то добавляются данные в БД со всех полей всех страниц.

  226. King_Artes says:

    Обьясните пожалуйста, где можна установить virtualhost прописаный в начале статьи. Непонял в каком файле это нужно прописывать

  227. King_Artes says:

    Уже нашел )

  228. Oldman says:

    А подскажите пожалуйста как сделать многостраничную форму на Zend Framework ?
    то есть:
    - заполняем поля на первой странице, нажимаем кнопку “Далее” (при этом поля проверяются на валидность)
    - заполняем форму на второй странице (аналогично проверяются)
    - и заполняется поля на 3-й последней странице. И если всё ок – то добавляются данные в БД со всех полей всех страниц.

    почитай про куки и про сессии

  229. ML says:

    Oldman:
    почитай про куки и про сессии

    Zend_Session_Namespace?

  230. Asel says:

    Вопрос у меня относительно встроенной командной строки зенда. Не могу понять как создавать через нее действия для контроллера какого либо модуля. У меня модульное разделение в проекте обязательно должно быть. В зенде я новичок, настраивать пришлось много. По вашему туториалу уже поработала, все работает. Тока вот к модулям не знаю с какой стороны подобраться :(

  231. Anton says:

    А в каком месте после $application->bootstrap()->run(); перехватывается и разбирается http запрос?

  232. Ruslan says:

    Менял я и файлы на utf-8 (хотя и менять было нечего, все было нормлаьно).
    Нашел проблему в Денвере.
    Дописал в .htaccess AddDefaultCharset UTF-8 и проблема с русскими (кирилицей) пропала.

  233. Jeckz says:

    Tirei says:

    Warning: require_once(Zend/Application.php) [function.require-once]: failed to open stream: No such file or directory in Z:\home\localhost\www\zf-tutorial\public\index.php on line 18

    Fatal error: require_once() [function.require]: Failed opening required ‘Zend/Application.php’ (include_path=’Z:\home\localhost\www\zf-tutorial\library;.;/usr/local/php5/PEAR’) in Z:\home\localhost\www\zf-tutorial\public\index.php on line 18

    То же самя ошибка, как ее исправить не могу понять
    27 мая 2010, 11:49
    Tirei says:

    блин я идиот, все там рассписано!

    Я похоже еще больше идиот, ткните носом, где там расписано. Пожалуйста. Вот не находит он Application.php и все тут, где и как надо ему путь указать?

  234. Jeckz says:

    Когда создаю проект у меня сообщение выводится:

    Warning: call_user_func_array(): Unable to call Zend_Tool_Project_Provider_Proje
    ct::getDefaultReadmeContents() in C:\Program Files\ZendFrameworkCli\library\Zend
    \Tool\Project\Context\Filesystem\File.php on line 166
    Creating project at D:/Documents/localhost/zftest
    Note: This command created a web project, for more information setting up your V
    HOST, please see docs/README
    Testing Note: PHPUnit was not found in your include_path, therefore no testing actions will be created.

  235. Sergey says:

    Отличная статья! Когда то с нее начинал)

  236. Alex says:

    Мне требуется законектится к 2 базам на разных серваках как быть?

    и вид ссылок нужен такой:
    site/album/artist/song/id/5555
    и же
    site/artist/song/id/5555
    и же
    site/song/id/5555
    и же
    site/id/5555

    как быть?
    похоже на лажу с этим ZF
    руками такое просто пишется.

  237. volkulion says:

    если команда zf create form Album завершается ошибкой, посмотрите есть ли в файле. zfprogect.xml строка
    если нет добавьте ее после

    мне помогло

  238. Dimok says:

    Zabi says:
    Подскажите плс, встал на шаге после создания экшенов, неработают ссылки типа

    но заходит с необходимым результатом на ссылки типа

    теперь на шаге создания динамичных ссылок echo $this->url(array(‘controller’ => ‘index’, ‘action’ => ‘add’)) немогу сгенерировать необходимые ссылки, перерыл кучу инфы но не могу найти ответ на вопрос: как сделать так чтобы не нужно было писать в адресе index.php, или написать функцию для создания правильных ссылок.
    в httpd.conf AllowOverride All прописано и LoadModule rewrite_module modules/mod_rewrite.so раскомментировано

    точно такаяже проблема! пол дня убил(((( что не так? HELP ME!!!

  239. Dimok says:

    никто не знает, что это?

  240. Сергей Митрошин says:

    Dimok, проблема в mod_rewrite – все запросы должны перенаправляться на index.php, этого не происходит.

  241. Володя says:

    Здраствуйте, та же проблема что и у многих других

    Fatal error: Class ‘Application_Model_DbTable_Albums’ not found in C:\xampp\htdocs\projects\zend.local\www\application\controllers\IndexController.php on line 19

    Решения не нашел ни тут ни в других постах.
    Буду благодарен за помощь.

  242. Mac says:

    Друзья, у кого ошибка:
    Fatal error: Class ‘Application_Model_DbTable_Albums’ not found in C:\xampp\htdocs\projects\zend.local\www\application\controllers\IndexController.php on line 19

    Сам ломал голову, потом дошло. Этот дурацкий Zend Tool почему-то не скопировал в папку library папку Zend из дистрибутива (не понятно, зачем тогда она лежит в Program Files/ZendFrameworkCli…). Сделайте это, и заработает.

    Вообще автор статьи очень халатно подошел к написанию мануала, т.к. сам намучался с одной только установкой этого фреймворка. Кроме вышеназванной ошибки помучался с “php.exe не является внутренней или внешней программой” – о ее решении тоже ни в одном руководстве ни слова – еле нагуглил. Если у вас такая же проблема, открывайте Program Files\ZendFrameworkCli\bin\zf.bat блокнотом и указывайте верный путь до php.exe в строке, где он определяется (по умолчанию там просто php.exe).

    Никогда раньше этап установки ни движков, ни фреймворков не вызывал столько проблем. А все в недостаточном качестве руководств.

    Надеюсь, мой комментарий сэкономит кому-то время и нервы.

  243. Seryoga says:

    Мдааа, с установкой и настройкой постоянные траблы. Лично я остановился на связке денвер-зф. Ставил всё как здесь написано . Может кому пригодиться.

  244. Seryoga says:

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

  245. Стас says:

    почему то при нажатии на “добавить альбом” у меня вылазит “View script for controller Index and script/action name add” вместо формы..хотя все сделал ну 100% по инструкции)

  246. TaurusSoft says:

    Стас says, скрипт явным же образом ругается на то что у вас нет файла вида “add.phtml” в директории “script”

  247. Стас says:

    он есть. и в нем прописана строка View script for controller Index and script/action name add

  248. Стас says:

    при чем он не ругается а просто выводит то, что было в файле сразу после создания действия

  249. Стас says:

    Add new album

    View script for controller Index and script/action name add

    вот так выводит точнее

  250. TaurusSoft says:

    Где именно у вас лежит файл вида add.phtml? Он должен находить в scripts/[Название контроллера]/[Название действия].phtms
    Если это не поможет, создайте другой контроллер, в нем создайте действие(action) и потом уже файл вида для действия, потом с помощью браузера откройте корректный адрес, т.е. . В этом случае главное понимание структуры MVC, а начинка контроллера не важна.

  251. Стас says:

    все разобрал)просто не заметил одну строчку кода)

  252. TaurusSoft says:

    Бывает и такое… Удачного освоения Zend Framework!!!

  253. Стас says:

    спасибо=)

  254. Никита says:

    Толково описано, все продумано… Но это кажется достаточно жестким (не гибким) по сравнению с Kohana.

  255. Aleks says:

    Спасибо огромное за статью.
    Все получилось, до вывода альбомов
    Fatal error: Class ‘Applications_Models_DbTable_Albums’ not found in Z:\home\myzend.fr\applications\controllers\IndexController.php on line 14.

    Все перепробовал. И все равно выдает такую ошибку. :(
    А если перейти на выдает
    Some error happened!

    В чем может быть проблема?

  256. Aleks says:

    Спасибо!
    Все работает!

  257. Andrii says:

    Все прошел, работает. Большое спасибо.

  258. Ann says:

    Моя проблема была уже рассмотрена,но все предложенные способы не помогли(
    В пункте “Вывод альбомов”, вместо списка альбомов появляется следующее:

    My Albums
    An error occurred
    Application error

    Подскажите пожауйста, где может быть ошибка?

  259. Ann says:

    Разобралась, не работало из-за паролей)

  260. Alex says:

    Все получилось! Но вот в русским языком в названиях музыкантов и альбомов не сложилось – какие-то одни вопросики.

  261. Владимир says:

    Спасибо все работает

  262. Dahanavar says:

    У меня выдает ошибку, что не может найти php5.dll
    Это при настройке zend tools когда ввожу проверку на версию зенда.

  263. Dahanavar says:

    Это на Windows XP

  264. Dahanavar says:

    Проблема решена. Проблема была в том, что путь к php был прописан в переменных среды в path нормально, но в переменной php не к тому ресурсу. Будте внимательны, что путь к пхп может быть прописан не только в path но и может быть отдельная переменная php и phprc.

  265. Dahanavar says:

    Ребят, помогите. В IndexController добавил action add был создан скрипт вида add.phtml, но при обращении домен\index\add выдает 404 ошибку.
    LoadModule rewrite_module modules/mod_rewrite.so раскоменчен на апаче.
    Прописано в виртуал хостах:

    Options Indexes MultiViews FollowSymLinks
    AllowOverride All
    Order allow,deny
    Allow from all

    Но init в indexcontroller отрабатывает.
    Может кто встречался с такой проблемой, подскажите решение ибо 4-й день перелопачиваю инет пока что никаких успехов.

  266. Dahanavar says:

    Проблема решена.

  267. aaa says:

    Про FF и “Чтобы отобразить эту страницу, Firefox должен отправить информацию, которая повторит любое ранее произведённое действие (например, запрос на поиск или онлайн-покупка)”
    Сделал форму, у меня в опере всё замечательно, а у заказчика ФФ ругается и заказчик нервничает… победил вставкой в форму следующего кода:
    <input type="hidden" value="”>

  268. pavel says:

    В общем ответ на вопрос “Fatal error: Class ‘Applications_Models_DbTable_Albums’ not found in …”!
    Посмотрите внимательно как вы обьявили свои классы!!!
    У меня эта ошибка возникла из-за того что я вместо “Applications_Models_DbTable_Albums” назвал класс “Aplications_Models_DbTable_Albums”!!!
    из-за этого 3 часа было потрачено на чтение разной ненужной информации

Leave a Reply

info@zend-framework.ru