Объявление блока zend модуля


Содержание

htmllab

Создание модуля Zend Framework 2.4

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

Zend Framework создание модуля

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

Модуль приложения для работы с альбомами содержит указание на пространство имён, перечень используемых компонентов, указываются реализуемые интерфейсы, стандартные методы модуля (в рамках ZF2.4)
getAutoloaderConfig() и getConfig() . Первый возвращает массив элементов, совместимых с AutoloaderFactory , а второй просто загружает данные из файла config/module.config.php .

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

Добавить комментарий Отменить ответ

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

Пример разработки блога на Zend Framework 2. Часть 2. Модуль MyBlog

Это вторая из 3 частей статьи, посвященной разработке простого приложения при помощи Zend Framework 2.В первой части я разглядел конструкцию ZendSkeletonApplication, а в этой части приведу пример разработки простого модуля. Третья часть будет посвящена работе с пользователями и шаблонизатором Twig.

Установка и настройка дополнительных модулей

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

  1. добавляем соответствующую строчку в composer.json, Дабы известить Композеру о новом модуле,
  2. исполняем команду php composer.phar update, Дабы Композер загрузил новейший модуль и при необходимости перегенерировал автолоад файлы,
  3. добавляем новейший модуль в список modules в файле config/application.config.php,
  4. при необходимости, размещаем конфигурационный файл модуля (обыкновенно пример такого файла находится в папке config модуля) в config/autoload и делаем в нем нужные правки.

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

Давайте начнем с установки простого, но пригодного модуля Zend Developer Tools.

Zend Developer Tools

Zend Developer Tools — это комфортный тулбар, содержащий пригодную для разработчика информацию о сделанной странице: число и список запросов к БД, список ролей нынешнего пользователя, использованные Entity, загруженная конфигурация сайта и т.д. Разумеется, тулбар может быть расширен всякий иной вспомогательной информацией. Обнаружить его дозволено здесь:github.com/zendframework/ZendDeveloperTools.

Дабы установить тулбар вначале добавим строчку:

в файл composer.json в корне плана и после этого исполним команду php composer.phar update в корне плана.

После этого в файл config/application.config.php в массив modules необходимо добавить элемент ZendDeveloperTools:

Сейчас осталось скопировать файл vendor/zendframework/zend-developer-tools/config/zenddevelopertools.local.php.dist в папку config/autoload нашего плана и переименовать его, скажем, в zenddevelopertools.local.php (часть имени до local.php по огромному счету значения не имеет).

Всё, сейчас, по умолчанию, внизу всех страниц выводится информация о затраченных на генерацию страницы источниках, конфигурация плана и т.п.

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

Нынешняя версия приложения доступна на Гитхабе в репозитории плана с тэгом zenddevelopertools:github.com/romka/zend-blog-example/tree/zenddevelopertools

Doctrine ORM

Для интеграции с Концепцией потребуются модули DoctrineModule и DoctrineORMModule (https://github.com/doctrine/DoctrineModule и github.com/doctrine/DoctrineORMModule).

Добавим в секцию require файла composer.json строчки:

и исполним в консоли команду php composer.phar update.

Модуль DoctrineModule дозволено не указывать очевидно в нашем composer.json, так как эта связанность прописана на ярусе модуля DoctrineORMModule.

Сейчас необходимо в директории config/autoload поместить файл doctrine.local.php с параметрами доступа к БД, тот, что будет применяться Концепцией, его содержимое должно быть приблизительно таким:

Сейчас если мы перезагрузим страницу нашего сайта, то внизу страницы в Zend девлопер тулбаре увидим два новых блока, показывающих число исполненных запросов и список маппингов к БД. Оба значения равны нулю, так как маппинги мы пока не сделали и, как следствие, запросов к базе нет.

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

Модуль MyBlog

В каталоге modules сделаем следующие директории и файлы:

Содержимое файла Module.php должно быть таким:

Файл аналогичен тому, что применяется в модуле Application, мы говорим ядру фреймворка где искать конфигурационный файл модуля и файлы исходников.

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

Файл src/MyBlog/Entity/BlogPost.php является связью (маппингом) между Концепцией и базой данных и о нем необходимо побеседовать подробнее.

BlogPost.php

Всякий блогпост в моем примере будет содержать следующие поля:

  • заголовок,
  • тело блогпоста,
  • id автора (0 для анонимов),
  • ранг (опубликовано/не опубликовано)
  • дата публикации.

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

Данный файл объявляет класс BlogPost, тот, что содержит изложения полей блогпоста и способов доступа к ним. Полную версию файла вы можете посмотреть на Гитхабе (https://github.com/romka/zend-blog-example/blob/master/module/MyBlog/src/MyBlog/Entity/BlogPost.php), вот так выглядит его часть:

Всякая переменная в этом классе станет полем в БД, параметры полей задаются в аннотациях, которые будут прочитаны Концепцией (приблизительно вот так: php.net/manual/en/reflectionclass.getdoccomment.php, классDoctrineCommonAnnotationsAnnotationReader способ getClassAnnotations()).

Сейчас в конфигурационный файл модуля config/module.config.php дозволено добавить информацию о нашей новойEntity, которая будет использована Концепцией:

И осталось добавить модуль MyBlog в список энергичных модулей в application.config.php.

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

И итогом должно быть сообщение вида:


Позже того как мы удостоверились в том, что Концепция видит наш объект BlogPost исполним команду:

В итоге должна возвратиться оплошность вида:

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

Её итогом будет дальнейший итог:

И сейчас вызов команды:

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

Начальные коды нынешней версии плана дозволено обнаружить в репозитории плана на Гитхабе с тэгомblogpost_entity: github.com/romka/zend-blog-example/tree/blogpost_entity.

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

Добавление блогпоста

В директории src/MyBlog модуля сделаем два новых каталога с файлами:

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

Исходя из заданных выше настроек, все страницы нашего блога будут иметь урлы вида blog/[action]/[id](элементы пути в квадратных скобках не непременны).

Файл BlogPostForm.php будет содержать форму, которая будет применяться для добавления/редактирования блогпоста, давайте сотворим эту форму.

BlogPostForm.php

В самом простом случае код формы будет выглядеть вот так (это не полный начальный код формы, целиком его дозволено увидеть здесь: github.com/romka/zend-blog-example/blob/master/module/MyBlog/src/MyBlog/Form/BlogPostForm.php):

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

BlogController.php

Важным для нас является код экшена addAction (имена всех экшенов обязаны создаваться по маске nameAction()). В нем мы вначале создаем объект формы и заменяем текст кнопки submit на ней (у нас одна и та же форма будет применяться и для создания, и для редактирования блогпостов, по этому тексты на этой кнопке комфортно иметь различные):

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

Если cейчас испробовать сберечь пустую форму, то Концепция вернет сообщение об ошибке вида:

Это верно, чай у нас есть только одно поле, помеченное как nullable=«true» — это поле state, а все остальные обязаны быть заполнены. Давайте добавим к форме инпут фильтры и валидаторы, Дабы перехватывать сходственные ошибки еще до попытки сберечь данные (на ярусе нашего приложения, а не БД), Дабы у пользователя была вероятность поправить ошибку.

Валидация форм

Полагаю, что толк этих строк должен быть подсознательно внятным: для полей title и text мы добавляем инпут фильтры, которые удалят из текстов все html тэги (фльтр StripTags) и обрежут пробелы по краям строк (StringTrim), а также добавляем валидаторы, определяющие значения минимальной и максимальной длины полей (StringLength).

Осталось присоединить новейший фильтр к форме, добавив в класс формы строчку:

Сейчас форма не пройдет валидацию, если в нее введены некорректные данные.

View плагины

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

Добавить такие сообщения дозволено с поддержкой способов:

Извлечь сообщения, добавленные таким методом, дозволено в контроллере либо в phtml-образцах таким образом:

Задача в том, что неудобно (а в Twig-образцах, которые мы будем применять позднее, и совсем немыслимо) вызывать PHP-код для итога сообщений. По этому мы напишем маленький View-плагин, тот, что сумеет одной строчкой выводить на экран все сообщения.

Для этого в директории srcMyBlog модуля сделаем такие директории и файлы:

Содержимое ShowMessages.php дозволено посмотреть здесь: github.com/romka/zend-blog-example/blob/master/module/MyBlog/src/MyBlog/View/Helper/ShowMessages.php, оно не дюже увлекательно, я тут легко получаю список сообщений, форматирую и возвращаю готовый html-код для их отображения.

Осталось сделать три действия:

  1. зарегистрировать View-плагин,
  2. добавить его применение в образец,
  3. и вывести сообщения о успешном/неудачном сохранении формы.

Дабы зарегистрировать плагин добавим в настройки модуля в сецкию view_helper => invokables строчку:

В образцы добавим итог сообщений:

Для итога сообщений на экран добавим в контроллер такие строчки:

Сейчас у нас есть вероятность выводить пользователю системные сообщения.

Эту версию приложения вы можете обнаружить в гит-репозитории с тэгом blogpost_form_1:github.com/romka/zend-blog-example/tree/blogpost_form_1.

На нынешнем этапе у нас есть:

  1. сущность для связи приложения и БД, сделанная при помощи Концепции,
  2. контроллер обслуживающий страницу добавления блогпоста,
  3. форма добавления блогпоста с инпут фильтрами и валидаций,
  4. свой кастомный View-плагин для итога сообщений на экран.

Сейчас давайте добавим страницы одного блогпоста, списка блогпостов и формы редактирования/удаления поста.

Страница блогпоста

Добавим в контроллер BlogpostController новое действие view:

Данный экшен доступен по адресу blog/view/ID. В нем мы вначале мы проверяем, что в URL’е задан id блогпоста, если это не так, то возвращаем ошибку и редиректим пользователя на страницу со списком блогпостов. Если id указан, то мы извлекаем пост из базы и передаем его в образец.

В качестве имени образца по умолчанию применяется имя контроллера, по этому сейчас в директории модуля view/my-blog/blog необходимо сделать файл view.phtml с приблизительно вот таким содержимым:

Список блогпостов

Обновим код нашего indexAction до такого вида:

Тут мы выбираем все опубликованные блогпосты (state == 1), сортируем их по дате публикации и передаем в образец index.phtml github.com/romka/zend-blog-example/blob/blogpost_form_2/module/MyBlog/view/my-blog/blog/index.phtml. В образце выводятся заголовки блогпостов и ссылки на их редактирование и удаление.


Малое отхождение

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

Помимо того, я добавил к форме Csrf-токен (поле security), тот, что должен защитить форму от подделки. По умолчанию данный токен формируется на основании пользовательской сессии и соли и живет 300 секунд (ZendFormElementCsrf.php), но может быть (и по классному должен быть) переопределен и к нему как минимум должна быть добавлена связанность от ip посетителя.

Редактирование блогпоста

Для редактирования поста мы будем применять теснее существующую форму. В контроллере нужно сделать действие editAction(), которое будет создавать форму, наполнять её существующими данными и отдавать пользователю. Данный экшен является смесью addAction(), в части работы с формой, и viewAction(), в части выборки данных github.com/romka/zend-blog-example/blob/blogpost_form_2/module/MyBlog/src/MyBlog/Controller/BlogController.php#L95.

Вот самая увлекательная часть этого контроллера:

Тут мы загружаем из БД блогпост, базируясь на id, тот, что пришел в форме, обновляем данные:

и кладем обновленный блогпост в базу:

Удаление блогпостов

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

Исходники с тэгом blogpost_form_2 (https://github.com/romka/zend-blog-example/tree/blogpost_form_2) содержат формы редактирования и удаления блогпоста, список постов и соответствующие образцы.

Илон Маск рекомендует:  Регулярные выражения в mysql

На этом я бы хотел закончить вторую часть статьи. В третьей части мы займёмся работой с пользователями и прикрутим к плану шаблонизатор Twig.

CMS на ZendFramework?

Собственно сабж, сейчас используем TomatoCMS:

1) она заброшенная,

2) писать невозможно,

3) дедлайны не совпадают с теми килограммами кода которые нужно написать для простого функционала.

Кто с чем работал? Какие предложения?

  • Вопрос задан более трёх лет назад
  • 6655 просмотров

Недавно, хотел сократить время разработки при помощи CMF. Делаем тоже на Zend.
Перебрал штук 10 разных. Смотрел код так, чтобы он был прилично написан.
Очень понравилась вот эта разработка. habrahabr.ru/blogs/zend_framework/84313/
и ещё одна (ссылку сейчас не вспомню, т.к. из дома)

Для моих задач проще по простому накидать каркас самому. Тащить ворох лишних библ, а потом за них отвечать, как-то не захотелось.

Если вас заставили использовать ZF, но это не значит, что нужно использовать только ZF. Если какие-то компоненты вас не устраивают, то проще сменить их на сторонние…

Например, если вас не устраивает Zend_Db — Прикрутите Doctrine
Для рассылки почты, например, я использую swiftMail. Получилось проще, чем решение Zend_Mail + Zend_Queue
и так далее…

Хотя в Zend есть не плохие модули, а есть такие, код которых у меня вызывает содрогание.
Короче, тут нужен здоровый прагматизм.

PS. Посмотрите идеологию Symfony 2) Очень симпатично.

PS2: Zend_Tool + всякие кодогенераторы тоже могут быть полезны, т.к. ускоряют разработку.

И ещё, килограммы коды писать всё-равно придется. Это же Zend. Там много всяких кубиков разного размера, между которыми нужно писать связки, пусть даже примитивные, но их приходится писать.

Так что совет, увеличивайте трудоемкость. Введите какую-нибудь систему оценки трудоемкости.
мы недавно оценивали в попугаях, получилось более адекватно, чем в человеко-часах.
Идея такая, выбираете какую-нибудь самую простую задачу. Пусть это будет скрипт генерации бреда.
А далее считайте, написание такой-то логики займет 10 скриптов генерации бреда.
Такая оценка получается точнее. пробовали на нескольких разных программистах, все они оценивали так точнее.
так получается потому, что оценивается сразу сложность задачи без прикидки сколько делать. А из сложности сразу следует время автоматом.

Конкретно в том проекте не меняли.
Да в Zend_Form есть такие моменты, которые сложно обходить.
Если очень сильно нужно, то попробуйте Symfony2 forms в связке с Doctrine ORM.
Эти формы меня гораздо больше радуют. Но как их прикручивать к Zend — вопрос, там некоторые фишки могут сойти на нет (например, когда данные берутся автоматически из реквеста сразу в модель, хотя если помучаться, то и это можно прикрутить). Всё зависит от ваших ожиданий.

я моих проектов пока хватало Zend_Form. Уж не такие там и сложные формы были.

Поделиться контроллерами модулей zend для использования в другом модуле

Предположим, у меня есть User_RegistrationController, и я хочу расширить его в следующем модуле:

но у меня есть ошибка PHP для этого:

Есть ли способ расширить контроллер из другого модуля?

Вы можете перевести свой базовый контроллер в отдельный класс библиотеки:

Тогда контроллер в модуле foo может быть пустым:

в то время как контроллер в bar модулей может содержать ваши переопределения:

Не забудьте добавить App_ в качестве App_ autoloadernamespace .

Автозагрузчик просто не настроен для поиска контроллеров из других модулей.

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

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

Zend Framework 3 перенаправление страницы из модуля приложения

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

Решение: про первой инициализации модуля, создаем событие onDispath, в котором смотрим куки, и если они нас не устраивают — меняем шаблон и перенаправляем на другой контроллер:

Комментарии:

Добавить комментарий Отменить ответ

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.


Объявление блока zend модуля

Неоднократно я сталкивался с мнением, что в мануале по Zend Framework очень мало туториалов, то есть в нем хорошо описаны отдельные классы, но тяжело разобраться как их использовать вместе. Сейчас я попытаюсь восполнить этот недостаток. Статья предназначена для начинающего и среднего уровня. После прочтения вы сможете создавать простые сайты на базе Zend Framework. В конце вы сможете скачать полноценный рабочий код мини сайта — примера, разработанного специально под статью. Код был протестирован на Zend Framework 1.5.2, php 5.2.0, mysql 5.0, apache 1.3

В сайте реализовано:

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

Старт

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

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

А вот так выглядит дерево папок сайта:

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

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

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

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

Не перенаправляются только запросы на реально существующие файлы, поэтому во избежание неприятных ситуаций сразу закрываем доступ в папку applications где расположены php файлы. Для этого кладем туда .htaccess запрещающий доступ к любым файлам.

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

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

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

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

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

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

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

Z end_Loader

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

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

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

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

Z end_Registry

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

Z end_Config

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

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

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

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

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

F ront контроллер

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

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

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

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

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

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

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

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

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

Работа с моделью практически не освещена в мануале, в файловой структуре предпологается папка models но не дается конкретных рекомендаций по ее и спользованию. Кроме того можно сказать что понятия модели в Zend Framework как такового нет. Реализация этой части MVC возлагается на плечи разработчика. Я рассматриваю модель как набор классов оперирующих с данными, это может быть получение данных, изменения данных, вставка данных в базу данных или другое хранилище. Я не допускаю составления и выполнения sql-запросов в классах контроллеров. Название каждого класса модели состоит из двух слов, самого названия сущности данных и слова «Model», по аналогии к названиям контроллеров. В рассматриваемом сайте-примере существует два класса модели, это PagesModel и ArticlesModel . В первом классе собраны функции работающие с сущностью «страница», во втором с сущностью «статьи». Классы модели являются наследниками Zend_Db_Table_Abstract. Методы работы с базой и пример класса модели смотрите ниже.

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

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

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

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

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

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


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

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

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

Илон Маск рекомендует:  Лекции по конструированию компиляторов литература

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

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

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

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

При создании объектов этих классов в Kernel.php я произвел небольшую настройку. Изменил расширение этих файлов на привычное tpl, и изменил название главного layout макета. Я дал ему привычное название «index»

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

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

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

Объявление блока zend модуля

Вам необходимо скачать файл

Разместить его на хостинге, далее распаковать его содержимое на хостинге в папке /home/[login]/Ваш_сайт/docs/ioncube.
Далее открыть страницу http://Ваш_сайт/ioncube и выбрать
ioncube-loader-helper.php в котором приведена инструкция.
Далее скопировать php.ini согласно
http://hosting.nic.ru/faq/php.shtml#q6, и внести в него строчку
указанную в инструкции IonCube.

Меню пользователя Павел Удовенко
Посмотреть профиль
Отправить личное сообщение для Павел Удовенко
Найти ещё сообщения от Павел Удовенко

Внимание! строку указанную в примере необходимо поместить НАД строкой:

06.04.2009, 09:55 #2
Меню пользователя Amalthea
Посмотреть профиль
Отправить личное сообщение для Amalthea
Найти ещё сообщения от Amalthea
04.07.2009, 11:30 #3
Меню пользователя paradox
Посмотреть профиль
Отправить личное сообщение для paradox
Посетить домашнюю страницу paradox
Найти ещё сообщения от paradox

Действительно. zend-то изначально установлен. Рекомендую администрации сделать то же и с йонкубом

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

10.07.2010, 15:39 #4
Меню пользователя vmato
Посмотреть профиль
Отправить личное сообщение для vmato
Найти ещё сообщения от vmato

Вам необходимо скачать файл

17.04.2011, 18:56 #5
Меню пользователя Autorun
Посмотреть профиль
Отправить личное сообщение для Autorun
Найти ещё сообщения от Autorun
24.04.2011, 18:10 #6
Меню пользователя nel-finger
Посмотреть профиль
Отправить личное сообщение для nel-finger
Посетить домашнюю страницу nel-finger
Найти ещё сообщения от nel-finger
02.04.2012, 04:17 #7
Меню пользователя AD-min
Посмотреть профиль
Отправить личное сообщение для AD-min
Посетить домашнюю страницу AD-min
Найти ещё сообщения от AD-min
02.04.2012, 04:29 #8
Меню пользователя AD-min
Посмотреть профиль
Отправить личное сообщение для AD-min
Посетить домашнюю страницу AD-min
Найти ещё сообщения от AD-min
31.08.2012, 08:21 #9
Меню пользователя megasales34
Посмотреть профиль
Отправить личное сообщение для megasales34
Посетить домашнюю страницу megasales34
Найти ещё сообщения от megasales34
01.09.2012, 08:18 #10
Меню пользователя Roxseo
Посмотреть профиль
Отправить личное сообщение для Roxseo
Найти ещё сообщения от Roxseo
15.12.2013, 20:38 #11
Меню пользователя RichArt
Посмотреть профиль
Отправить личное сообщение для RichArt
Найти ещё сообщения от RichArt

Добрый день. ioncube-loader-helper.php в архиве нет. попробовала разные версии php, но ionCube там нет.

сейчас стоит 5.3, но там этого модуля нет.

при попытке в /home/sleepnat/etc/php53.ini добавить строку zend_extension=/home/[login]/sitename/docs/ioncube/ioncube_loader_fre_*.2.so — нет строки с zend, перед которой необходимо ее разместить

Прошу помочь. Заранее спасибо.

п.с. договор 2486743/NIC-D

25.07.2020, 11:02 #12
Меню пользователя nastiywa
Посмотреть профиль
Отправить личное сообщение для nastiywa
Найти ещё сообщения от nastiywa
25.07.2020, 15:12 #13
Меню пользователя nel-finger
Посмотреть профиль
Отправить личное сообщение для nel-finger
Посетить домашнюю страницу nel-finger
Найти ещё сообщения от nel-finger

Добрый день. ioncube-loader-helper.php в архиве нет. попробовала разные версии php, но ionCube там нет.

сейчас стоит 5.3, но там этого модуля нет.


при попытке в /home/sleepnat/etc/php53.ini добавить строку zend_extension=/home/[login]/sitename/docs/ioncube/ioncube_loader_fre_*.2.so — нет строки с zend, перед которой необходимо ее разместить

Прошу помочь. Заранее спасибо.

п.с. договор 2486743/NIC-D

25.07.2020, 17:51 #14
Меню пользователя nastiywa
Посмотреть профиль
Отправить личное сообщение для nastiywa
Найти ещё сообщения от nastiywa

И снова про IonCube Loader. Требуется помощь.

В настройках PHP 5.3 предоставляется возможность установки IonCube Loader, но версии 40701. Данная версия для моих нужд никак не подходит. Требуется версия 5 (и выше). Как обновить?

В первом посте написана инструкция, но «Далее скопировать php.ini согласно
http://hosting.nic.ru/faq/php.shtml#q6″ — открывает главную страницу поддержки. Не могу понять согласно чему скопировать.

Отправил письмо в саппорт еще вчера, но до сих пор тишина.
1701679/NIC-D

18.08.2020, 19:23 #15
Меню пользователя Bergosio
Посмотреть профиль
Отправить личное сообщение для Bergosio
Найти ещё сообщения от Bergosio

Проблема решена. Все оказалось просто.Нужно было лишь подольше посидеть и вникнуть.

Кому нужно обновиться до пятой версии — делаем следующее:
1. Качаем пакет под FreeBSD 8 32 здесь http://www.ioncube.com/loaders.php.
2. Создаем на хостинге новую папку ioncube.
3. В созданную папку заливаем содержимое пакета.
4. В /home/[ACCOUNTNAME]/etc находим файл php53.ini ( это если ваша версия php 5.3) и копируем содержимое.
5. Создаем новый файл php.ini, куда вставляем содержимое файла php53.ini.
6. В коде данного файла находим строку: zend_extension=/opt/php/lib/php/extensions/ZendOptimizer.so и ПРЯМО НАД НЕЙ вставляем строчку: [ionCube]
zend_extension = /home/[ACCOUNTNAME]/[SITENAME]/docs/ioncube/ioncube_loader_fre_5.3.so
7. Сохраняем файл и заливаем его в /home/[ACCOUNTNAME]/
8. Вбиваем в адресную строку: [SITENAME]/ioncube и находим файл loader-wizard.php, жмакаем на него.
9. В окне выбираем тип сервера (в нашем случае — второй вариант с доступом к php.ini), название хостера: ru center, адрес: nic.ru. Далее.
10. Сервис сообщает какая версия ioncube loader установлена и что нужно сделать для обновления до пятерки. В моем случае мне было необходимо скачать новый пакет (он доступен на страничке ниже) и заменить уже имеющийся на хостинге файл ioncube_loader_fre_5.3.so на аналогичный из нового пакета. Заменил.
11. Перезагружаем сервер.
12. Радуемся и начинаем работать с пятой версией ioncube loader.

Вроде все описал.

19.08.2020, 04:05 #16
Меню пользователя Bergosio
Посмотреть профиль
Отправить личное сообщение для Bergosio
Найти ещё сообщения от Bergosio

Если версия PHP не критична, то просто выбираем PHP 5.6 в настройках и включаем модуль ioncube. Там уже стоит 5 версия.

21.08.2020, 01:28 #17
Меню пользователя Bergosio
Посмотреть профиль
Отправить личное сообщение для Bergosio
Найти ещё сообщения от Bergosio

Если версия PHP не критична, то просто выбираем PHP 5.6 в настройках и включаем модуль ioncube. Там уже стоит 5 версия.

Пример разработки блога на Zend Framework 2. Часть 2. Модуль MyBlog

Это вторая из трех частей статьи, посвященной разработке простого приложения при помощи Zend Framework 2. В первой статье я рассмотрел структуру ZendSkeletonApplication, а в этой части приведу пример разработки простого модуля. Третья часть будет посвящена работе с пользователями.

Установка и настройка дополнительных модулей

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

  1. добавляем соответствующую строчку в composer.json, чтобы сообщить Композеру о новом модуле,
  2. выполняем команду php composer.phar update, чтобы Композер загрузил новый модуль и при необходимости перегенерировал автолоад файлы,
  3. добавляем новый модуль в список modules в файле config/application.config.php,
  4. при необходимости, размещаем конфигурационный файл модуля (обычно пример такого файла находится в папке config модуля) в config/autoload и делаем в нем необходимые правки.

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

Давайте начнем с установки простого, но полезного модуля Zend Developer Tools.

Zend Developer Tools

Zend Developer Tools — это удобный тулбар, содержащий полезную для разработчика информацию о созданной странице: число и список запросов к БД, список ролей текущего пользователя, использованные Entity, загруженная конфигурация сайта и т.д. Разумеется, тулбар может быть расширен любой другой вспомогательной информацией. Найти его можно тут: https://github.com/zendframework/ZendDeveloperTools.

Чтобы установить тулбар сначала добавим строчку:

в файл composer.json в корне проекта и затем выполним команду php composer.phar update в корне проекта.

Затем в файл config/application.config.php в массив modules нужно добавить элемент ZendDeveloperTools:

Теперь осталось скопировать файл vendor/zendframework/zend-developer-tools/config/zenddevelopertools.local.php.dist в папку config/autoload нашего проекта и переименовать его, например, в zenddevelopertools.local.php (часть имени до local.php по большому счету значения не имеет).

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

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

Текущая версия приложения доступна на Гитхабе в репозитории проекта с тэгом zenddevelopertools: https://github.com/romka/zend-blog-example/tree/zenddevelopertools

Doctrine ORM

Добавим в секцию require файла composer.json строчки:

и выполним в консоли команду php composer.phar update.

Модуль DoctrineModule можно не указывать явно в нашем composer.json, так как эта зависимость прописана на уровне модуля DoctrineORMModule.

Теперь нужно в директории config/autoload разместить файл doctrine.local.php с параметрами доступа к БД, который будет использоваться Доктриной, его содержимое должно быть примерно таким:

Теперь если мы перезагрузим страницу нашего сайта, то внизу страницы в Zend девлопер тулбаре увидим два новых блока, показывающих число выполненных запросов и список маппингов к БД. Оба значения равны нулю, так как маппинги мы пока не сделали и, как следствие, запросов к базе нет.

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

Модуль MyBlog

В каталоге modules создадим следующие директории и файлы:

Содержимое файла Module.php должно быть таким:

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

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

Файл src/MyBlog/Entity/BlogPost.php является связью (маппингом) между Доктриной и базой данных и о нем нужно поговорить подробнее.

BlogPost.php


Каждый блогпост в моем примере будет содержать следующие поля:

  • заголовок,
  • тело блогпоста,
  • id автора (0 для анонимов),
  • статус (опубликовано/не опубликовано)
  • дата публикации.

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

Этот файл объявляет класс BlogPost, который содержит описания полей блогпоста и методов доступа к ним. Полную версию файла вы можете посмотреть на Гитхабе (https://github.com/romka/zend-blog-example/blob/master/module/MyBlog/src. ), вот так выглядит его часть:

Каждая переменная в этом классе станет полем в БД, параметры полей задаются в аннотациях, которые будут прочитаны Доктриной (примерно вот так: http://php.net/manual/en/reflection >Doctrine\Common\Annotations\AnnotationReader метод getClassAnnotations()).

Теперь в конфигурационный файл модуля config/module.config.php можно добавить информацию о нашей новой Entity, которая будет использована Доктриной:

И осталось добавить модуль MyBlog в список активных модулей в application.config.php.

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

И результатом должно быть сообщение вида:

После того как мы убедились в том, что Доктрина видит наш объект BlogPost выполним команду:

В результате должна вернуться ошибка вида:

Это и логично, так как наша база данных все еще пуста и сейчас мы создадим нужную таблицу командой:

Её результатом будет следующий вывод:

И теперь вызов команды:

Если сейчас обновить страницу нашего сайта, то в тулбаре внизу страницы мы увидим, что Доктрина видит один маппинг Myblog\Entity\BlogPost.

Исходные коды текущей версии проекта можно найти в репозитории проекта на Гитхабе с тэгом blogpost_entity: https://github.com/romka/zend-blog-example/tree/blogpost_entity.

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

Добавление блогпоста

В директории src/MyBlog модуля создадим два новых каталога с файлами:

Далее в конфигурационный файл модуля нужно добавить элементы, объявляющие список контроллеров модуля, маршруты и путь к директории с шаблонами:

Исходя из заданных выше настроек, все страницы нашего блога будут иметь урлы вида blog/[action]/[id] (элементы пути в квадратных скобках не обязательны).

Файл BlogPostForm.php будет содержать форму, которая будет использоваться для добавления/редактирования блогпоста, давайте создадим эту форму.

BlogPostForm.php

В самом простом случае код формы будет выглядеть вот так (это не полный исходный код формы, целиком его можно увидеть тут: https://github.com/romka/zend-blog-example/blob/master/module/MyBlog/src. ):

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

BlogController.php

Полный код контроллера вы можете посмотреть в репозитории (https://github.com/romka/zend-blog-example/blob/master/module/MyBlog/src. ), ниже его ключевая часть:

Значимым для нас является код экшена addAction (имена всех экшенов должны создаваться по маске nameAction()). В нем мы сначала создаем объект формы и заменяем текст кнопки submit на ней (у нас одна и та же форма будет использоваться и для создания, и для редактирования блогпостов, по этому тексты на этой кнопке удобно иметь разные):

Затем, в случае если форма прошла валидацию (а валидацию сейчас она пройдет в любом случае, так как валидаторов у нас пока нет) мы создаем экземпляр класса \MyBlog\Entity\BlogPost(), который является связью между нашим приложением и БД, наполняем созданный объект данными и сохраняем их в БД:

Текущую версию шаблона, отвечающего за отображение формы, можно увидеть по ссылке https://github.com/romka/zend-blog-example/blob/blogpost_form_1/module/M. .

Если cейчас попробовать сохранить пустую форму, то Доктрина вернет сообщение об ошибке вида:

Это правильно, ведь у нас есть только одно поле, помеченное как nullable=»true» — это поле state, а все остальные должны быть заполнены. Давайте добавим к форме инпут фильтры и валидаторы, чтобы перехватывать подобные ошибки еще до попытки сохранить данные (на уровне нашего приложения, а не БД), чтобы у пользователя была возможность исправить ошибку.

Валидация форм

В ранее созданном файле BlogPostInputFilter.php разместим такой код (полная версия на Гитхабе: https://github.com/romka/zend-blog-example/blob/master/module/MyBlog/src. ):

Предполагаю, что смысл этих строк должен быть интуитивно понятным: для полей title и text мы добавляем инпут фильтры, которые удалят из текстов все html тэги (фльтр StripTags) и обрежут пробелы по краям строк (StrinTrim), а также добавляем валидаторы, определяющие значения минимальной и максимальной длины полей (StringLength).

Осталось присоединить новый фильтр к форме, добавив в класс формы строчку:

Теперь форма не пройдет валидацию, если в нее введены некорректные данные.

View плагины

После того как блогпост успешно сохранен (или не сохранен) мы перенаправляем пользователя на страницу /blog, на которой в будущем у нас будет полный список блогпостов. Хотелось бы не просто сделать редирект, но и вывести на экран сообщение об успешно выполненном действии.

Добавить такие сообщения можно с помощью методов:

Извлечь сообщения, добавленные таким способом можно в контроллере или в phtml-шаблонах таким образом:

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

Для этого в директории src\MyBlog модуля создадим такие директории и файлы:

Содержимое ShowMessages.php можно посмотреть тут: https://github.com/romka/zend-blog-example/blob/master/module/MyBlog/src. , оно не очень интересно, я здесь просто получаю список сообщений, форматирую и возвращаю готовый html-код для их отображения.

Осталось сделать три действия:

  1. зарегистрировать View-плагин,
  2. добавить его использование в шаблон,
  3. и вывести сообщения о успешном/неудачном сохранении формы.

Чтобы зарегистрировать плагин добавим в настройки модуля в сецкию view_helper => invokables строчку:

В шаблоны добавим вывод сообщений:

Для вывода сообщений на экран добавим в контроллер такие строчки:


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

Эту версию приложения вы можете найти в гит-репозитории с тэгом blogpost_form_1: https://github.com/romka/zend-blog-example/tree/blogpost_form_1.

На текущем этапе у нас есть:

  1. сущность для связи приложения и БД, созданная при помощи Доктрины,
  2. контроллер обслуживающий страницу добавления блогпоста,
  3. форма добавления блогпоста с инпут фильтрами и валидаций,
  4. свой кастомный View-плагин для вывода сообщений на экран.

Теперь давайте добавим страницы одного блогпоста, списка блогпостов и формы редактирования/удаления поста.

Страница блогпоста

Добавим в контроллер BlogpostController новое действие view:

Этот экшен доступен по адресу blog/view/ID. В нем мы сначала мы проверяем, что в URL’е задан id блогпоста, если это не так, то возвращаем ошибку и редиректим пользователя на страницу со списком блогпостов. Затем извлекаем пост из базы и передаем его в шаблон.

В качестве имени шаблона по умолчанию используется имя контроллера, по этому теперь в директории модуля view/my-blog/blog нужно создать файл view.phtml с примерно вот таким содержимым:

Здесь мы выбираем все опубликованные блогпосты (state == 1), сортируем их по дате публикации и передаем в шаблон index.phtml https://github.com/romka/zend-blog-example/blob/blogpost_form_2/module/M. . В шаблоне выводятся заголовки блогпостов и ссылки на их редактирование и удаление.

Небольшое отступление

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

Кроме того, я добавил к форме Csrf-токен (поле security), который должен защитить форму от подделки. По умолчанию этот токен формируется на основании пользовательской сессии и соли и живет 300 секунд ( Zend\Form\Element\Csrf.php), но может быть (и по хорошему должен быть) переопределен и к нему как минимум должна быть добавлена зависимость от ip посетителя.

Редактирование блогпоста

Для редактирования поста мы будем использовать уже существующую форму. В контроллере необходимо создать действие editAction(), которое будет создавать форму, наполнять её существующими данными и отдавать пользователю. Этот экшен является смесью addAction(), в части работы с формой, и viewAction(), в части выборки данных https://github.com/romka/zend-blog-example/blob/blogpost_form_2/module/M. .

Вот самая интересная часть этого контроллера:

Здесь мы загружаем из БД блогпост, основываясь на id, который пришел в форме, обновляем данные:

и кладем обновленный блогпост в базу:

Удаление блогпостов

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

Исходники с тэгом blogpost_form_2 (https://github.com/romka/zend-blog-example/tree/blogpost_form_2) содержат формы редактирования и удаления блогпоста, список постов и соответствующие шаблоны.

На этом я бы хотел завершить вторую часть статьи. В третьей части мы займёмся работой с пользователями.

Объявление блока zend модуля

We recommend upgrading to the latest Google Chrome or Firefox.

Join GitHub today

GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.

PHP / Zend / zend_modules.h

23.08.2020, 16:57 #18
/*
+———————————————————————-+
| Zend Engine |
+———————————————————————-+
| Copyright (c) 1998-2011 Zend Technologies Ltd. (http://www.zend.com) |
+———————————————————————-+
| This source file is subject to version 2.00 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.zend.com/license/2_00.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+———————————————————————-+
| Authors: Andi Gutmans |
| Zeev Suraski |
+———————————————————————-+
*/
/* $ >*/
# ifndef MODULES_H
# define MODULES_H
# include » zend.h «
# include » zend_compile.h «
# include » zend_build.h «
# define INIT_FUNC_ARGS int type, int module_number TSRMLS_DC
# define INIT_FUNC_ARGS_PASSTHRU type, module_number TSRMLS_CC
# define SHUTDOWN_FUNC_ARGS int type, int module_number TSRMLS_DC
# define SHUTDOWN_FUNC_ARGS_PASSTHRU type, module_number TSRMLS_CC
# define ZEND_MODULE_INFO_FUNC_ARGS zend_module_entry *zend_module TSRMLS_DC
# define ZEND_MODULE_INFO_FUNC_ARGS_PASSTHRU zend_module TSRMLS_CC
# define ZEND_MODULE_API_NO 20090626
# ifdef ZTS
# define USING_ZTS 1
# else
# define USING_ZTS 0
# endif
# define STANDARD_MODULE_HEADER_EX sizeof (zend_module_entry), ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS
# define STANDARD_MODULE_HEADER \
STANDARD_MODULE_HEADER_EX, NULL , NULL
# define ZE2_STANDARD_MODULE_HEADER \
STANDARD_MODULE_HEADER_EX, ini_entries, NULL
# define ZEND_MODULE_BUILD_ID » API » ZEND_TOSTR(ZEND_MODULE_API_NO) ZEND_BUILD_TS ZEND_BUILD_DEBUG ZEND_BUILD_SYSTEM ZEND_BUILD_EXTRA
# define STANDARD_MODULE_PROPERTIES_EX 0 , 0 , NULL , 0 , ZEND_MODULE_BUILD_ID
# define NO_MODULE_GLOBALS 0 , NULL , NULL , NULL
# ifdef ZTS
# define ZEND_MODULE_GLOBALS ( module_name ) sizeof (zend_##module_name##_globals), &module_name##_globals_id
# else
# define ZEND_MODULE_GLOBALS ( module_name ) sizeof (zend_##module_name##_globals), &module_name##_globals
# endif
# define STANDARD_MODULE_PROPERTIES \
NO_MODULE_GLOBALS, NULL , STANDARD_MODULE_PROPERTIES_EX
# define NO_VERSION_YET NULL
# define MODULE_PERSISTENT 1
# define MODULE_TEMPORARY 2
struct _zend_ini_entry;
typedef struct _zend_module_entry zend_module_entry;
typedef struct _zend_module_dep zend_module_dep;
struct _zend_module_entry <
unsigned short size;
unsigned int zend_api;
unsigned char zend_debug;
unsigned char zts;
const struct _zend_ini_entry *ini_entry;
const struct _zend_module_dep *deps;
const char *name;
const struct _zend_function_entry *functions;
int (*module_startup_func)(INIT_FUNC_ARGS);
int (*module_shutdown_func)(SHUTDOWN_FUNC_ARGS);
int (*request_startup_func)(INIT_FUNC_ARGS);
int (*request_shutdown_func)(SHUTDOWN_FUNC_ARGS);
void (*info_func)(ZEND_MODULE_INFO_FUNC_ARGS);
const char *version;
size_t globals_size;
# ifdef ZTS
ts_rsrc_id* globals_id_ptr;
# else
void * globals_ptr;
# endif
void (*globals_ctor)( void *global TSRMLS_DC);
void (*globals_dtor)( void *global TSRMLS_DC);
int (*post_deactivate_func)( void );
int module_started;
unsigned char type;
void *handle;
int module_number;
char *build_id;
>;
# define MODULE_DEP_REQUIRED 1
# define MODULE_DEP_CONFLICTS 2
# define MODULE_DEP_OPTIONAL 3
# define ZEND_MOD_REQUIRED_EX ( name, rel, ver ) < name, rel, ver, MODULE_DEP_REQUIRED >,
# define ZEND_MOD_CONFLICTS_EX ( name, rel, ver ) < name, rel, ver, MODULE_DEP_CONFLICTS >,
# define ZEND_MOD_OPTIONAL_EX ( name, rel, ver ) < name, rel, ver, MODULE_DEP_OPTIONAL >,
# define ZEND_MOD_REQUIRED ( name ) ZEND_MOD_REQUIRED_EX(name, NULL , NULL )
# define ZEND_MOD_CONFLICTS ( name ) ZEND_MOD_CONFLICTS_EX(name, NULL , NULL )
# define ZEND_MOD_OPTIONAL ( name ) ZEND_MOD_OPTIONAL_EX(name, NULL , NULL )
struct _zend_module_dep <
const char *name; /* module name */
const char *rel; /* version relationship: NULL (exists), lt|le|eq|ge|gt (to given version) */
const char *version; /* version */
unsigned char type; /* dependency type */
>;
extern ZEND_API HashTable module_registry;
void module_destructor (zend_module_entry *module);
int module_registry_cleanup (zend_module_entry *module TSRMLS_DC);
int module_registry_request_startup (zend_module_entry *module TSRMLS_DC);
int module_registry_unload_temp ( const zend_module_entry *module TSRMLS_DC);
# define ZEND_MODULE_DTOR ( void (*)( void *)) module_destructor
# endif
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* indent-tabs-mode: t
* End:
*/
  • © 2020 GitHub , Inc.
  • Terms
  • Privacy
  • Security
  • Status
  • Help

You can’t perform that action at this time.

You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.

Невозможно загрузить действие индекса модуля для модуля Zend Framework

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

Модуль содержится внутри моей внешней библиотеки PHP, которую я повторно использую для каждого проекта, основанного на ZendFramework или нет. Это первый раз, когда я добавляю модуль, но ранее я использовал библиотеку для хранения вспомогательных классов и плагинов без проблем. Структура модуля содержится внутри PHPLib/ZF/Modules и выглядит следующим образом:

Класс IndexController.php определяется как «ModAdmin_IndexController», поскольку мне было дано указание в некоторых из ресурсов ZF, которыми я владею. Скрипт присутствует, а макет еще не создан. Я не уверен, буду ли я использовать его или нет.

Поэтому, когда я пытаюсь запросить индекс модуля ModAdmin в браузере, я получаю 404. Используемый мной URL-адрес:

Я что-то упускаю? Согласно некоторым книгам, таким как «ZendFramework In Action» и «ProPHP», они говорят, что это все, что требуется. Когда я читал, что они говорят, что это было просто, я почти не мог перестать смеяться — ничто в ZendFramework никогда не было «таким» простым — мне нравится ZF, ALOT, но это не просто. Сложность существует, потому что она настолько гибкая и мощная.

В любом случае — любые идеи?

Я думаю, я должен добавить, что я начал использовать ZF задолго до того, как появились классы Zend_Application или Zend_Tool — это было до того, как ZF стал мудрым и начал имитировать RoR-стиль MVC, — и в любом случае мой проект не имеет ничего из этого, потому что пока я не начал исследуя модули, я даже не знал о их существовании. Сказанное — у меня нет времени, чтобы смонтировать кривую обучения, связанную с этими, и я достаточно доволен, создавая вручную загрузку.

На самом деле, если честно, я создал «инструмент развертывания» под названием «padmin», который представляет собой скрипт PHP для работы с CLI, который делает многое из того, что делает Zend_Tool, и я использую его в сочетании с «phing», который похож на «ant», для php — во всяком случае — я обошел его, как и большинство людей.

Я нашел этот ресурс, который, как представляется, касается добавления модулей без использования Zend_Tool и, несмотря на то, что после выполнения всех требований, которые он излагает, я все еще получаю код 404 при запросе модуля описанным образом:

Ну, люди — я не могу выразить, как это расстраивает. Каждый ресурс в Интернете либо ссылается на создание модулей с Zend_Tool/Application, либо на то, что я заканчиваю тем, что обсуждает только модули в очень специфическом аспекте. Мне нужно что-то, что поможет мне отладить, почему он не находит модуль отправки/маршрута FrontController. Я установил каталог модулей в моем бутстрапе. Модуль имеет контроллер и сценарий вида. Вот оно — ему не нужно ничего больше. Что еще может потребоваться? Я попытался добавить каталог контроллера модуля отдельно (вместо добавления его через ‘addModuleDirectory’) и до сих пор нет кубиков. Существует некоторая документация, о которой я упоминал ранее, которая гласит:

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

Ну, люди — я сделал именно это:

Тем не менее — без кубиков. Браузер откидывается назад на 404. Было бы неплохо, если бы на переднем контроллере была какая-то внутренняя способность аудита/регистрации, которую я мог бы переворачивать, и наблюдать за тем, что происходит (и, полагаю, я мог бы это сделать, если бы захотел копаться в источнике и поставить некоторые заявления печати, но это становится нелепым).

Это абсолютно ошеломляет. Это случилось со мной давным-давно, когда я впервые изучил ZF — и как это было зафиксировано, — когда что-то пошло не так — очень сложно понять, почему. Ну, я снова здесь с другой проблемой — я следил за каждой мыслимой инструкцией (которую я нашел в преддверии zend_tool), но пока ничего не работает.

Единственное, что я сделал, это настроить мою структуру каталогов следующим образом:

но выполнение этого полностью лишило бы цели модуля? Если я не могу сохранить модульный код модуля в библиотеке (т.е. Не в каталоге приложения, а во внешней библиотеке), то какой черт — это момент создания модуля !? Мне нужно уметь вводить код модуля в мою библиотеку: ‘/library/PHPLib/ZF/Modules/ModAdmin’ — что дает!

EDIT — в ответ на выбранный ответ

Настолько интересно — после изменения настроек Directory Apache для AllowOverride All, я получаю ваш ответ плагина на запрос mod-admin вместо 404 (массив (3) <["module"] =>string (9) «mod -admin «[» controller «] => string (5)» index «[» action «] => string (5)» index «>), то если я отключу плагин, я получу эту ошибку:

Неустранимая ошибка: исключить исключение «Zend_Controller_Dispatcher_Exception» с сообщением «Недопустимый контроллер указан (индекс)» в /home/nevertap/work/nevertap/library/Zend/Controller/Dispatcher/Standard.php:248 Трассировка стека: # 0/home/nevertap/work/nevertap/library/Zend/Controller/Front.php(954): Zend_Controller_Dispatcher_Standard-> отправка (объект (Zend_Controller_Request_Http), объект (Zend_Controller_Response_Http)) # 1/home/nevertap/work/nevertap/application/configuration/bootstrap.php(100): Zend_Controller_Front-> dispatch() # 2/home/nevertap/work/nevertap/application/configuration/bootstrap.php(110): Bootstrap-> configureFrontController() # 3/home/nevertap/www/nevertap/index.php(19): Bootstrap-> runApp() # 4

заброшен в /home/nevertap/work/nevertap/library/Zend/Controller/Dispatcher/Standard.php в строке 248

что очень странно, потому что. /Modules/mod-admin/controller/IndexController.php существует, как и. /Модули /mod-admin/view/scripts/index/index.phtml — не говоря уже о том, что класс IndexController соответствующим образом префикс как «ModAdmin_IndexController»

OK Я, наконец, получил его — похоже, загрузив каталог модуля, он искал директорию контроллера по умолчанию, которая всегда имеет форму «контроллеров», а мой был «контроллером», поэтому вместо загрузки модуля с помощью addModuleDir я использовал другое:

Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL