Zend Framework - Краткое руководство
Веб-платформа PHP - это набор классов, который помогает разрабатывать веб-приложение. Zend - один из самых популярных фреймворков PHP. Этоopen-source MVC frameworkдля быстро развивающихся современных веб-приложений. Zend Framework имеет несколько слабо связанных компонентов, поэтому она называется «Библиотека компонентов». Zend Framework предоставляет любой стек PHP и сервер Zend для запуска приложений Zend framework.
Zend Studio - это IDE, которая включает функции для интеграции с Zend Framework. Он обеспечивает представление MVC и генерацию кода. Текущая версия Zend Framework 3.0 включает новые компоненты, такие как сервер JSON RPC, преобразователь XML в JSON, функциональность PSR-7 и совместимость с PHP 7.
Zend Framework 2 - это фреймворк с открытым исходным кодом для разработки веб-приложений и сервисов с использованием PHP 5.3+. Zend Framework 2 использует 100% объектно-ориентированный код и большинство новых функций PHP 5.3, а именно:Namespaces, Lambda Functions и Closures.
Zend Framework 2 произошел от Zend Framework 1, успешного PHP-фреймворка с более чем 15 миллионами загрузок. Zend Server имеет бесплатную версию сообщества и коммерческую версию.
Возможности Zend Framework
Некоторые из характерных особенностей Zend Framework следующие:
- Чистая объектно-ориентированная структура веб-приложений
- Расширенная реализация MVC
- Поддерживает несколько баз данных, включая PostgreSQL, SQLite и т. Д.,
- Простой облачный API
- Управление сессией
- Шифрование данных
- Гибкая маршрутизация URI
- Zend обеспечивает поддержку разработки RESTful API.
- Код многоразовый и простой в обслуживании.
Почему Zend Framework?
Что делает Zend Framework одной из основных платформ, используемых разработчиками PHP, так это то, что она предоставляет чистый и стабильный код с правами интеллектуальной собственности. Это также упрощает программирование. Это быстрый, простой в освоении и удобный фреймворк. Zend поддерживает надежные инструменты криптографии и методы хеширования паролей.
Zend Goals
Ниже приведены цели Zend Framework.
- Flexibility
- Просто и продуктивно
- Compatibility
- Расширяемость - Программист может легко расширить все классы фреймворка.
- Переносимость - поддерживает несколько сред
Приложения Zend
Следующие популярные продукты разработаны с использованием Zend Framework.
- Веб-сайт компании McAfee
- Веб-сайт компании IBM
- Magento - один из самых популярных сайтов корзины покупок.
Преимущества Zend Framework
Некоторые из преимуществ Zend Framework перечислены ниже.
Loosely Coupled - Zend предоставляет возможность удалять модули или компоненты, которые нам не нужны в приложении.
Performance- Zend Framework оптимизирован для повышения производительности. Zend Framework 3 в 4 раза быстрее своей предыдущей версии.
Security - Framework поддерживает стандартное шифрование.
Testing - PHPUnit интегрирован с Zend, поэтому вы можете легко протестировать фреймворк.
В следующей главе мы узнаем, как установить Zend Framework.
Чтобы установить Zend Framework, мы должны сначала установить Composer и последнюю версию PHP, как показано в следующих шагах.
Install Composer- Zend использует Composer для управления своими зависимостями, поэтому убедитесь, что на вашем компьютере установлен Composer. Если Composer не установлен, посетите официальный сайт Composer и установите его.
Install the latest version of PHP- Чтобы получить максимальную пользу от Zend Framework, установите последнюю версию PHP. Минимальная необходимая версия для Zend Framework 3 - PHP 5.6 или новее.
Установить Zend Framework
Zend Framework можно установить двумя способами. Они следующие -
- Ручная установка
- Установка на основе композитора
Обсудим подробно обе эти установки.
Ручная установка
Загрузите последнюю версию Zend Framework, перейдя по следующей ссылке - https://framework.zend.com/downloads/archives
Распакуйте содержимое загруженного файла архива в папку, в которой вы хотите его сохранить. Когда у вас есть копия Zend Framework, доступная на вашем локальном компьютере, ваше веб-приложение на основе Zend Framework может получить доступ к классам платформы. Хотя есть несколько способов добиться этого, ваш PHPinclude_pathдолжен содержать путь к классам Zend Framework в каталоге / library в дистрибутиве. Этот метод применим только к Zend Framework версии 2.4 и более ранних.
Установка на основе композитора
Чтобы легко установить Zend Framework, используйте инструмент Composer. Это предпочтительный метод для установки последней версии Zend Framework. Чтобы установить все компоненты Zend Framework, используйте следующую команду Composer -
$ composer require zendframework/zendframework
Каждый модуль / компонент Zend Framework также можно установить индивидуально. Например, чтобы установитьMVC component Zend Framework используйте следующие composer команда -
$ composer require zendframework/zend-mvc
Давайте создадим скелет приложения, используя слой Zend Framework MVC и модульные системы.
Установка с помощью Composer
Самый простой способ создать новый проект Zend Framework - использовать Composer. Это определяется как ниже -
$ cd /path/to/install $ composer create-project -n -sdev zendframework/skeleton-application myapp
Вы увидите на своем экране следующий результат -
Installing zendframework/skeleton-application (dev-master
941da45b407e4f09e264f000fb537928badb96ed)
- Installing zendframework/skeleton-application (dev-master master)
Cloning master
Created project in myapp
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
- Installing zendframework/zend-component-installer (0.3.0)
Loading from cache
- Installing zendframework/zend-stdlib (3.0.1)
Loading from cache
- Installing zendframework/zend-config (2.6.0)
Loading from cache
- Installing zendframework/zend-loader (2.5.1)
Loading from cache
- Installing zendframework/zend-eventmanager (3.0.1)
Loading from cache
- Installing zendframework/zend-view (2.8.0)
Loading from cache
- Installing container-interop/container-interop (1.1.0)
Loading from cache
- Installing zendframework/zend-servicemanager (3.1.0)
Loading from cache
- Installing zendframework/zend-validator (2.8.1)
Loading from cache
- Installing zendframework/zend-escaper (2.5.1)
Loading from cache
- Installing zendframework/zend-uri (2.5.2)
Loading from cache
- Installing zendframework/zend-http (2.5.4)
Loading from cache
- Installing zendframework/zend-router (3.0.2)
Loading from cache
- Installing zendframework/zend-modulemanager (2.7.2)
Loading from cache
- Installing zendframework/zend-mvc (3.0.1)
Loading from cache
- Installing zendframework/zend-skeleton-installer (0.1.3)
Loading from cache
- Installing zfcampus/zf-development-mode (3.0.0)
Loading from cache
zendframework/zend-config suggests installing zendframework/zend-filter
(Zend\Filter component)
zendframework/zend-config suggests installing zendframework/zend-i18n
(Zend\I18n component)
zendframework/zend-config suggests installing zendframework/zend-json
(Zend\Json to use the Json reader or writer classes)
zendframework/zend-view suggests installing zendframework/zend-authentication
(Zend\Authentication component)
zendframework/zend-view suggests installing zendframework/zend-feed
(Zend\Feed component)
zendframework/zend-view suggests installing zendframework/zend-filter
(Zend\Filter component)
zendframework/zend-view suggests installing zendframework/zend-i18n
(Zend\I18n component)
zendframework/zend-view suggests installing zendframework/zend-json
(Zend\Json component)
zendframework/zend-view suggests installing zendframework/zend-navigation
(Zend\Navigation component)
zendframework/zend-view suggests installing zendframework/zend-paginator
(Zend\Paginator component)
zendframework/zend-view suggests installing zendframework/zend-permissions-acl
(Zend\Permissions\Acl component)
zendframework/zend-servicemanager suggests installing ocramius/proxy-manager
(ProxyManager 1.* to handle lazy initialization of services)
zendframework/zend-validator suggests installing zendframework/zend-db
(Zend\Db component)
zendframework/zend-validator suggests installing zendframework/zend-filter
(Zend\Filter component, required by the Digits validator)
zendframework/zend-validator suggests installing zendframework/zend-i18n
(Zend\I18n component to allow translation of validation error messages as well as
to use the various Date validators)
zendframework/zend-validator suggests installing zendframework/zend-i18nresources
(Translations of validator messages)
zendframework/zend-validator suggests installing zendframework/zend-math
(Zend\Math component)
zendframework/zend-validator suggests installing zendframework/zend-session
(Zend\Session component)
zendframework/zend-router suggests installing zendframework/zend-i18n
(^2.6, if defining translatable HTTP path segments)
zendframework/zend-modulemanager suggests installing zendframework/zend-console
(Zend\Console component)
zendframework/zend-mvc suggests installing zendframework/zend-json ((^2.6.1 ||
^3.0) To auto-deserialize JSON body content in AbstractRestfulController
extensions, when json_decode is unavailable)
zendframework/zend-mvc suggests installing zendframework/zend-mvc-console
(zend-mvc-console provides the ability to expose zend-mvc as a console application)
zendframework/zend-mvc suggests installing zendframework/zend-mvc-i18n
(zendmvc-i18n provides integration with zend-i18n, including a translation bridge
and translatable route segments)
zendframework/zend-mvc suggests installing zendframework/zend-mvc-pluginfileprg
(To provide Post/Redirect/Get functionality around forms that container
file uploads)
zendframework/zend-mvc suggests installing zendframework/zend-mvc-pluginflashmessenger
(To provide flash messaging capabilities between requests)
zendframework/zend-mvc suggests installing zendframework/zend-mvc-pluginidentity
(To access the authenticated identity (per zend-authentication) in controllers)
zendframework/zend-mvc suggests installing zendframework/zend-mvc-plugin-prg
(To provide Post/Redirect/Get functionality within controllers)
zendframework/zend-mvc suggests installing zendframework/zend-psr7bridge
((^0.2) To consume PSR-7 middleware within the MVC workflow)
zendframework/zend-mvc suggests installing zendframework/zend-servicemanager-di
(zend-servicemanager-di provides utilities for integrating zend-di and
zendservicemanager in your zend-mvc application)
Generating autoload files
Removing optional packages from composer.json
Updating composer.json
Removing zendframework/zend-skeleton-installer...
- Removing zendframework/zend-skeleton-installer (0.1.3)
Removed plugin zendframework/zend-skeleton-installer.
Removing from composer.json
Complete!
> zf-development-mode enable
You are now in development mode.
Теперь, когда приложение установлено, вы можете сразу же протестировать его, используя PHP's built-in web server -
$ cd path/to/install/myapp $ composer serve
Тогда вы увидите следующий ответ -
> php -S 0.0.0.0:8080 -t public/ public/index.php
Это запустит встроенный в PHP сервер CLI на порту 8080. После запуска сервера разработки вы можете посетить сайт по адресу (http://localhost:8080/). Встроенный сервер CLI предназначен только для разработки.
Модульные тесты
Чтобы запустить скелетные модульные тесты, введите в терминале следующую команду.
$ composer require --dev zendframework/zend-test
Это даст следующий ответ -
Using version ^3.0 for zendframework/zend-test
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
- Installing zendframework/zend-dom (2.6.0)
Loading from cache
- Installing zendframework/zend-console (2.6.0)
Loading from cache
- Installing sebastian/version (2.0.1)
Loading from cache
- Installing symfony/yaml (v3.2.1)
Downloading: 100%
- Installing sebastian/resource-operations (1.0.0)
Loading from cache
- Installing sebastian/recursion-context (2.0.0)
Loading from cache
- Installing sebastian/object-enumerator (2.0.0)
Loading from cache
- Installing sebastian/global-state (1.1.1)
Loading from cache
- Installing sebastian/exporter (2.0.0)
Loading from cache
- Installing sebastian/environment (2.0.0)
Loading from cache
- Installing sebastian/diff (1.4.1)
Loading from cache
- Installing sebastian/comparator (1.2.2)
Loading from cache
- Installing phpunit/php-text-template (1.2.1)
Loading from cache
- Installing doctrine/instantiator (1.0.5)
Loading from cache
- Installing phpunit/phpunit-mock-objects (3.4.3)
Downloading: 100%
- Installing phpunit/php-timer (1.0.8)
Loading from cache
- Installing phpunit/php-file-iterator (1.4.2)
Loading from cache
- Installing sebastian/code-unit-reverse-lookup (1.0.0)
Loading from cache
- Installing phpunit/php-token-stream (1.4.9)
Loading from cache
- Installing phpunit/php-code-coverage (4.0.4)
Downloading: 100%
- Installing webmozart/assert (1.2.0)
Loading from cache
- Installing phpdocumentor/reflection-common (1.0)
Loading from cache
- Installing phpdocumentor/type-resolver (0.2.1)
Loading from cache
- Installing phpdocumentor/reflection-docblock (3.1.1)
Loading from cache
- Installing phpspec/prophecy (v1.6.2)
Loading from cache
- Installing myclabs/deep-copy (1.5.5)
Loading from cache
- Installing phpunit/phpunit (5.7.4)
Downloading: 100%
- Installing zendframework/zend-test (3.0.2)
Loading from cache
zendframework/zend-console suggests installing zendframework/zend-filter
(To support DefaultRouteMatcher usage)
symfony/yaml suggests installing symfony/console (For validating YAML files
using the lint command)
sebastian/global-state suggests installing ext-uopz (*)
phpunit/phpunit-mock-objects suggests installing ext-soap (*)
phpunit/php-code-coverage suggests installing ext-xdebug (>=2.4.0)
phpunit/phpunit suggests installing phpunit/php-invoker (~1.1)
phpunit/phpunit suggests installing ext-xdebug (*)
zendframework/zend-test suggests installing zendframework/zend-mvc-console
(^1.1.8, to test MVC <-> console integration)
Writing lock file
Generating autoload files
Теперь поддержка тестирования включена, поэтому вы можете запустить тест с помощью следующей команды.
$ ./vendor/bin/phpunit
Веб-сервер Apache
Размещение приложения на основе Zend Framework в производственной среде очень просто и понятно. Просто создайтеVirtualHost в файле конфигурации Apache и укажите DocumentRoot к Public папка приложения Zend Framework.
Пример конфигурации (myapp) приведен ниже -
<VirtualHost *:80>
ServerName myapp.localhost
DocumentRoot /path/to/install/myapp/public
<Directory /path/to/install/myapp/public>
DirectoryIndex index.php
AllowOverride All
Order allow,deny
Allow from all
<IfModule mod_authz_core.c>
Require all granted
</IfModule>
</Directory>
</VirtualHost>
Прежде чем перейти к этой главе, давайте вкратце разберемся с MVC. АModel View Controllerэто программный подход, который отделяет логику приложения от представления. На практике это позволяет веб-страницам содержать минимальные сценарии PHP, поскольку презентация отделена от них.
Краткое описание компонентов MVC выглядит следующим образом
Model- Модель представляет собой структуру данных приложения. Обычно классы модели содержат функции, которые помогаютretrieve, insert и update business data во внутренней базе данных (MySQL, PostgreSQL и т. д.).
View- Просмотр - это уровень представления приложения MVC. Он получает данные моделей через контроллер и отображает их по мере необходимости. Он слабо связан сController и Model и поэтому его можно изменить, не затрагивая ни Модель, ни Контроллер.
Controller- Контроллер является основным компонентом архитектуры MVC. Каждый запрос сначала попадает в контроллер. Другими словами, контроллер обрабатывает весь запрос и служит посредником между моделью, представлением и любыми другими ресурсами, необходимыми дляprocess the HTTP request и генерировать ответ.
В следующей главе мы поймем различные концепции Zend Framework.
Zend Framework - это набор из более чем 60 компонентов. Они слабо связаны друг с другом. Их можно использовать как автономный компонент, так и как группу компонентов, работающих как единое целое.
Zend Framework предоставляет три наиболее важных компонента, а именно:
- zend-servicemanager
- zend-eventmanager и
- zend-modulemanager.
Они предоставляют компонентам Zend возможность эффективно интегрироваться с другими компонентами.
Event Manager- Это дает возможность создавать программирование на основе событий. Это помогает создавать, вводить и управлять новыми событиями.
Service Manager - Это дает возможность потреблять любые сервисы (классы PHP) из любого места с небольшими усилиями.
Module Manager - Возможность преобразовать коллекцию классов PHP с аналогичной функциональностью в единый блок, называемый module. Вновь созданные модули можно использовать, обслуживать и настраивать как единое целое.
Мы подробно рассмотрим эти концепции в следующих главах.
Zend Framework включает мощную реализацию паттерна локатора сервисов, которая называется zend-servicemanager. Zend framework широко использует диспетчер служб для всех своих функций. Service Manager обеспечивает абстракцию высокого уровня для Zend Framework. Он также прекрасно интегрируется со всеми другими компонентами Zend Framework.
Установить Service Manager
Компонент Service Manager можно установить с помощью composer инструмент.
composer require zendframework/zend-servicemanager
пример
Во-первых, все сервисы нужно зарегистрировать в сервис-менеджере. После того, как службы зарегистрированы в системе диспетчера серверов, к ней можно получить доступ в любое время с минимальными усилиями. Сервис-менеджер предоставляет множество возможностей для регистрации сервиса. Простой пример выглядит следующим образом -
use Zend\ServiceManager\ServiceManager;
use Zend\ServiceManager\Factory\InvokableFactory;
use stdClass;
$serviceManager = new ServiceManager([
'factories' => [stdClass::class => InvokableFactory::class,],
]);
Приведенный выше код регистрирует stdClass в систему с помощью Factoryвариант. Теперь мы можем получить экземпляр stdClass в любое время, используяget() метод диспетчера службы, как показано ниже.
use Zend\ServiceManager\ServiceManager;
$object = $serviceManager->get(stdClass::class);
Метод get () совместно использует извлеченный объект, поэтому объект, возвращаемый путем многократного вызова метода get (), является одним и тем же экземпляром. Чтобы каждый раз получать новый экземпляр, диспетчер служб предоставляет другой метод, которым являетсяbuild() метод.
use Zend\ServiceManager\ServiceManager;
$a = $serviceManager->build(stdClass::class); $b = $serviceManager->build(stdClass::class);
Регистрация сервис-менеджера
Диспетчер служб предоставляет набор методов для регистрации компонента. Некоторые из наиболее важных методов приведены ниже -
- Заводской метод
- Абстрактный фабричный метод
- Метод инициализатора
- Метод фабрики делегатора
Мы подробно обсудим каждый из них в следующих главах.
Заводской метод
Фабрика - это в основном любой вызываемый или любой класс, реализующий FactoryInterface (Zend \ ServiceManager \ Factory \ FactoryInterface).
FactoryInterface имеет единственный метод -
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
Детали аргументов FactoryInterface следующие:
container (ContainerInterface)- Это базовый интерфейс ServiceManager. Он дает возможность пользоваться другими услугами.
requestedName - Это название службы.
options - Предоставляет дополнительные возможности, необходимые для обслуживания.
Давайте создадим простой класс, реализующий FactoryInterface, и посмотрим, как зарегистрировать класс.
Тест класса - объект для извлечения
use stdClass;
class Test {
public function __construct(stdClass $sc) { // use $sc
}
}
В Test класс зависит от stdClass.
Класс TestFactory - класс для инициализации тестового объекта
class TestFactory implements FactoryInterface {
public function __invoke(ContainerInterface $container, $requestedName,
array $options = null) { $dep = $container->get(stdClass::class); return new Test($dep);
}
}
TestFactory использует контейнер для получения stdClass, создает экземпляр класса Test и возвращает его.
Регистрация и использование Zend Framework
Давайте теперь поймем, как зарегистрироваться и использовать Zend Framework.
serviceManager $sc = new ServiceManager([ 'factories' => [stdClass::class => InvokableFactory::class, Test::class => TestFactory::class] ]); $test = $sc->get(Test::class);
Сервис-менеджер предоставляет специальный завод под названием InvokableFactoryдля получения любого класса, который не имеет зависимости. Например,stdClass можно настроить с помощью InvokableFactory, поскольку stdClass не зависит от других классов.
serviceManager $sc = new ServiceManager([
'factories' => [stdClass::class => InvokableFactory::class]
]);
$stdC = $sc->get(stdClass::class);
Другой способ получить объект без реализации FactoryInterface или используя InvokableFactory использует встроенный метод, как показано ниже.
$serviceManager = new ServiceManager([ 'factories' => [ stdClass::class => InvokableFactory::class, Test::class => function(ContainerInterface $container, $requestedName) { $dep = $container->get(stdClass::class); return new Test($dep);
},
],
]);
Абстрактный фабричный метод
Иногда нам может потребоваться создать объекты, о которых мы узнаем только во время выполнения. В этой ситуации можно справиться с помощьюAbstractFactoryInterface, который является производным от FactoryInterface.
AbstractFactoryInterface определяет метод проверки того, может ли объект быть создан в запрошенном экземпляре или нет. Если создание объекта возможно, он создаст объект, используя__invokemethod FactoryInterface и верните его.
Подпись AbstractFactoryInterface выглядит следующим образом:
public function canCreate(ContainerInterface $container, $requestedName)
Метод инициализатора
Метод инициализатора - это специальная опция для добавления дополнительной зависимости для уже созданных сервисов. Он реализуетInitializerInterface и подпись единственного доступного метода следующая -
public function(ContainerInterface $container, $instance)
function(ContainerInterface $container, $instance) {
if (! $instance instanceof EventManagerAwareInterface) { return; } $instance->setEventManager($container->get(EventManager::class));
}
В приведенном выше примере метод проверяет, имеет ли экземпляр тип EventManagerAwareInterface. Если это типаEventManagerAwareInterface, он устанавливает объект диспетчера событий, в противном случае - нет. Поскольку метод может устанавливать или не устанавливать зависимость, он ненадежен и вызывает множество проблем во время выполнения.
Фабричный метод делегатора
Zend Framework поддерживает шаблон делегаторов через DelegatorFactoryInterface. Его можно использовать для украшения сервиза.
Сигнатура этой функции следующая -
public function __invoke(ContainerInterface $container,
$name, callable $callback, array $options = null
);
Здесь $callback отвечает за украшение экземпляра службы.
Ленивые службы
Ленивый сервис - это один из тех сервисов, которые не будут полностью инициализированы во время создания. На них просто ссылаются и инициализируются только тогда, когда это действительно необходимо. Один из лучших примеров - подключение к базе данных, которое может понадобиться не во всех местах. Это дорогой ресурс, и на его создание нужно много времени. Zend framework предоставляетLazyServiceFactory полученный из DelegatorFactoryInterface, который может производить ленивое обслуживание с помощью Delegator концепция и сторонний прокси-менеджер, который называется ocramius proxy manager.
Менеджер плагинов
Диспетчер подключаемых модулей расширяет диспетчер служб и предоставляет дополнительные функции, такие как проверка экземпляра. Zend Framework широко использует диспетчер плагинов.
Например, все службы проверки подпадают под ValidationPluginManager.
Вариант конфигурации
Диспетчер служб предоставляет несколько возможностей для расширения возможностей диспетчера служб. Они естьshared, shared_by_default и aliases. Как мы обсуждали ранее, полученные объекты по умолчанию распределяются между запрошенными объектами, и мы можем использоватьbuild()метод, чтобы получить отдельный объект. Мы также можем использоватьsharedопция, чтобы указать, к какой услуге следует предоставить общий доступ Вshared_by_default такой же, как shared функция, за исключением того, что она применяется ко всем услугам.
$serviceManager = new ServiceManager([
'factories' => [
stdClass::class => InvokableFactory::class
],
'shared' => [
stdClass::class => false // will not be shared
],
'shared_by_default' => false, // will not be shared and applies to all service
]);
В aliasesОпция может использоваться для предоставления альтернативного имени зарегистрированным службам. У этого есть как преимущества, так и недостатки. С положительной стороны, мы можем предоставить альтернативные короткие названия для услуги. Но, в то же время, название может вырываться из контекста и вносить ошибки.
aliases' => ['std' => stdClass::class, 'standard' => 'std']
Всем современным приложениям нужны надежные и гибкие компоненты событий. Zend Framework предоставляет один из таких компонентов,zend-eventmanager. Zend-eventmanager помогает разрабатывать архитектуру высокого уровня и поддерживает паттерн субъект / наблюдатель и аспектно-ориентированное программирование.
Установить Event Manager
Менеджер событий можно установить с помощью Composer как указано ниже -
composer require zendframework/zend-eventmanager
Концепции Event Manager
Основные концепции менеджера событий следующие:
Event - Событие - это произвольно названное действие, скажем greet.
Listener- Любой обратный вызов PHP. Они привязаны к событиям и вызываются при срабатывании события. Подпись слушателя по умолчанию -
function(EventInterface $e)
EventInterface Class- Используется для указания самого события. У него есть методы для установки и получения информации о событии, например, имени (set / getName), цели (get / setTarget) и параметра (get / setParams).
EventManager class- Экземпляр EventManager отслеживает все определенные события в приложении и его соответствующих слушателях. EventManager предоставляет метод,attach чтобы прикрепить слушателя к событию, и он предоставляет метод, triggerдля запуска любого заранее определенного события. После вызова триггера EventManager вызывает прикрепленный к нему слушатель.
EventManagerAwareInterface- Чтобы класс поддерживал программирование на основе событий, он должен реализовать EventManagerAwareInterface. Он предоставляет два метода:setEventManager и getEventManager получить и установить менеджер событий.
пример
Давайте напишем простое консольное приложение PHP, чтобы понять концепцию диспетчера событий. Следуйте инструкциям ниже.
Создайте папку «eventapp».
Установить zend-eventmanager с помощью композитора.
Создать файл PHP Greeter.php внутри папки «eventapp».
Создать класс Greeter и реализовать EventManagerAwareInterface.
require __DIR__ . '/vendor/autoload.php';
class Greeter implements EventManagerAwareInterface {
// code
}
Вот, require используется для автозагрузки всех установленных компонентов композитора.
Написать setEventManager метод в классе Greeter как показано ниже -
public function setEventManager(EventManagerInterface $events) { $events->setIdentifiers([ __CLASS__, get_called_class(),]);
$this->events = $events;
return $this;
}
Этот метод устанавливает текущий класс в данный диспетчер событий (аргумент $ events), а затем устанавливает диспетчер событий в локальной переменной. $events.
Следующим шагом будет написание getEventManager метод в классе Greeter как показано ниже -
public function getEventManager() {
if (null === $this->events) {
$this->setEventManager(new EventManager()); } return $this->events;
}
Метод получает диспетчер событий из локальной переменной. если он недоступен, он создает экземпляр диспетчера событий и возвращает его.
Напишите метод, greet, в классе Greeter.
public function greet($message) { printf("\"%s\" from class\n", $message);
$this->getEventManager()->trigger(__FUNCTION__, $this, $message ]);
}
Этот метод получает диспетчер событий и запускает / запускает связанные с ним события.
Следующим шагом будет создание экземпляра Greeter class и прикрепите слушателя к его методу, greet.
$greeter = new Greeter();
$greeter->getEventManager()->attach('greet', function($e) {
$event_name = $e->getName();
$target_name = get_class($e->getTarget());
$params_json = json_encode($e->getParams());
printf("\"%s\" event of class \"%s\" is called." .
" The parameter supplied is %s\n",
$event_name, $target_name,
$params_json);
});
Обратный вызов слушателя просто печатает имя события, цель и предоставленные параметры.
Полный список Greeter.php выглядит следующим образом -
<?php
require __DIR__ . '/vendor/autoload.php';
use Zend\EventManager\EventManagerInterface;
use Zend\EventManager\EventManager;
use Zend\EventManager\EventManagerAwareInterface;
class Greeter implements EventManagerAwareInterface {
protected $events;
public function setEventManager(EventManagerInterface $events) { $events->setIdentifiers([__CLASS__, get_called_class(), ]);
$this->events = $events;
return $this; } public function getEventManager() { if (null === $this->events) {
$this->setEventManager(new EventManager()); } return $this->events;
}
public function greet($message) { printf("\"%s\" from class\n", $message);
$this->getEventManager()->trigger(__FUNCTION__, $this, [$message ]); } } $greeter = new Greeter();
$greeter->greet("Hello"); $greeter->getEventManager()->attach('greet', function($e) { $event_name = $e->getName(); $target_name = get_class($e->getTarget()); $params_json = json_encode($e->getParams()); printf("\"%s\" event of class \"%s\" is called." . " The parameter supplied is %s\n", $event_name,
$target_name, $params_json);
});
$greeter->greet("Hello");
Теперь запустите приложение в командной строке php Greeter.php и результат будет следующим -
"Hello" from class
"Hello" from class
"greet" event of class "Greeter" is called. The parameter supplied is ["Hello"]
В приведенном выше примере приложения объясняются только основы диспетчера событий. Менеджер событий предоставляет множество дополнительных опций, таких какListener Priority, Custom Callback Prototype / Signature, Short Circuiting, и т. д. Менеджер событий широко используется в среде Zend MVC.
Zend Framework предоставляет мощную модульную систему. Модульная система состоит из трех компонентов. Они следующие -
Module Autoloader- Автозагрузчик модулей отвечает за поиск и загрузку модулей из множества источников. Он может загружать модули, упакованные какPhar archivesтакже. Реализация автозагрузчика модулей находится в myapp / vendor / zendframework / zend-loader / src / ModuleAutoloader.php.
Module Manager- Как только автозагрузчик модулей обнаруживает модули, диспетчер модулей запускает последовательность событий для каждого модуля. Реализация диспетчера модулей находится в myapp / vendor / zendframework / zendmodulemanager / src / ModuleManager.php.
Module Manager Listeners- Их можно привязать к событиям, запускаемым диспетчером модулей. Присоединяясь к событиям менеджера модулей, они могут делать все, от разрешения и загрузки модулей до выполнения сложной работы для каждого модуля.
Система веб-модулей MVC
Веб-приложение MVC в Zend Framework обычно пишется как модули. Один веб-сайт может содержать один или несколько модулей, сгруппированных по функциональности. Рекомендуемая структура для модуля, ориентированного на MVC, следующая:
module_root/
Module.php
autoload_classmap.php
autoload_function.php
autoload_register.php
config/
module.config.php
public/
images/
css/
js/
src/
<module_namespace>/
<code files>
test/
phpunit.xml
bootstrap.php
<module_namespace>/
<test code files>
view/
<dir-named-after-module-namespace>/
<dir-named-after-a-controller>/
<.phtml files>
Структура такая же, как обсуждалась в предыдущей главе, но здесь она общая. Вautoload_ files может использоваться как механизм по умолчанию для автозагрузки классов, доступных в модуле, без использования расширенных Module Manager доступно в zend-modulemanager.
autoload_classmap.php - Возвращает массив имени класса и соответствующего имени файла.
autoload_function.php- Возвращает обратный вызов PHP. Это может использовать классы, возвращаемые autoload_classmap.php.
autoload_register.php - Регистрирует обратный вызов PHP, возвращаемый autoload_function.php.
Эти файлы автозагрузки не требуются, но рекомендуются. В скелетном приложении мы не использовалиautoload_ files.
Класс модуля
Класс Module следует назвать Module и пространство имен класса модуля должно быть Module name. Это поможет Zend Framework легко разрешить и загрузить модуль. ВApplication код модуля в скелетном (myapp) приложении myapp / module / Application / src / Module.php выглядит следующим образом:
namespace Application;
class Module {
const VERSION = '3.0.2dev';
public function getConfig() {
return include __DIR__ . '/../config/module.config.php';
}
}
Диспетчер модулей Zend Framework вызовет getConfig() будут работать автоматически и выполнят необходимые действия.
В этой главе давайте разберемся со структурой приложения Zend Framework. Структураmyapp приложение выглядит следующим образом -
├── composer.json
├── composer.lock
├── CONDUCT.md
├── config
│ ├── application.config.php
│ ├── autoload
│ │ ├── development.local.php
│ │ ├── development.local.php.dist
│ │ ├── global.php
│ │ ├── local.php.dist
│ │ ├── README.md
│ │ └── zend-developer-tools.local-development.php
│ ├── development.config.php
│ ├── development.config.php.dist
│ └── modules.config.php
├── CONTRIBUTING.md
├── data
│ └── cache
│ └── module-classmap-cache.application.module.cache.php ├── docker-compose.yml
├── Dockerfile
├── LICENSE.md
├── module
│ └── Application
│ ├── config
│ ├── src
│ ├── test
│ └── view
├── phpcs.xml
├── phpunit.xml.dist
├── public
│ ├── css
│ │ ├── bootstrap.css
│ │ ├── bootstrap.css.map
│ │ ├── bootstrap.min.css
│ │ ├── bootstrap.min.css.map
│ │ ├── bootstrap-theme.css
│ │ ├── bootstrap-theme.css.map
│ │ ├── bootstrap-theme.min.css
│ │ ├── bootstrap-theme.min.css.map
│ │ └── style.css
│ ├── fonts
│ │ ├── glyphicons-halflings-regular.eot
│ │ ├── glyphicons-halflings-regular.svg
│ │ ├── glyphicons-halflings-regular.ttf
│ │ ├── glyphicons-halflings-regular.woff
│ │ └── glyphicons-halflings-regular.woff2
│ ├── img
│ │ ├── favicon.ico
│ │ └── zf-logo-mark.svg
│ ├── index.php
│ ├── js
│ │ ├── bootstrap.js
│ │ ├── bootstrap.min.js
│ │ └── jquery-3.1.0.min.js
│ └── web.config
├── README.md
├── TODO.md
├── Vagrantfile
└── vendor
├── autoload.php
├── bin
│ ├── phpunit -> ../phpunit/phpunit/phpunit
│ ├── templatemap_generator.php -> ../zendframework/zend-
view/bin/templatemap_generator.php
│ └── zf-development-mode -> ../zfcampus/zf-development-mode/bin/zf-
development-mode
├── composer
│ ├── autoload_classmap.php
│ ├── autoload_namespaces.php
│ ├── autoload_psr4.php
│ ├── autoload_real.php
│ ├── ClassLoader.php
│ ├── installed.json
│ └── LICENSE
├── container-interop
│ └── container-interop
├── doctrine
│ └── instantiator
├── myclabs
│ └── deep-copy
├── phpdocumentor
│ ├── reflection-common
│ ├── reflection-docblock
│ └── type-resolver
├── phpspec
│ └── prophecy
├── phpunit
│ ├── php-code-coverage
│ ├── php-file-iterator
│ ├── php-text-template
│ ├── php-timer
│ ├── php-token-stream
│ ├── phpunit
│ └── phpunit-mock-objects
├── sebastian
│ ├── code-unit-reverse-lookup
│ ├── comparator
│ ├── diff
│ ├── environment
│ ├── exporter
│ ├── global-state
│ ├── object-enumerator
│ ├── recursion-context
│ ├── resource-operations
│ └── version
├── symfony
│ └── yaml
├── webmozart
│ └── assert
├── zendframework
│ ├── zend-component-installer
│ ├── zend-config
│ ├── zend-console
│ ├── zend-dom
│ ├── zend-escaper
│ ├── zend-eventmanager
│ ├── zend-http
│ ├── zend-loader
│ ├── zend-modulemanager
│ ├── zend-mvc
│ ├── zend-router
│ ├── zend-servicemanager
│ ├── zend-stdlib
│ ├── zend-test
│ ├── zend-uri
│ ├── zend-validator
│ └── zend-view
└── zfcampus
└── zf-development-mode
73 directories, 55 files
Приложение Zend Framework состоит из разных папок. Они следующие -
Application- Этот каталог содержит ваше приложение. Он будет содержать систему MVC, а также конфигурации, используемые службы и ваш файл начальной загрузки.
Config - Этот каталог содержит файлы конфигурации приложения.
Data - Этот каталог предоставляет место для хранения изменчивых и, возможно, временных данных приложения.
Module - Модули позволяют разработчику сгруппировать набор связанных контроллеров в логически организованную группу.
Public- Это корень документа приложения. Он запускает приложение Zend. Он также содержит активы приложения, такие как JavaScript, CSS, изображения и т. Д.
Vendor - Этот каталог содержит зависимости композитора.
Структура модулей приложения
Это главный каталог вашего приложения. Zend Framework 2 представляет мощную и гибкую модульную систему для эффективной организации приложения. ВApplicationмодуль скелетного приложения (myapp) обеспечивает настройку начальной загрузки, ошибок и маршрутизации для всего приложения. СтруктураApplication модуль, как показано ниже -
├── module
│ └── Application
│ ├── config
│ │ └── module.config.php
│ ├── src
│ │ ├── Controller
│ │ │ └── IndexController.php
│ │ └── Module.php
│ ├── test
│ │ └── Controller
│ │ └── IndexControllerTest.php
│ └── view
│ ├── application
│ │ └── index
│ │ └── index.phtml
│ ├── error
│ │ ├── 404.phtml
│ │ └── index.phtml
│ └── layout
│ └── layout.phtml
Давайте подробно рассмотрим каждый из этих каталогов модулей -
Application- Это корневой каталог модуля. Имя папки будет соответствовать имени модуля, и это имя также используется в качестве пространства имен PHP для всех классов, определенных внутри модуля. Он будет содержать систему MVC, а также конфигурации, используемые службы и ваш файл начальной загрузки.
Config - Самостоятельная настройка модуля.
Src - Основная бизнес-логика приложения.
View- Содержит файлы дизайна / презентации (HTML). Например, index.phtml.
src/Module.php- Это сердце модуля. Он работает как «фронт-контроллер» для модуля. Процесс Zendsrc/Module.php перед обработкой любых PHP-классов в этом модуле.
Application/config/module.config.php - Реализовано для настройки роутера и автозагрузки файлов.
Application/view/layout- Макеты представляют собой общие части нескольких представлений. Например, верхний и нижний колонтитулы страницы. По умолчанию макеты должны храниться вviews/layoutsfolder.
Все модули имеют ту же или аналогичную структуру, что и вышеуказанный модуль приложения .
В этой главе мы узнаем, как создать модуль на основе MVC в Zend Framework. Давайте создадим модуль с именемTutorial чтобы понять процесс создания модуля.
Создайте новый класс PHP с именем Module внутри каталога –myapp / module / Tutorial / src / и реализуйте интерфейс ConfigProviderInterface.
Набор Tutorial как пространство имен для Module класс.
Напишите публичную функцию getConfig в Module class и верните файл конфигурации для Tutorial Модуль.
Полный код для Module класс выглядит следующим образом -
<?php
namespace Tutorial;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
class Module implements ConfigProviderInterface {
public function getConfig() {
return include __DIR__ . '/../config/module.config.php';
}
}
Настроить Tutorial модуль в composer.json под autoload раздел, используя следующий код.
"autoload": {
"psr-4": {
"Application\\": "module/Application/src/",
"Tutorial\\": "module/Tutorial/src/"
}
}
Обновите приложение с помощью композитора update как показано ниже.
composer update
В composer команда внесет необходимые изменения в приложение и покажет журналы в командной строке, как показано ниже -
Loading composer repositories with package information
Updating dependencies (including require-dev)
- Removing zendframework/zend-component-installer (0.3.0)
- Installing zendframework/zend-component-installer (0.3.1)
Downloading: 100%
- Removing zendframework/zend-stdlib (3.0.1)
- Installing zendframework/zend-stdlib (3.1.0)
Loading from cache
- Removing zendframework/zend-eventmanager (3.0.1)
- Installing zendframework/zend-eventmanager (3.1.0)
Downloading: 100%
- Removing zendframework/zend-view (2.8.0)
- Installing zendframework/zend-view (2.8.1)
Loading from cache
- Removing zendframework/zend-servicemanager (3.1.0)
- Installing zendframework/zend-servicemanager (3.2.0)
Downloading: 100%
- Removing zendframework/zend-escaper (2.5.1)
- Installing zendframework/zend-escaper (2.5.2)
Loading from cache
- Removing zendframework/zend-http (2.5.4)
- Installing zendframework/zend-http (2.5.5)
Loading from cache
- Removing zendframework/zend-mvc (3.0.1)
- Installing zendframework/zend-mvc (3.0.4)
Downloading: 100%
- Removing phpunit/phpunit (5.7.4)
- Installing phpunit/phpunit (5.7.5)
Downloading: 100%
Writing lock file
Generating autoload files
Создайте файл конфигурации модуля «module.config.php» в /config/ со следующим кодом -
<?php
namespace Tutorial;
use Zend\ServiceManager\Factory\InvokableFactory;
use Zend\Router\Http\Segment;
return [
'controllers' => [
'factories' => [Controller\TutorialController::class => InvokableFactory::class,],
],
'view_manager' => [
'template_path_stack' => ['tutorial' => __DIR__ . '/../view',],
],
];
Файл конфигурации состоит из трех частей, и они следующие:
Controller configuration - Укажите контроллеры, доступные внутри модуля.
Routing configuration - Укажите, как контроллеры в модуле должны быть преобразованы в URL-адреса.
View configuration - Укажите конфигурацию, относящуюся к просмотру движка, например расположение просмотров и т. Д.
Настроить Tutorial модуль в файле конфигурации уровня приложения - myapp / config / modules.config.php.
return ['Zend\Router', 'Zend\Validator', 'Application', 'Tutorial'];
Запустите приложение, выполнив composer serve в корне папки приложения.
Мы успешно добавили новый модуль, но нам все еще нужно добавить Controller, Routing и Views чтобы успешно запустить Tutorial модуль.
Как обсуждалось ранее, controllerиграет важную роль в Zend MVC Framework. Все веб-страницы в приложении должны обрабатываться контроллером.
В Zend MVC Framework контроллеры - это объекты, реализующие - Zend / Stdlib / DispatchableInterface. ВDispatchableInterface имеет единственный метод, dispatch, который получает Request объект в качестве ввода, выполните некоторую логику и вернет Response объект в качестве вывода.
dispatch(Request $request, Response $response = null)
Простой пример объекта Controller, возвращающего «Hello World», выглядит следующим образом:
use Zend\Stdlib\DispatchableInterface;
use Zend\Stdlib\RequestInterface as Request;
use Zend\Stdlib\ResponseInterface as Response;
class HelloWorld implements DispatchableInterface {
public function dispatch(Request $request, Response $response = null) { $response->setContent("Hello World!");
}
}
В DispatchableInterfaceявляется базовым и требует множества других интерфейсов для написания контроллеров высокого уровня. Некоторые из таких интерфейсов следующие:
InjectApplicationEventInterface - Используется для внедрения событий (Zend EventManager)
ServiceLocatorAwareInterface - Используется для поиска служб (Zend ServiceManager)
EventManagerAwareInterface - Используется для управления событиями (Zend EventManager)
Помня об этом, Zend Framework предоставляет множество готовых контроллеров, реализующих эти интерфейсы. Наиболее важные контроллеры описаны ниже.
AbstractActionController
AbstractActionController (Zend / Mvc / Controller / AbstractActionController) является наиболее часто используемым контроллером в Zend MVC Framework. В нем есть все необходимые функции для написания типичной веб-страницы. Он позволяет маршрутам (маршрутизация - это сопоставление URL-адреса запроса с контроллером и одним из его методов) для сопоставленияaction. При совпадении метод, названный в честь действия, будет вызван контроллером.
Например, если маршрут test совпадает и маршрут, test возвращается hello для действий, то helloAction будет вызван метод.
Напишем наш TutorialController используя AbstractActionController.
Создайте новый класс PHP с именем TutorialController за счет расширения AbstractActionController и поместите его в module/Tutorial/src/Controller/ каталог.
Установить Tutorial\Controller как пространство имен.
Напишите indexAction метод.
Вернуть ViewModel объект из indexActionметод. ВViewModel объект используется для отправки данных из контроллера в движок просмотра, который мы увидим в следующих главах.
Полный список кода выглядит следующим образом -
?php
namespace Tutorial\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class TutorialController extends AbstractActionController {
public function indexAction() {
return new ViewModel();
}
}
Мы успешно добавили новый TutorialController.
АннотацияRestfulController
AbstractRestfulController (Zend \ Mvc \ Controller \ AbstractRestfulController) проверяет HTTP method входящего запроса и соответствует действию (методу) с учетом методов HTTP
Например, запрос с методом GET HTTP либо соответствует getList() метод или get() метод, если id параметр находится в запросе.
AbstractConsoleController
AbstractConsoleController (Zend \ Mvc \ Controller \ AbstractConsoleController) похож на AbstractActionController, за исключением того, что он работает только в среде консоли, а не в браузере.
Карты маршрутизации Request URIк конкретному методу контроллера. В этой главе мы увидим, как реализовать маршруты в Zend Framework.
В общем, любой URI состоит из трех частей:
- Сегмент имени хоста,
- Сегмент пути и
- Сегмент запроса.
Например, в URI / URL - http://www.example.com/index?q=data, www.example.com это сегмент имени хоста, index это сегмент пути и q=dataэто сегмент запроса. Обычно при маршрутизации проверяетсяPage segmentпротив набора ограничений. Если какое-либо ограничение совпадает, оно возвращает набор значений. Одна из главных ценностей - это контроллер.
Маршрутизация также проверяет сегмент хоста, сегмент запроса, методы HTTP запроса, заголовки HTTP запроса и т. Д. В определенной ситуации.
Маршрут и RouteStack
Маршрут - это главный объект в маршрутизации. Zend Framework имеет специальный интерфейс для объекта маршрута,RouteInterface. Все объекты маршрута должны реализовывать RouteInterface. Полный список RouteInterface выглядит следующим образом:
namespace Zend\Mvc\Router;
use Zend\Stdlib\RequestInterface as Request;
interface RouteInterface {
public static function factory(array $options = []); public function match(Request $request);
public function assemble(array $params = [], array $options = []);
}
Основной метод - match. Этот метод сопоставления проверяет данный запрос на соответствие определенному в нем ограничению. Если найдено какое-либо совпадение, возвращаетсяRouteMatchобъект. Этот объект RouteMatch предоставляет подробные сведения о согласованном запросе в качестве параметров. Эти параметры можно извлечь изRouteObject используя getParams метод.
Полный список RouteObject выглядит следующим образом:
namespace Zend\Mvc\Router;
class RouteMatch {
public function __construct(array $params); public function setMatchedRouteName($name);
public function getMatchedRouteName();
public function setParam($name, $value);
public function getParams();
public function getParam($name, $default = null);
}
В общем, типичное приложение MVC имеет множество маршрутов. Каждый из этих маршрутов будет обрабатываться в порядке LIFO, и один маршрут будет сопоставлен и возвращен. Если ни один маршрут не найден / не возвращен, приложение возвращает ошибку «Страница не найдена». Zend Framework предоставляет интерфейс для обработки маршрутов,RouteStackInterface. Этот RouteStackInterface имеет возможность добавлять / удалять маршруты.
Полный список RouteStackInterface выглядит следующим образом:
namespace Zend\Mvc\Router;
interface RouteStackInterface extends RouteInterface {
public function addRoute($name, $route, $priority = null); public function addRoutes(array $routes);
public function removeRoute($name); public function setRoutes(array $routes);
}
Zend framework предоставляет две реализации RouteStack интерфейс, и они следующие -
- SimpleRouteStack
- TreeRouteStack
Тип маршрутов
Zend framework предоставляет множество готовых объектов маршрута для всех ситуаций в пространстве имен "Zend \ Mvc \ Router \ Http". Достаточно выбрать и использовать подходящий объект маршрута для данной ситуации.
Доступные маршруты следующие -
Hostname - Используется для сопоставления части URI хоста.
Literal - Используется для соответствия точному URI.
Method - Используется для соответствия HTTP-методу входящего запроса.
Part - Используется для сопоставления части сегмента пути URI с использованием настраиваемой логики.
Regex - Используется для сопоставления сегмента пути URI с помощью шаблона Regex.
Schema - Используется для соответствия схеме URI, такой как http, https и т. Д.
Segment - Используется для сопоставления пути URI путем разделения его на несколько сегментов.
Давайте посмотрим, как написать наиболее часто используемый буквальный и сегментный маршрут. Маршруты обычно указываются в файле конфигурации каждого модуля -module.config.php.
Буквальный маршрут
Обычно маршруты запрашиваются в порядке LIFO. Маршрут Literal предназначен для точного сопоставления пути URI.
Это определяется, как показано ниже -
$route = Literal::factory(array(
'route' => '/path',
'defaults' => array('controller' => 'Application\Controller\IndexController',
'action' => 'index',),
));
Указанный выше маршрут соответствует /path в URL-адресе запроса и возвращает index как action и IndexController как контролер.
Сегмент Маршрут
Сегментированный маршрут используется всякий раз, когда ваш URL-адрес должен содержать переменные параметры.
Это описано, как указано ниже -
$route = Segment::factory(array(
'route' => '/:controller[/:action]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]+',
'action' => '[a-zA-Z][a-zA-Z0-9_-]+',
),
'defaults' => array(
'controller' => 'Application\Controller\IndexController',
'action' => 'index',),
));
Здесь сегменты обозначаются двоеточием, за которым следуют буквенно-цифровые символы. Если оставить сегмент необязательным, то он будет заключен в квадратные скобки. Каждый сегмент может иметь связанные с ним ограничения. Каждое ограничение - это регулярное выражение.
Настройка маршрута в учебном модуле
Давайте добавим сегментный маршрут в наш учебный модуль. Обновите файл конфигурации учебного модуля -module.config.php доступны на myapp/module/Tutorial/config.
<?php
namespace Tutorial;
use Zend\ServiceManager\Factory\InvokableFactory;
use Zend\Router\Http\Segment;
return [
'controllers' => [
'factories' => [
Controller\TutorialController::class => InvokableFactory::class,
],
],
'router' => [
'routes' => [
'tutorial' => [
'type' => Segment::class,
'options' => [
'route' => '/tutorial[/:action[/:id]]',
'constraints' => [
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
],
'defaults' => [
'controller' => Controller\TutorialController::class,
'action' => 'index',
],
],
],
],
],
'view_manager' => [
'template_path_stack' => ['tutorial' => __DIR__ . '/../view',],
],
];
Мы успешно добавили маршрутизацию для нашего Tutorialмодуль. Мы всего на один шаг отстали в завершении нашего учебного модуля. Нам нужно добавитьView для нашего модуля, о котором мы узнаем в следующей главе.
Слой представления - это уровень представления приложения MVC. Он отделяет логику приложения от логики представления. В типичном веб-приложении PHP вся бизнес-логика и дизайн перемешаны. Перемешивание позволяет ускорить разработку небольшого проекта. Но он терпит неудачу в большом проекте, где задействовано много архитектуры высокого уровня. Чтобы изменить дизайн веб-приложения, разработчику также необходимо поработать над бизнес-логикой. Это может иметь катастрофические последствия и привести к нарушению бизнес-логики.
Zend Framework предоставляет хорошо продуманный, чистый, гибкий и расширяемый слой просмотра. Слой View доступен как отдельный модуль,Zend/View и прекрасно интегрировать с Zend/Mvcмодуль. Слой Zend View разделен на несколько компонентов, прекрасно взаимодействующих друг с другом.
Его различные компоненты следующие:
Variables Containers - Содержит данные слоя просмотра.
View Models - Содержит переменные контейнеры и шаблон дизайна.
Renderers - Обработайте данные и шаблон из модели представления и выведите представление проекта, возможно, окончательный вывод в формате html.
Resolvers - Разрешает шаблон, доступный в модели представления, таким образом, чтобы средство визуализации могло его использовать.
View (Zend\View\View) - Сопоставляет запрос рендереру, а затем рендереру ответ.
Rendering Strategies - Используется View для отображения запроса на рендерер.
Response Strategies - Используется View для отображения ответа на рендерер.
Слой просмотра, View обрабатывает ViewModel, разрешает шаблон с помощью Resolver, сделайте это с помощью Rendering Strategy и, наконец, выводит его с помощью Response Renderer.
Просмотр конфигурации слоя
Как и контроллер, уровень просмотра можно настроить в файле конфигурации модуля, который называется - module.config.php. Основная конфигурация - указать, где будут размещаться шаблоны. Это можно сделать, добавив следующую конфигурацию в «module.config.php».
'view_manager' => [
'template_path_stack' => ['tutorial' => __DIR__ . '/../view',],
]
По умолчанию слой View имеет поведение по умолчанию для всех своих компонентов. Например,ViewModelразрешает имя шаблона действия контроллера внутри корня шаблона по правилу «нижний регистр имя модуля / нижний регистр имени контроллера / нижний регистр имени действия». Однако это может быть отмененоsetTemplate() метод ViewModel.
Контроллеры и слой представления
По умолчанию контроллеру не нужно отправлять какие-либо данные на уровень представления. Достаточно написать шаблон в нужном месте.
Например, в нашем примере TutorialController, шаблон необходимо разместить в myapp/module/Tutorial/view/tutorial/tutorial/index.phtml. Вindex.phtmlссылается на шаблон на основе PHP, и он будет отображаться PHPRenderer. Существуют и другие средства визуализации, такие какJsonRenderer за json выход и FeedRenderer за rss и atom вывод.
Полный список выглядит следующим образом -
<?php
namespace Tutorial\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class TutorialController extends AbstractActionController {
public function indexAction() {
}
}
Шаблон приложения Zend
<div class = "row content">
<h3>This is my first Zend application</h3>
</div>
Наконец, мы успешно завершили Tutorial модуль, и мы можем получить к нему доступ, используя url - http://localhost:8080/tutorial.
Передача данных на уровень просмотра
Самый простой способ отправить данные на уровень представления - использовать ViewModelаргументы. ИзмененныйindexAction метод выглядит следующим образом -
public function indexAction() {
$view = new ViewModel([ 'message' => 'Hello, Tutorial' ]); return $view;
}
Теперь измените index.phtml файл следующим образом -
<div class = "row content">
<h3>This is my first Zend application</h3>
<h4><?php echo $this->message?></h4>
</div>
Просмотр помощников
Помощник по представлению используется для написания небольших элементарных функций, которые будут использоваться в шаблонах. Zend framework предоставляет интерфейс Zend \ View \ Helper \ HelperInterface для написания стандартных помощников представления.
HelperInterface имеет всего два метода:
setView() - Этот метод принимает экземпляр / реализацию Zend \ View \ Renderer \ RendererInterface.
getView() - Он используется для получения этого экземпляра.
Полный листинг кода HelperInterface выглядит следующим образом -
namespace Zend\View\Helper;
use Zend\View\Renderer\RendererInterface as Renderer;
interface HelperInterface {
/**
* Set the View object
*
* @param Renderer $view
* @return HelperInterface
*/
public function setView(Renderer $view);
/**
* Get the View object
*
* @return Renderer
*/
public function getView();
}
Чтобы использовать помощник в сценарии просмотра, откройте его, используя $this->helperName().
Встроенные помощники
Zend Framework предоставляет множество встроенных вспомогательных функций для различных целей. Некоторые из помощников просмотра, доступных вzend-mvc следующие -
URL
Помощник URL используется для генерации URL-адресов, соответствующих маршрутам, определенным в приложении.
Определение помощника URL-адреса -
$this->url($name, $params, $options, $reuseMatchedParameters)
Например, в учебном модуле маршрут называется tutorial и имеет два параметра action и id. Мы можем использовать помощник URL-адресов для создания двух разных URL-адресов, как показано ниже -
<a href = "<? = $this->url('tutorial'); ?>">Tutorial Index</a>
<a href = "<? = $this->url('tutorial', ['action' => 'show', 'id' =>10]); ?>">
Details of Tutorial #10
</a>
Результат будет следующим -
<a href = "/tutorial">Tutorial Index</a>
<a href = "/tutorial/show/10"> Details of Tutorial #10</a>
Заполнитель
Помощник-заполнитель используется для сохранения содержимого между сценариями представления и экземплярами представления. Он предоставляет возможность изначально установить данные, а затем использовать их на более поздних этапах.
Например, мы можем установить, скажем, company name а затем использовать его во всех других местах.
<?php $this->placeholder('companyname')->set("TutorialsPoint") ?>
<?= $this->placeholder('companyname'); ?>
Заполнитель предоставляет некоторые дополнительные параметры для создания сложного содержимого из массива и объектов PHP. Он также имеет возможность захватывать определенный раздел самого шаблона.
Например, следующий код фиксирует промежуточный результат шаблона и сохраняет его в productlist заполнитель.
Class – Product
class Product {
public $name;
public $description;
}
Controller
$p1 = new Product();
$p1->name = 'Car'; $p1->description = 'Car';
$p2 = new Product(); $p2->name = 'Cycle';
$p2->description = 'Cycle'; $view = new ViewModel(['products' => $products]);
Template
<!-- start capture -->
<?php $this->placeholder('productlist')->captureStart();
foreach ($this->products as $product): ?>
<div>
<h2><?= $product->name ?></h2> <p><?= $product->description ?></p>
</div>
<?php endforeach; ?>
<?php $this->placeholder('productlist')->captureEnd() ?> <!-- end capture --> <?= $this->placeholder('productlist') ?>
Result
<div class = "foo">
<h2>Car</h2>
<p>Car</p>
</div>
<div class = "foo">
<h2>Cycle</h2>
<p>Cycle</p>
</div>
Doctype
Помощник Doctype используется для создания различных типов документов HTML. Это конкретная реализацияPlaceholderпомощник. Тип документа может быть установлен в файле начальной загрузки и файле конфигурации.
Основное использование показано ниже -
Application Bootstrap file
use Zend\View\Helper\Doctype;
$doctypeHelper = new Doctype(); $doctypeHelper->doctype('XHTML5');
Module Configuration
// module/Application/config/module.config.php:
return [
/* ... */
'view_manager' => [
'doctype' => 'html5',
/* ... */
],
];
Template
<?php echo $this->doctype() ?>
HeadTitle
Помощник HeadTitle используется для создания элемента заголовка html. Это конкретная реализацияPlaceholderпомощник. Zend предоставляет возможность установить заголовок в файле конфигурации модуля, и его можно установить на любом уровне, таком как сайт, модуль, контроллер, действие и т. Д. Частичный код для HeadTitle выглядит следующим образом:
Module
headTitleHelper->append($action);
$headTitleHelper->append($controller);
$headTitleHelper->append($module);
$headTitleHelper->append($siteName);
Template
<?= $this->headTitle() ?>
Result
action - controller - module - Zend Framework
HeadMeta
Помощник HeadMeta используется для создания метатегов html. Это конкретная реализация помощника Placeholder.
Template -
<?php
$this->headMeta()->appendName('keywords', 'turorialspoint, zend framework, php');
echo $this->headMeta()
?>
Result
<meta name = "keywords" content = "tutorialspoint, zend framework, php" />
HeadLink
Помощник HeadLink используется для создания HTML-ссылок для включения внешних ресурсов. Это конкретная реализация помощника Placeholder.
Template
<?php
// setting links in a view script:
$this->headLink(['rel' => 'icon', 'href' => '/img/favicon.ico'], 'PREPEND')
->appendStylesheet('/styles/site.css')
->prependStylesheet('/styles/mystyle.css', 'screen', true, ['id' => 'mystyle']);
// rendering the links from the layout:
echo $this->headLink();
?>
Result
<link href = "/styles/mystyle.css" media = "screen" rel = "stylesheet"
type = "text/css" id = "mystyle">
<link href = "/img/favicon.ico" rel = "icon">
<link href = "/styles/site.css" media = "screen" rel = "stylesheet" type = "text/css">
HeadStyle
Помощник HeadStyle используется для создания встроенных стилей CSS. Это конкретная реализация помощника Placeholder.
Template
<?php $this->headStyle()->appendStyle($styles); ?> <?php echo $this->headStyle() ?>
HeadScript
HeadScript используется для создания встроенного скрипта или для включения внешних скриптов. Это конкретная реализация помощника Placeholder.
Template
<? $this->headScript()->appendFile(‘/js/sample.js’);?> <?php echo $this->headScript() ?>
InlineScript
InlineScript используется для создания сценария как в заголовке, так и в основной части шаблона html. Он получен из HeadScript.
HTMLList
HTMLList используется для создания упорядоченного и неупорядоченного списка. Определение HTMLList следующее:
Definition
htmlList($items, $ordered, $attribs, $escape)
Template
$items = [ '2015', ['March', 'November'], '2016', ]; echo $this->htmlList($items);
Result
<ul>
<li>2015
<ul>
<li>March</li>
<li>November</li>
</ul>
</li>
<li>2016</li>
</ul>
Цикл
Цикл используется для создания альтернатив в циклической среде. У него есть функции assign, next и prev.
Controller
$view = new ViewModel(['message' => 'Hello, Tutorial', 'data' => array('One', 'Two')]);
Template
<?php $this->cycle()->assign(['#F0F0F0', '#FFF'], 'colors'); ?> <table> <?php foreach ($this->data as $datum): ?> <tr style = "background-color: <?= $this->cycle()->setName('colors')>next() ?>">
<td><?= $this->escapeHtml($datum) ?></td>
</tr>
<?php endforeach ?>
</table>
Result
<table>
<tr style = "background-color: #F0F0F0">
<td>One</td>
</tr>
<tr style = "background-color: #FFF">
<td>Two</td>
</tr>
</table>
Вот несколько других важных встроенных помощников:
BasePath - BasePath используется для создания пути к общей папке корня приложения.
Partial - Частичный используется для рендеринга определенного шаблона в его собственной переменной области.
PartialLoop - PartialLoop похож на Partial, но используется в циклической среде.
Identity - Удостоверение используется для получения идентификационных данных вошедшего в систему пользователя из службы аутентификации.
JSON- JSON используется в спокойной среде, где вывод находится в формате JSON. Он генерирует правильный HTTP-заголовок и отключает концепцию макета.
В Zend Framework по-прежнему доступно множество помощников, таких как i18n helper, form helpers, pagination helpers, navigation helpers, и т.д.
Создание помощников просмотра
Zend Framework предоставляет встроенный AbstractHelper реализация HelperInterface написать помощников просмотра.
Шаги, необходимые для написания нового помощника, следующие:
Step 1 - Расширить класс Zend \ View \ Helper \ AbstractHelper.
Step 2 - Отменить __invoke() функция.
Step 3 - Установите конфигурацию в module.config.php file.
Step 4 - Используйте помощник просмотра в сценариях просмотра.
Давайте теперь создадим TestHelper
Создать папку Helper в myapp/module/Tutorial/src/View directory. НаписатьTestHelper внутри каталога Helper, TestHelper.php.
Полный список выглядит следующим образом -
<?php
namespace Tutorial\View\Helper;
use Zend\View\Helper\AbstractHelper;
class TestHelper extends AbstractHelper {
public function __invoke() {
$output = "I am from test helper"; return htmlspecialchars($output, ENT_QUOTES, 'UTF-8');
}
}
Установить конфигурацию в module.config.php.
'view_helpers' => [
'aliases' => [
'testHelper' => View\Helper\TestHelper::class,
],
'factories' => [
View\Helper\TestHelper::class => InvokableFactory::class,
],
],
Используйте только что созданный TestHelper в about просмотр скрипта.
<?= $this->testHelper() ?>
Макет представляет собой общие части нескольких представлений, например, верхний и нижний колонтитулы страницы. По умолчанию макеты должны храниться вview/layout папка.
Конфигурация макета определяется под view_manager раздел в файле module.config.php.
Конфигурация скелетного приложения по умолчанию выглядит следующим образом:
'view_manager' => array(
'display_not_found_reason' => true,
'display_exceptions' => true,
'doctype' => 'HTML5',
'not_found_template' => 'error/404',
'exception_template' => 'error/index',
'template_map' => array(
'layout/layout' => __DIR__ . '/../view/layout/layout.phtml',
'application/index/index' => __DIR__ . '/../view/application/index/index.phtml',
'error/404' => __DIR__ . '/../view/error/404.phtml',
'error/index' => __DIR__ . '/../view/error/index.phtml',
),
'template_path_stack' => array(
__DIR__ . '/../view',
),
Здесь template_mapиспользуется для указания макета. Если макет не найден, он вернет ошибку. Давайте посмотрим на основной макет скелетного приложения.
Layout.phtml
<?= $this->doctype() ?>
<html lang = "en">
<head>
<meta charset = "utf-8">
<?= $this->headTitle('ZF Skeleton Application')->setSeparator(' - ')> setAutoEscape(false) ?> <?= $this->headMeta()
->appendName('viewport', 'width = device-width, initial-scale = 1.0')
->appendHttpEquiv('X-UA-Compatible', 'IE = edge')
?>
<!-- Le styles -->
<?= $this->headLink(['rel' => 'shortcut icon', 'type' => 'image/vnd.microsoft.icon', 'href' => $this->basePath() . '/img/favicon.ico'])
->prependStylesheet($this->basePath('css/style.css')) ->prependStylesheet($this->basePath('css/bootstraptheme.min.css'))
->prependStylesheet($this->basePath('css/bootstrap.min.css')) ?> <!-- Scripts --> <?= $this->headScript()
->prependFile($this->basePath('js/bootstrap.min.js')) ->prependFile($this->basePath('js/jquery-3.1.0.min.js'))
?>
</head>
<body>
<nav class = "navbar navbar-inverse navbar-fixed-top" role = "navigation">
<div class = "container">
<div class = "navbar-header">
<button type = "button" class = "navbar-toggle" data-
toggle = "collapse" data-target = ".navbar-collapse">
<span class = "icon-bar"></span>
<span class = "icon-bar"></span>
<span class = "icon-bar"></span>
</button>
<a class = "navbar-brand" href = "<?= $this->url('home') ?>"> <img src = "<?= $this->basePath('img/zf-logo-mark.svg') ?>
" height = "28" alt = "Zend Framework <?= \Application\Module::
VERSION ?>"/> Skeleton Application
</a>
</div>
<div class = "collapse navbar-collapse">
<ul class = "nav navbar-nav">
<li class = "active"><a href = "<?=
$this->url('home') ?>">Home</a></li> </ul> </div> </div> </nav> <div class = "container"> <?= $this->content ?>
<hr>
<footer>
<p>© 2005 - <?= date('Y') ?> by Zend Technologies Ltd.
All rights reserved.</p>
</footer>
</div>
<?= $this->inlineScript() ?>
</body>
</html>
Когда вы анализируете макет, он в основном использует помощников представления, которые мы обсуждали в предыдущей главе. При ближайшем рассмотрении в макете используется специальная переменная,$this->content. Эта переменная важна, так как она будет заменена сценарием просмотра (шаблоном) фактически запрошенной страницы.
Создание нового макета
Давайте создадим новый макет для нашего учебного модуля.
Для начала создадим tutorial.css file в каталоге «public / css».
body {
background-color: lightblue;
}
h1 {
color: white;
text-align: center;
}
Создайте новый файл макета newlayout.phtmlв / myapp / module / Tutorial / view / layout / и скопируйте содержимое из существующего макета. Затем добавьтеtutorial.css таблица стилей с использованием HeadLink вспомогательный класс внутри раздела заголовка макета.
<?php echo $this->headLink()->appendStylesheet('/css/tutorial.css');?>
Добавить новый about ссылку в разделе навигации с помощью URL помощник.
<li><a href = "<?= $this->url('tutorial', ['action' => 'about']) ?>">About</a></li>
Эта страница макета является общей для приложения учебного модуля. Обновитеview_manager раздел конфигурационного файла учебного модуля.
'view_manager' => array(
'template_map' => array(
'layout/layout' => __DIR__ . '/../view/layout/newlayout.phtml'),
'template_path_stack' => array('tutorial' => __DIR__ . '/../view',),
)
Добавить aboutAction функция в TutorialController.
public function aboutAction() {
}
Добавить about.phtml в myapp / module / Tutorial / view / tutorial / tutorial / со следующим содержимым.
<h2>About page</h2>
Теперь вы готовы, наконец, запустить приложение - http://localhost:8080/tutorial/about.
В этой главе мы обсудим различные модели и базу данных Zend Framework.
Модели в Zend Framework
Модель определяет логическое представление данных приложения. Например, в приложении корзины покупок - Product, Customer, Cart и Orders являются моделями. Они определяют свойства удерживаемого объекта. Некоторые из концепций моделей следующие:
Контроллеры общаются с моделями и просят их получить необходимую информацию. Эта полученная информация затем передается контроллером в представление. Наконец, View будет отображать модель как потребляемые пользователем презентационные данные.
Очень редко модель напрямую взаимодействует с представлением, но иногда это может случиться.
Модели могут разговаривать друг с другом и не замкнуты. У них отношения друг с другом. Эти отношения упрощают и ускоряют получение информации контроллером, поскольку ему не нужно взаимодействовать с разными моделями; модели могут сделать это сами.
Давайте посмотрим на простую модель - MyModel
<?php
namespace Tutorial\Model;
class Book {
public $id; public $author;
public $title;
}
База данных в Zend Framework
Zend framework предоставляет простой и многофункциональный класс Zend \ Db \ TableGateway \ TableGateway для поиска, вставки, обновления и удаления данных из таблицы базы данных.
Давайте посмотрим, как подключить MySqlservice через драйвер PHP PDO в Zend framework, выполнив следующие действия.
Шаг 1. Создайте базу данных в MySQL
Создать базу данных tutorialsна локальном сервере MySQL. Мы можем использоватьphpmyadminили любые другие инструменты MySQL GUI для этой цели. Давайте использоватьMySQL clientв командной строке. Подключитесь к серверу mysql и выполните следующую команду, чтобы создатьtutorial база данных.
create database tutorials
Шаг 2: Создайте таблицу в учебной базе данных
Давайте теперь создадим базу данных book в tutorials db, используя следующую команду SQL.
use tutorials;
CREATE TABLE book (
id int(11) NOT NULL auto_increment,
author varchar(100) NOT NULL,
title varchar(100) NOT NULL,
PRIMARY KEY (id)
);
Шаг 3. Заполните данные в таблице книги
Заполните bookтаблица с образцами данных. Используйте следующую команду SQL.
INSERT INTO book (author, title) VALUES ('Dennis Ritchie', 'C Programming');
INSERT INTO book (author, title) VALUES ('James gosling', 'Java Programming');
INSERT INTO book (author, title) VALUES ('Rasmus Lerdorf', 'Programming PHP');
Шаг 4: Обновите соединение с базой данных
Обновите файл глобальной конфигурации - myapp / config / autoload / global.php, указав необходимую информацию о диске базы данных.
<?php
return array(
'db' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname = tutorials;host = localhost',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
),
'service_manager' => array(
'factories' => array(
'Zend\Db\Adapter\Adapter' => 'Zend\Db\Adapter\AdapterServiceFactory',
),
),
);
Шаг 5. Обновите учетные данные базы данных
Обновите учетные данные базы данных в локальном файле конфигурации - myapp / config / autoload / local.php. Таким образом, мы можем разделить учетные данные для подключения к локальной и действующей базе данных.
<?php
return array(
'db' => array(
'username' => '<user_name>',
'password' => '<password>',
),
);
Шаг 6: Создайте модель для книги
Давайте создадим модель, Book в нашем модуле srcкаталог. Обычно модели сгруппированы в папке Model - /myapp/module/Tutorial/src/Model/Book.php.
<?php
namespace Tutorial\Model;
class Book {
public $id;
public $author; public $title;
}
Шаг 7. Внедрите exchangeArray в модель книги
В TableGateway взаимодействует с моделью через exchangeArrayфункция. Стандартный аргумент функции exchangeArray - это набор результатов базы данных, хранящийся в виде массива PHP. ИспользуяexchangeArrayfunction, свойство модели можно легко синхронизировать с соответствующей таблицей базы данных.
Обновите модель, Book как показано ниже -
<?php
namespace Tutorial\Model;
class Book {
public $id; public $author;
public $title; public function exchangeArray($data) {
$this->id = (!empty($data['id'])) ? $data['id'] : null; $this->Author = (!empty($data['author'])) ? $data['author'] : null;
$this->Title = (!empty($data['title'])) ? $data['title'] : null;
}
}
Шаг 8. Используйте TableGateway для получения книги
Создайте класс, BookTableдля получения информации о книге из базы данных. Создайте класс BookTable вModel сама папка.
<?php
namespace Tutorial\Model;
use Zend\Db\TableGateway\TableGatewayInterface;
class BookTable {
protected $tableGateway;
public function __construct(TableGatewayInterface $tableGateway) { $this->tableGateway = $tableGateway; } public function fetchAll() { $resultSet = $this->tableGateway->select(); return $resultSet;
}
}
Мы использовали select()метод класса TableGateway для получения информации о книге из базы данных. Но мы не использовали ссылку на таблицу -bookв коде. TableGateway является универсальным по своей природе и может получать данные из любой таблицы, используя определенную конфигурацию. Обычно эти конфигурации выполняются вmodule.config.php файл, который мы обсудим в следующих шагах.
Шаг 9. Настройте класс BookTable
Обновите учебный модуль, Module.php с getServiceConfig() метод.
<?php
namespace Tutorial;
use Zend\Db\Adapter\AdapterInterface;
use Zend\Db\ResultSet\ResultSet;
use Zend\Db\TableGateway\TableGateway;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
class Module implements ConfigProviderInterface {
public function getConfig() {
return include __DIR__ . '/../config/module.config.php';
}
public function getServiceConfig() {
return [
'factories' => [
Model\BookTable::class => function ($container) { $tableGateway = $container->get(Model\BookTableGateway::class); $table = new Model\BookTable($tableGateway); return $table;
},
Model\BookTableGateway::class => function ($container) { $dbAdapter = $container->get(AdapterInterface::class); $resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Model\Book()); return new TableGateway('book', $dbAdapter, null, $resultSetPrototype);
},
],
];
}
}
Здесь мы зарегистрировали BookTableкласс с помощью диспетчера служб. Класс BookTable используется для получения информации о книге, и, зарегистрировав ее, мы можем получить к ней доступ в любом месте. Поскольку зарегистрированные службы являются общими, они увеличивают производительность, уменьшают потребление памяти и т. Д.
Другой элемент, Model \ BookTableGateway :: class, является объектом TableGateway, специализированным для Book модель и является зависимостью BookTable.
Шаг 10: Обновите конфигурацию TutorialController
Нам нужен BookTableв контроллере учебника для получения информации о книге. Чтобы получить службу BookTable, зарегистрируйте ее как зависимость конструктора в TutorialController.
Эта зависимость конструктора помогает получить службу BookTable, пока сам контроллер находится на стадии инициализации. Обновите раздел контроллера конфигурации учебного модуля,module.config.php как показано ниже.
'controllers' => [
'factories' => [
Controller\TutorialController::class => function($container) {
return new Controller\TutorialController(
$container->get(Model\BookTable::class)
);
},
],
],
Шаг 11: Обновите Tutorial Controller
Это делается путем соблюдения следующих трех шагов.
- Добавить конструктор с BookTable в качестве аргумента.
private $table;
public function __construct(BookTable $table) { $this->table = $table;
}
Получить информацию о книге с помощью BookTable's fetchAll() метод и зарегистрируйте его в представлении.
public function indexAction() {
$view = new ViewModel([
'data' => $this->table->fetchAll(), ]); return $view;
}
Отобразите информацию о книге в скрипте просмотра.
<table class = "table">
<tr>
<th>Author</th>
<th>Title</th>
<th> </th>
</tr>
<?php foreach ($data as $sampledata) : ?>
<tr>
<td><?php echo $this->escapeHtml($data->author);?></td>
<td><?php echo $this->escapeHtml($data->title);?></td>
</tr>
<?php endforeach ?>
</table>
Шаг 12: Запустите приложение
Проверьте приложение, запустив - http://localhost:8080/tutorial.
Как обсуждалось в предыдущей главе, Zend framework предоставляет общий способ доступа к базе данных с помощью Database Driverконцепция. Работа с базой данных зависит исключительно от информации о драйвере, поэтому подключение к другой базе данных требует простого изменения информации о драйвере.
Давайте теперь изменим book пример подключения к postgresql базу данных со следующими шагами.
Step 1 - Создайте базу данных, учебники в локальной базе данных postgresql, используя следующую команду -
CREATE DATABASE tutorials
Step 2 - Добавить bookстол. Перейдите в новую базу данных и выполните сценарий создания таблицы.
\c tutorials
CREATE TABLE book (
id SERIAL NOT NULL,
author varchar(100) NOT NULL,
title varchar(100) NOT NULL,
PRIMARY KEY (id)
);
Step 3 - Добавьте информацию о книге с образцами, используя следующий скрипт -
INSERT INTO book (author, title) VALUES ('Dennis Ritchie', 'C Programming');
INSERT INTO book (author, title) VALUES ('James gosling', 'Java Programming');
INSERT INTO book (author, title) VALUES ('Rasmus Lerdorf', 'Programming PHP');
Step 4 - Измените информацию о драйвере в global.config file.
<?php
return array (
'db' => array (
'driver' => 'Pdo',
'dsn' => 'pgsql:dbname = tutorials;host = localhost',
'driver_options' => array (
),
),
);
Step 5 - Измените учетные данные базы данных в local.config файл.
return array (
'db' => array(
'username' => '<username>',
'password' => '<password>',
),
);
Step 6 - Наконец, запустите приложение http://localhost:8080/tutorial. Результат такой же, как и в приложении MySQL.
Zend Framework предоставляет отдельный компонент, zend-formдля ускорения процесса создания и проверки формы. Он соединяет модель и слой вида. Он предоставляет набор элементов формы для создания полноценной html-формы из предопределенных моделей,InputFilter класс для проверки модели на соответствие форме и варианты привязки данных из формы к модели и наоборот.
Установить компонент формы
Компонент формы Zend можно установить с помощью Composer команда, как указано ниже -
composer require zendframework/zend-form
Платформа форм Zend имеет три подкомпонента для управления формами. Они подробно описаны ниже -
Elements - Используется для определения одного элемента управления вводом html, сопоставленного со свойством в модели.
Fieldset - Используется для группировки элементов и прочего fieldset вложенным образом.
Form - Используется для создания HTML-формы и состоит из элементов и наборов полей.
Формы Zend обычно создаются под module//src/Form каталог.
пример
Давайте теперь создадим простую форму для добавления bookв базу данных. Для этого мы должны придерживаться следующих шагов -
Шаг 1. Создайте BookForm
Создайте «BookForm.php» в каталоге * myapp / module / Tutorial / src / Form ». Добавьте следующие изменения в файл -
<?php
namespace Tutorial\Form;
use Zend\Form\Form;
class BookForm extends Form {
public function __construct($name = null) { parent::__construct('book'); $this->add(array(
'name' => 'id',
'type' => 'Hidden',
));
$this->add(array( 'name' => 'author', 'type' => 'Text', 'options' => array( 'label' => 'Author', ), )); $this->add(array(
'name' => 'title',
'type' => 'Text',
'options' => array(
'label' => 'Title',
),
));
$this->add(array(
'name' => 'submit',
'type' => 'Submit',
'attributes' => array(
'value' => 'Go',
'id' => 'submitbutton',
),
));
}
}
В Form класс предоставляет add methodдля сопоставления модели и соответствующих деталей формы. мы создалиBookForm за счет расширения Form class и добавил детали формы для Book модель.
Шаг 2. Обновите модель книги, Book.php
Обновите модель, ‘Book’ с фильтром и проверкой, как указано ниже -
<?php
namespace Tutorial\Model;
use Zend\InputFilter\InputFilterInterface;
use Zend\InputFilter\InputFilterAwareInterface;
use Zend\InputFilter\InputFilter;
class Book implements InputFilterAwareInterface {
public $id;
public $author; public $title;
protected $inputFilter; public function setInputFilter(InputFilterInterface $inputFilter) {
throw new \Exception("Not used");
}
public function getInputFilter() {
if (!$this->inputFilter) { $inputFilter = new InputFilter();
$inputFilter->add(array( 'name' => 'id', 'required' => true, 'filters' => array( array('name' => 'Int'), ), )); $inputFilter->add(array(
'name' => 'author',
'required' => true,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'min' => 1,
'max' => 100,
),
),
),
));
$inputFilter->add(array( 'name' => 'title', 'required' => true, 'filters' => array( array('name' => 'StripTags'), array('name' => 'StringTrim'), ), 'validators' => array( array( 'name' => 'StringLength', 'options' => array( 'encoding' => 'UTF-8', 'min' => 1, 'max' => 100, ), ), ), )); $this->inputFilter = $inputFilter; } return $this->inputFilter;
}
public function exchangeArray($data) { $this->id = (!empty($data['id'])) ? $data['id'] : null;
$this->author = (!empty($data['author'])) ? $data['author'] : null; $this->title = (!empty($data['title'])) ? $data['title'] : null;
}
}
Каждая модель должна реализовывать InputFilterAwareInterface. InputFilterAwareInterface предоставляет два метода:setInputFilter() и getInputFilter().
GetInputFilter используется для получения сведений о проверке модели. Zend framework предоставляет богатый набор фильтров и валидаторов для проверки формы. Некоторые из фильтров и валидаторов, используемых в модели книги, следующие:
StripTags - Удалите ненужный HTML.
StringTrim - Удалите ненужные пробелы.
StringLength validator - Убедитесь, что пользователь не вводит больше символов, чем указано.
Шаг 3. Обновите класс BookTable
Включите saveBook метод добавления книги в базу данных.
BookTable.php
<?php
namespace Tutorial\Model;
use Zend\Db\TableGateway\TableGatewayInterface;
class BookTable {
protected $tableGateway; public function __construct(TableGatewayInterface $tableGateway) {
$this->tableGateway = $tableGateway;
}
public function fetchAll() {
$resultSet = $this->tableGateway->select();
return $resultSet; } public function getBook($id) {
$id = (int) $id;
$rowset = $this->tableGateway->select(array('id' => $id)); $row = $rowset->current(); if (!$row) {
throw new \Exception("Could not find row $id"); } return $row;
}
public function saveBook(Book $book) { $data = array (
'author' => $book->author, 'title' => $book->title,
);
$id = (int) $book->id;
if ($id == 0) { $this->tableGateway->insert($data); } else { if ($this->getBook($id)) { $this->tableGateway->update($data, array('id' => $id));
} else {
throw new \Exception('Book id does not exist');
}
}
}
}
Шаг 4. Обновите класс TutorialController
Добавьте новое действие addAction в учебный контроллер - myapp / module / Tutorial / src / Controller / TutorialController.php.
public function addAction() {
$form = new BookForm(); $form->get('submit')->setValue('Add');
$request = $this->getRequest();
if ($request->isPost()) { $book = new Book();
$form->setInputFilter($book->getInputFilter());
$form->setData($request->getPost());
if ($form->isValid()) { $book->exchangeArray($form->getData()); $this->bookTable->saveBook($book); // Redirect to list of Tutorial return $this->redirect()->toRoute('tutorial');
}
}
return array('form' => $form);
}
В addAction метод выполняет следующие процессы -
Получает объект запроса.
Проверяет, является ли метод http запроса post метод.
Если http-метод запроса не post, он просто отображает шаблон, add.phtml
Если http-метод запроса не post, затем он устанавливает inputfilter, получает данные запроса и помещает их во входной файл.
Проверяет, действительна ли форма, используя isValid() метод класса Form.
Если форма недействительна, она снова отображает шаблон, add.phtml
Если форма действительна, она сохраняет книгу в базе данных и перенаправляет на домашнюю страницу.
Шаг 5: Добавьте шаблон add.phtml
Создайте шаблон - add.phtml в myapp / module / Tutorial / view / tutorial / tutorial / add.phtml
Add.phtml
<?php
$title = 'Add new Book';
$this->headTitle($title);
?>
<h1><?php echo $this->escapeHtml($title); ?></h1>
<?php
if(!empty($form)) { $form->setAttribute('action', $this->url('tutorial', array('action' => 'add'))); $form->prepare();
echo $this->form()->openTag($form);
echo $this->formHidden($form->get('id'));
echo $this->formRow($form->get('author'))."<br>";
echo $this->formRow($form->get('title'))."<br>";
echo $this->formSubmit($form->get('submit'));
echo $this->form()->closeTag();
}
Здесь мы отображаем форму книги с помощью Form пример, $form.
Шаг 6: Запустите приложение
Теперь мы можем запустить приложение - http://localhost:8080/tutorial/add.
Form Page
Validate Error Page
Загрузка файлов - одна из основных концепций программирования форм. Zend framework предоставляет все необходимые элементы для загрузки файлов черезzend-form и zend-inputfilter составная часть.
FileInput Класс
Компонент zend-inputfilter предоставляет класс Zend \ InputFilter \ FileInput для обработки элемента ввода файла html - <input type = 'file' />. ВFileInputаналогичен другим входным фильтрам, за некоторыми исключениями. Они следующие -
Поскольку PHP сохраняет сведения о загруженном файле в $_FILES глобальный массив, FileInput собирает информацию о загруженном файле только через $ _FILES.
Проверка должна выполняться до того, как класс FileInput обработает данные. Это противоположное поведение других входных фильтров.
Zend \ Validator \ File \ UploadFile - это валидатор по умолчанию. ВUploadFile проверяет входные данные файла.
Чтобы добавить тип загрузки файла в форму, нам нужно использовать тип ввода File. Частичный код выглядит следующим образом -
$form->add(array(
'name' => 'imagepath',
'type' => 'File',
'options' => array('label' => 'Picture',),
));
Другой класс, используемый при загрузке файлов, - это Zend \ Filter \ File \ RenameUpload. ВRenameUploadиспользуется для перемещения загруженного файла в желаемое место. Частичный класс для использования фильтра файлов выглядит следующим образом:
$file = new FileInput('imagepath');
$file->getValidatorChain()->attach(new UploadFile()); $file->getFilterChain()->attach(
new RenameUpload([
'target' => './public/tmpuploads/file',
'randomize' => true,
'use_upload_extension' => true
]));
$inputFilter->add($file);
Здесь варианты RenameUpload следующие -
target - Путь назначения загруженного файла.
randomize - Добавьте случайную строку, чтобы предотвратить дублирование загруженного файла.
use_upload_extension - Добавьте расширение файла к загружаемому файлу в целевой.
Загрузка файла - рабочий пример
Давайте изменим учебный модуль и включим функцию загрузки изображений.
Изменить таблицу базы данных
Добавим imagepath столбец в таблицу книги, выполнив следующую команду SQL -
ALTER TABLE `book` ADD `imagepath` VARCHAR(255) NOT NULL AFTER 'imagepath';
Обновите BookForm.php
Добавьте элемент ввода файла для загрузки изображения в форме книги - myapp / module / Tutorial / src / Model / BookForm.php.
Включите следующий код в __constructmethod класса BookForm.
$this->add(array(
'name' => 'imagepath',
'type' => 'File',
'options' => array ('label' => 'Picture',),
));
Обновите Book.php
Внесите следующие изменения в класс Book - myapp / module / Tutorial / src / Model / Book.php.
Добавить новую недвижимость imagepath для картины.
public $imagepath;
Обновите getInputFilter метод, как показано ниже -
Добавить FileInput фильтр для элемента ввода файла.
Установить UploadFile проверка для проверки элемента ввода файла.
Настроить RenameUpload , чтобы переместить загруженный файл в правильное место назначения.
Частичный листинг кода выглядит следующим образом:
$file = new FileInput('imagepath'); $file->getValidatorChain()->attach(new UploadFile());
$file->getFilterChain()->attach( new RenameUpload([ 'target' => './public/tmpuploads/file', 'randomize' => true, 'use_upload_extension' => true ])); $inputFilter->add($file);
Обновите exchangeArray метод включения imagepathсвойство. Путь к изображению может поступать из формы или базы данных. Если путь к изображению поступает из формы, форматом будет массив со следующей спецификацией:
array(1) {
["imagepath"] => array(5) {
["name"] => string "myimage.png"
["type"] => string "image/png"
["tmp_name"] => string
"public/tmpuploads/file_<random_string>.<image_ext>"
["error"] => int <error_number>
["size"] => int <size>
}
}
Если путь к изображению поступает из базы данных, это будет простая строка. Частичный листинг кода для анализа пути к изображению выглядит следующим образом:
if(!empty($data['imagepath'])) {
if(is_array($data['imagepath'])) { $this->imagepath = str_replace("./public", "", $data['imagepath']['tmp_name']); } else { $this->imagepath = $data['imagepath']; } } else { $data['imagepath'] = null;
}
Полный список Book модель выглядит следующим образом -
<?php
namespace Tutorial\Model;
use Zend\InputFilter\InputFilterInterface;
use Zend\InputFilter\InputFilterAwareInterface;
use Zend\Filter\File\RenameUpload;
use Zend\Validator\File\UploadFile;
use Zend\InputFilter\FileInput;
use Zend\InputFilter\InputFilter;
class Book implements InputFilterAwareInterface {
public $id; public $author;
public $title; public $imagepath;
protected $inputFilter; public function setInputFilter(InputFilterInterface $inputFilter) {
throw new \Exception("Not used");
}
public function getInputFilter() {
if (!$this->inputFilter) { $inputFilter = new InputFilter();
$inputFilter->add(array( 'name' => 'id', 'required' => true, 'filters' => array( array('name' => 'Int'), ), )); $inputFilter->add(array(
'name' => 'author',
'required' => true,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'min' => 1,
'max' => 100,
),
),
),
));
$inputFilter->add(array( 'name' => 'title', 'required' => true, 'filters' => array( array('name' => 'StripTags'), array('name' => 'StringTrim'), ), 'validators' => array( array( 'name' => 'StringLength', 'options' => array( 'encoding' => 'UTF-8', 'min' => 1, 'max' => 100, ), ), ), )); $file = new FileInput('imagepath');
$file->getValidatorChain()->attach(new UploadFile()); $file->getFilterChain()->attach(
new RenameUpload([
'target' => './public/tmpuploads/file',
'randomize' => true,
'use_upload_extension' => true
]));
$inputFilter->add($file);
$this->inputFilter = $inputFilter;
}
return $this->inputFilter; } public function exchangeArray($data) {
$this->id = (!empty($data['id'])) ? $data['id'] : null; $this->author = (!empty($data['author'])) ? $data['author'] : null;
$this->title = (!empty($data['title'])) ? $data['title'] : null; if(!empty($data['imagepath'])) {
if(is_array($data['imagepath'])) { $this->imagepath = str_replace("./public", "",
$data['imagepath']['tmp_name']); } else { $this->imagepath = $data['imagepath']; } } else { $data['imagepath'] = null;
}
}
}
Обновите BookTable.php
Мы обновили BookForm и Book model. Теперь мы обновляемBookTable и изменить saveBookметод. Этого достаточно, чтобы включить запись пути к изображению в массив данных,$data.
Частичный листинг кода выглядит следующим образом:
$data = array('author' => $book->author, 'title' => $book->title,
'imagepath' => $book->imagepath
);
Полный листинг кода BookTable класс выглядит следующим образом -
<?php
namespace Tutorial\Model;
use Zend\Db\TableGateway\TableGatewayInterface;
class BookTable {
protected $tableGateway;
public function __construct(TableGatewayInterface $tableGateway) { $this->tableGateway = $tableGateway; } public function fetchAll() { $resultSet = $this->tableGateway->select(); return $resultSet;
}
public function getBook($id) { $id = (int) $id; $rowset = $this->tableGateway->select(array('id' => $id));
$row = $rowset->current();
if (!$row) { throw new \Exception("Could not find row $id");
}
return $row; } public function saveBook(Book $book) {
$data = array ( 'author' => $book->author,
'title' => $book->title, 'imagepath' => $book->imagepath
);
$id = (int) $book->id;
if ($id == 0) { $this->tableGateway->insert($data); } else { if ($this->getBook($id)) { $this->tableGateway->update($data, array('id' => $id));
} else {
throw new \Exception('Book id does not exist');
}
}
}
}
Update addAction in the TutorialController.php: Информация о загрузке файла будет доступна в $_FILES глобальный массив, и к нему можно получить доступ, используя Request's getFiles()метод. Итак, объедините опубликованные данные и информацию о загрузке файла, как показано ниже.
$post = array_merge_recursive(
$request->getPost()->toArray(), $request->getFiles()->toArray()
);
Полный список addAction() метод выглядит следующим образом -
public function addAction() {
$form = new BookForm(); $form->get('submit')->setValue('Add');
$request = $this->getRequest();
if ($request->isPost()) { $book = new Book();
$form->setInputFilter($book->getInputFilter());
$post = array_merge_recursive( $request->getPost()->toArray(),
$request->getFiles()->toArray() ); $form->setData($post); if ($form->isValid()) {
$book->exchangeArray($form->getData());
$this->bookTable->saveBook($book);
// Redirect to list of Tutorial
return $this->redirect()->toRoute('tutorial'); } } return array('form' => $form);
}
Обновить представление add.phtml
Наконец, измените «add.phtml» и включите элемент ввода файла пути к изображению, как показано ниже -
echo $this->formRow($form->get('imagepath'))."<br>";
Полный список выглядит следующим образом -
<?php
$title = 'Add new Book'; $this->headTitle($title); ?> <h1><?php echo $this->escapeHtml($title); ?></h1> <?php if(!empty($form)) {
$form->setAttribute('action', $this->url('tutorial', array('action' => 'add')));
$form->prepare(); echo $this->form()->openTag($form); echo $this->formHidden($form->get('id')); echo $this->formRow($form->get('author'))."<br>"; echo $this->formRow($form->get('title'))."<br>"; echo $this->formRow($form->get('imagepath'))."<br>"; echo $this->formSubmit($form->get('submit')); echo $this->form()->closeTag();
}
Запустить приложение
Наконец, запустите приложение на http://localhost:8080/tutorial/add и добавляем новые записи.
Результат будет таким, как показано на следующих снимках экрана -
Form Page
Index Page
AJAX - это современная технология веб-программирования. Он предоставляет возможности для асинхронной отправки и получения данных на веб-странице без обновления страницы. Zend framework предоставляет возможность работать сjson модель через zend-view и zend-jsonсоставная часть. Давайте изучим программирование Zend AJAX в этой главе.
Установить компонент json
Компонент Zend json можно установить с помощью Composer команда, как указано ниже -
composer require zendframework/zend-json
Концепция
Zend framework предоставляет два метода для простого написания веб-приложений с поддержкой AJAX. Они следующие -
В isXmlHttpRequest() метод в Requestобъект - Если выполняется запрос AJAX, метод isXmlHttpRequest () объекта запроса возвращает true, в противном случае - false. Этот метод используется для правильной обработки запроса AJAX на стороне сервера.
if ($request->isXmlHttpRequest()) {
// Ajax request
} else {
// Normal request
}
Zend / View / Model / JsonModel - The JsonModel альтернатива для ViewModelбудет использоваться исключительно для сценариев AJAX и REST API. JsonModel вместе сJsonStrategy (настраивается в блоке диспетчера представлений модуля) кодирует данные модели в Json и возвращает его как ответ вместо представлений (phtml).
AJAX - Рабочий пример
Давайте добавим новую страницу ajax, ajaxв учебном модуле и асинхронно получить информацию о книге. Для этого нам следует придерживаться следующих шагов.
Шаг 1. Добавьте JsonStrategy в конфигурацию модуля
Обновите блок диспетчера представлений в файле конфигурации учебного модуля - myapp / module / Tutorial / config / module.config.php. Потом,JsonStrategy будет работать с JsonModel для кодирования и отправки данных json.
'view_manager' => [
'template_map' => array
('layout/layout' => __DIR__ . '/../view/layout/newlayout.phtml'),
'template_path_stack' => [
'tutorial' => __DIR__ . '/../view',
],
'strategies' => array('ViewJsonStrategy',),
],
Шаг 2. Добавьте метод ajaxAction в TutorialController.php
Добавьте метод ajaxAction в TutorialController.php со следующим кодом -
public function ajaxAction() {
$data = $this->bookTable->fetchAll(); $request = $this->getRequest(); $query = $request->getQuery(); if ($request->isXmlHttpRequest() || $query->get('showJson') == 1) { $jsonData = array();
$idx = 0; foreach($data as $sampledata) { $temp = array(
'author' => $sampledata->author, 'title' => $sampledata->title,
'imagepath' => $sampledata->imagepath ); $jsonData[$idx++] = $temp;
}
$view = new JsonModel($jsonData);
$view->setTerminal(true); } else { $view = new ViewModel();
}
return $view;
}
Здесь ajaxAction проверит, является ли входящий запрос AJAX или нет. Если входящий запрос - AJAX, тоJsonModelбудет создан. В противном случае нормальныйViewModel будет создан.
В обоих случаях информация о книге будет извлечена из базы данных и введена в модель. Если модель является JsonModel, тогдаJsonStrategy будет вызван, он закодирует данные как json и вернет их в качестве ответа.
В $query->get('showJson') == 1используется для отладки. Просто добавьshowJson=1 в URL-адресе, и на странице будут отображаться данные json.
Шаг 3. Добавьте ajax.phtml
Теперь добавьте сценарий просмотра ajax.phtmlдля метода ajaxAction. На этой странице будет ссылка с меткой -Load book information.
При нажатии на эту ссылку выполняется запрос AJAX, который извлекает информацию о книге в виде данных Json и отображает информацию о книге в виде отформатированной таблицы. Обработка AJAX выполняется с использованиемJQuery.
Полный список кода выглядит следующим образом -
<a id = "loadbook" href = "#">Load book information</a>
</br> </br>
<table class = "table">
<tbody id = "book">
</tbody>
</table>
<script language = "javascript">
$(document).ready(function(){ $("#loadbook").on("click", function(event){
$.ajax({ url: '/tutorial/ajax', type: 'POST', dataType: 'json', async: true, success: function(data, status) { var e = $('<tr><th>Author</th><th>Title</th><th>Picture</th></tr>');
$('#book').html(''); $('#book').append(e);
for(i = 0; i < data.length; i++) {
book = data[i];
var e = $('<tr><td id = "author"></td><td id = "title"></td> <td id="imagepath"><img src = ""/></td></tr>'); $('#author', e).html(book['author']);
$('#title', e).html(book['title']); $('#imagepath img', e).attr('src', book['imagepath']);
$('#book').append(e);
}
},
error : function(xhr, textStatus, errorThrown) {
alert('Ajax request failed.');
}
});
});
});
</script>
Шаг 4: Запустите приложение
Наконец, запустите приложение - http://localhost:8080/tutorial/ajax и щелкните ссылку Загрузить информацию о книге.
Результат будет таким, как показано ниже -
Ajax Page -
Ajax Page with Book Information
Ajax page with debugging information
Cookie - очень важное понятие в веб-приложении. Он предоставляет возможность сохранять данные пользователя, обычно небольшую часть информации в самом браузере, в течение ограниченного периода времени.
Cookie-файл используется для поддержания состояния веб-приложения. Zend framework предоставляет модуль cookie внутриzend-httpсоставная часть. Этот zend-http предоставляет абстракцию HTTP и ее реализацию.
Установка компонента HTTP
Компонент HTTP можно легко установить с помощью Composer как указано в приведенном ниже коде.
composer require zendframework/zend-http
Концепция
Zend-http предоставляет Zend\Http\Cookiesкласс для управления файлами cookie. Он используется вместе сZend\Http\Clientкласс, который используется для отправки запроса на веб-сервер. Файлы cookie могут быть инициализированы, как показано в приведенном ниже коде -
use Zend\Http\Cookies
$c = new Cookies();
Когда HTTP-клиент (Zend \ Http \ Client) сначала отправляет запрос URI на веб-сервер, он не имеет файлов cookie. После того, как запрос получен веб-сервером, он включает файл cookie в свой объект ответа в качествеHTTP Header, Set-Cookieи отправляет его HTTP-клиенту. HTTP-клиент извлечет cookie из HTTP-ответа и повторно отправит его как тот же HTTP-заголовок в следующем запросе. Как правило, каждый файл cookie будет сопоставлен с доменом и путем к домену.
Методы, доступные в Cookies класс следующие -
addCookie(uri) - Он используется для добавления cookie в объект запроса данного URI.
getCookie(cookieName, $cookieForm) - Он используется для получения файла cookie $ cookieName, доступного в указанном URI, $uri. Третий аргумент - это то, как будет возвращен файл cookie: строка или массив.
fromResponse(uri) - Он используется для извлечения файлов cookie из объекта ответа данного URI.
addCookiesFromResponse - То же, что и fromResponse, но извлекает и снова добавляет его в объект запроса данного URI.
isEmpty() - Используется, чтобы узнать, Cookie есть у объекта cookie или нет.
reset() - Он используется для очистки всех файлов cookie в данном URI.
В следующей главе мы обсудим управление сеансами в Zend Framework.
Сессия - очень важное понятие в веб-приложении. Он предоставляет возможность сохранять данные пользователя на веб-сервере в течение ограниченного периода времени. Zend framework предоставляет отдельный компонент,zend-session для обработки информации о сеансе.
Установить компонент сеанса
Компонент сеанса можно установить с помощью Composer как указано ниже -
composer require zendframework/zend-session
Компоненты сеанса
Zend framework предоставляет шесть компонентов для управления сеансами. Все эти компоненты были объяснены ниже -
Zend\Session\Container - Основной API для чтения и записи информации о сеансе.
Zend\Session\SessionManager - Он используется для управления всем жизненным циклом сеанса.
Zend\Session\Storage - Используется для указания того, как данные сеанса будут храниться в памяти.
Zend\Session\SaveHandler - Он используется для хранения и извлечения данных сеанса в физическое место, такое как СУБД, Redis, MangoDB и т. Д.
Zend\Session\Validator - Это используется для защиты сеанса от взлома путем перекрестной проверки удаленного адреса исходного и последующего запроса и пользовательского агента.
Zend\Session\Config\SessionConfig - Он используется для настройки поведения сеанса.
Конфигурации по умолчанию достаточно для работы с сессией. Используя вышеуказанные компоненты, можно легко управлять всеми аспектами сеанса.
Пример компонента сеанса
Давайте придерживаться следующих пунктов, чтобы создать новую страницу для понимания сеанса в Zend framework. По умолчанию достаточно создать экземплярContainer класс для управления сеансами.
Создайте новое действие, sessionAction в TutorialController.
Инициализировать Container объект.
$c = new Container();
Проверить, есть ли произвольный ключ countсуществует. Если ключ недоступен, инициализируйтеcount со значением 1. Если доступно, увеличьте значение, как показано в следующем коде.
if (!isset($c->count)) { $c->count = 0;
} else {
$c->count++;
}
Зарегистрируйте счетчик в ViewModel.
Создайте файл шаблона для - sessionAction, session.phtml в myapp / module / Tutorial / view / tutorial / tutorial / session.phtml, а затем визуализируйте count значение.
Обновление страницы увеличит значение countв сеансе. Полный список выглядит следующим образом -
TutorialController.php
public function sessionAction() {
$c = new Container();
if (!isset($c->count)) { $c->count = 0;
} else {
$c->count++; } $view = new ViewModel([
'count' => $c->count, ]); return $view;
}
session.pthml
Session data, COUNT = <?= $this->count ?>
Sample Result
Session data, Count = 5
Аутентификация - одна из наиболее важных и обязательных функций любого веб-приложения. Zend Framework предоставляет отдельный компонент для обработки аутентификации, который называетсяzend-authentication.
Установите компонент аутентификации
Компонент аутентификации можно установить, используя следующие Composer команда.
composer require zendframework/zend-authentication
Концепция
Обычно разработчик пишет функцию php для аутентификации данных пользователя по источнику данных. После завершения аутентификации детали аутентификации сохраняются для последующих запросов. Zend Framework обобщает эту концепцию и предоставляет два класса, которые описаны ниже:
Класс 1 Zend \ Authentication \ Adapter \ AdaptorInterface
Этот класс предоставляет единственный метод, authenticateнаписать логику аутентификации. Метод аутентификации возвращает экземплярZend\Authentication\Result класс.
Этот Resultобъект содержит статус аутентификации; identity, если аутентификация прошла успешно, и сообщение об ошибке, если аутентификация не удалась. Подпись интерфейса аутентификации и класса результата следующая:
AdaptorInterface
namespace Zend\Authentication\Adaptor;
public function authenticate() {
// code
}
Result class
namespace Zend\Authentication;
class Result {
public function __construct($code, $identity, array $messages = []);
}
Zend Framework предоставляет реализацию по умолчанию для аутентификации по базе данных, ldap, базовым и дайджест-учетным данным http. AnAdaptor аутентифицирует, но не сохраняет детали для любых будущих запросов.
Zend \ Authentication \ AuthenticationService класса 2
AuthenticationService - это основной компонент, который использует уже настроенный адаптер для аутентификации. После завершения аутентификации данные аутентификации сохраняются и предоставляются методы,hasIdentity() чтобы проверить, доступна ли личность, getIdentity() чтобы получить данные аутентификации и clearIdentity() чтобы очистить детали аутентификации.
Частичный листинг кода для использования этой AuthenticationService выглядит следующим образом:
$adap = new Adapter($username, $password); $auth = new AuthenticationService();
$result = $auth->authenticate($adap); if($result->isValid) {
$identity = $auth->getIdentity();
} else {
// process $result->getMessages() } // clear $auth->clearIdentity();
Материал, связанный с авторизацией, упакован в два отдельных модуля, которые: zend-permissions-acl и zend-permissions-rbac. Zend-permissions-acl основан на списке управления доступом, а zend-permissions-rbac основан на списке управления доступом на основе ролей. Они обеспечивают абстракцию высокого уровня концепции ACL и RBAC и помогают в написании приложения корпоративного уровня.
Zend Framework предоставляет отдельный компонент, называемый zend-mailдля отправки сообщений электронной почты. Компонент zend-mail также предоставляет возможность читать и писать сообщения электронной почты с вложениями в текстовом и html формате. Отправку электронной почты в Zend намного проще и проще настроить.
Давайте рассмотрим в этой главе концепции электронной почты, основные настройки, расширенные настройки, такие как транспорт SMTP и т. Д.
Установить почтовый компонент
Почтовый компонент можно установить с помощью следующей команды Composer.
composer require zendframework/zend-mail
Базовая конфигурация электронной почты
Обычное электронное письмо состоит из одного или нескольких получателей, темы, тела и отправителя. Zend предоставляетZend\Mail\Messageкласс, чтобы создать новое сообщение электронной почты. Чтобы отправить электронное письмо с помощьюzend-mail, вы должны указать как минимум одного получателя, а также тело сообщения.
Частичный код для создания нового почтового сообщения выглядит следующим образом:
use Zend\Mail;
$mail = new Mail\Message(); $mail->setSubject('Zend email sample');
$mail->setBody('This is content of the mail message'); $mail->setFrom('[email protected]', "sender-name");
$mail->addTo('[email protected]', "recipient-name");
Zend предоставляет класс Zend \ Mail \ Sendmail для отправки почтового сообщения. Sendmail использует встроенную почтовую функцию php, mail для отправки почтового сообщения, и мы можем настроить транспортный уровень с помощью файла конфигурации php.
Частичное кодирование с использованием Sendmail выглядит следующим образом:
$transport = new Mail\Transport\Sendmail();
$transport->send($mail);
В zend-mail предоставляет множество транспортных уровней, и для каждого может потребоваться множество дополнительных параметров, таких как имя пользователя, пароль и т. д.
Методы управления электронной почтой
Некоторые из примечательных методов управления электронной почтой следующие:
isValid - Сообщения без адреса «От» недействительны.
isValid() : bool
setEncoding - Установить кодировку сообщения.
setEncoding(string $encoding) : void
getEncoding - Получить кодировку сообщения.
getEncoding() : string
setHeaders - Составлять заголовки.
setHeaders(Zend\Mail\Headers $headers) : void
getHeaders - Доступ к коллекции заголовков.
getHeaders() : Zend\Mail\Headers
setFrom- Установить (перезаписать) От адресов. Он содержит пары ключ / значение, где ключ - это удобочитаемое имя, а значение - адрес электронной почты.
setFrom(
string|AddressInterface|array|AddressList|Traversable $emailOrAddressList, string|null $name
) : void
addFrom - Добавьте адрес "От".
addFrom(
string|AddressInterface|array|AddressList|Traversable $emailOrAddressOrList, string|null $name
) : void
getFrom - Получить список отправителей "От".
getFrom() : AddressList
setTo - Overwrite the address list in the To recipients.
setTo(
string|AddressInterface|array|AddressList|Traversable $emailOrAddressList, null|string $name
) : void
setSubject - Установите значение заголовка темы сообщения.
setSubject(string $subject) :void
setBody - Установить тело сообщения.
setBody(null|string|Zend\Mime\Message|object $body) : void
Транспортный уровень SMTP
В zend-mail предоставляет параметры для отправки электронной почты с помощью SMTP-сервера через Zend\Mail\Transport\Smtpclass. Это какSendmail за исключением того, что у него есть несколько дополнительных параметров для настройки хоста SMTP, порта, имени пользователя, пароля и т. д.
Частичный код выглядит следующим образом -
use Zend\Mail\Transport\Smtp as SmtpTransport;
use Zend\Mail\Transport\SmtpOptions;
$transport = new SmtpTransport(); $options = new SmtpOptions([
'name' => 'localhost',
'host' =>'smtp.gmail.com',
'port' => 465,
]);
$transport->setOptions($options);
Вот,
name - Имя SMTP-хоста.
host - Имя удаленного хоста или IP-адрес.
port - Порт, который прослушивает удаленный хост.
Концепция почты - пример
Давайте рассмотрим следующие моменты, чтобы написать простое консольное приложение php для понимания концепции почты.
Создайте папку «mailapp».
Установить zend-mail с помощью инструмента композитора.
Создайте файл php Mail.php внутри папки «mailapp».
Создайте сообщение, используя Zend\Mail\Message.
$message = new Message(); $message->addTo('[email protected]');
$message->addFrom('[email protected]'); $message->setSubject('Hello!');
$message->setBody("My first Zend-mail application!");
Создайте транспортный уровень SMTP и добавьте необходимую конфигурацию.
// Setup SMTP transport using LOGIN authentication
$transport = new SmtpTransport();
$options = new SmtpOptions([ 'name' => 'localhost', 'host' => 'smtp.gmail.com', // or any SMTP server 'port' => 465, // port on which the SMTP server is listening 'connection_class' => 'login', 'connection_config' => [ username' => '<your username>', 'password' => '<your password>', 'ssl' => 'ssl'], ]); $transport->setOptions($options);
Отправьте электронное письмо с помощью send метод.
$transport->send($message);
Полный список Mail.php выглядит следующим образом:
<?php
require __DIR__ . '/vendor/autoload.php';
use Zend\Mail\Message;
use Zend\Mail\Transport\Smtp as SmtpTransport;
use Zend\Mail\Transport\SmtpOptions;
$message = new Message();
$message->addTo('[email protected]'); $message->addFrom('[email protected]');
$message->setSubject('Hello!'); $message->setBody("My first Zend-mail application!");
// Setup SMTP transport using LOGIN authentication
$transport = new SmtpTransport(); $options = new SmtpOptions([
'name' => 'localhost',
'host' => 'smtp.gmail.com', // or any SMTP server
'port' => 465, // port on which the SMTP server is listening
'connection_class' => 'login',
'connection_config' => [
'username' => '<your username>', 'password' => '<your password>',
'ssl' => 'ssl'],
]);
$transport->setOptions($options);
$transport->send($message);
Теперь запустите приложение в командной строке php Mail.php. Это отправит почту, как настроено в приложении.
В общем, мы можем отлаживать приложение PHP, используя advanced debugger tool или с помощью простых команд, например echo и die. В веб-сценарии нам нужно протестировать бизнес-логику, а также уровень представления. Формы в веб-приложении можно протестировать, введя соответствующие тестовые данные, чтобы убедиться, что формы работают должным образом.
Дизайн веб-сайта можно проверить вручную с помощью браузера. Процессы тестирования такого типа можно автоматизировать с помощью модульного тестирования. Модульный тест необходим в больших проектах. Эти модульные тесты помогут автоматизировать процесс тестирования и предупредить разработчика, когда что-то пойдет не так.
Настройка PHPUnit
Платформа Zend интегрируется со средой модульного тестирования PHPUnit. Чтобы написать модульный тест для Zend framework, нам нужно настроить PHPUnit, что можно легко сделать с помощью следующей команды Composer.
$ composer require --dev phpunit/phpunit
После выполнения указанной выше команды вы получите ответ, как показано в следующем блоке кода.
Using version ^5.7 for phpunit/phpunit
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Nothing to install or update
Writing lock file
Generating autoload files
Теперь, когда вы откроете файл «composer.json», вы увидите следующие изменения:
"require-dev": {
"phpunit/phpunit": "^5.7"
}
TestCase и утверждения
Платформа Zend предоставляет вспомогательные классы для модульного тестирования контроллера. ВTestCase является основным компонентом в PHPUnit framework для написания тестовых примеров, а Zend Framework предоставляет абстрактную реализацию TestCase, которая называется AbstractHttpControllerTestCase.
Этот AbstractHttpControllerTestCase предоставляет различные Assertметоды и могут быть сгруппированы по функциональности. Они следующие -
Request Assertions- Используется для подтверждения HTTP-запроса. Например, assertControllerName.
CSS Select Assertions - Используется для проверки HTML-ответа с использованием модели HTML DOM.
XPath Assertions - Альтернатива утверждениям выбора CSS на основе XPath.
Redirect Assertions - Используется для проверки перенаправления страницы.
Response Header Assertions - Используется для проверки заголовка ответа, такого как код состояния (assertResponseStatusCode)
Создать каталог тестов
Модульный тест можно написать отдельно для каждого модуля. Весь код, связанный с тестированием, должен быть создан внутриtest папка в корневом каталоге модуля.
Например, чтобы написать тест для TutorialController, доступного в модуле Tutorial, тестовый класс необходимо поместить в каталог myapp / module / Tutorial / test / Controller /.
пример
Давайте напишем тестовый класс для модульного тестирования TutorialController.
Для начала мы должны написать класс под названием TutorialControllerTest и расширить его до AbstractHttpControllerTestCase.
Следующим шагом будет написание Setupметод настройки тестовой среды. Это можно сделать, позвонив вsetApplicationConfig метод и передачу нашего основного файла конфигурации приложения myapp / config / application.config.php
public function setUp() {
$configOverrides = [];
$this->setApplicationConfig(ArrayUtils::merge( include __DIR__ . '/../../../../config/application.config.php', $configOverrides
));
parent::setUp();
}
Напишите один или несколько методов и вызовите различные методы assert в зависимости от требований.
$this->assertMatchedRouteName('tutorial');
Мы написали тестовый класс, и полный список выглядит следующим образом:
<?php
namespace TutorialTest\Controller;
use Tutorial\Controller\TutorialController;
use Zend\Stdlib\ArrayUtils;
use Zend\Test\PHPUnit\Controller\AbstractHttpControllerTestCase;
class TutorialControllerTest extends AbstractHttpControllerTestCase {
public function setUp() {
$configOverrides = [];
$this->setApplicationConfig(ArrayUtils::merge( include __DIR__ . '/../../../../config/application.config.php', $configOverrides
));
parent::setUp();
}
public function testIndexActionCanBeAccessed() {
$this->dispatch('/tutorial', 'GET'); $this->assertResponseStatusCode(200);
$this->assertModuleName('tutorial'); $this->assertControllerName(TutorialController::class);
$this->assertControllerClass('TutorialController'); $this->assertMatchedRouteName('tutorial');
}
}
Теперь откройте командную строку, перейдите в корневой каталог приложения и выполните команду phpunit исполняемый файл доступен внутри vendor папка.
cd /path/to/app
./vendor/bin/phpunit ./vendor/bin/phpunit module/
Tutorial/test/Controller/TutorialControllerTest.php
Результат будет таким, как показано в следующем блоке кода -
PHPUnit 5.7.5 by Sebastian Bergmann and contributors.
.1 / 1 (100%)
Time: 96 ms, Memory: 8.00MB
OK (1 test, 5 assertions)
Отказ системы необходимо эффективно обрабатывать для бесперебойной работы системы. Zend Framework поставляется сdefault error trappingкоторый печатает и регистрирует ошибки по мере их возникновения. Этот же обработчик ошибок используется для перехватаExceptions.
Обработчик ошибок отображает ошибки, когда отладка верна, и регистрирует ошибку, когда отладка ложна. Zend Framework имеет несколько классов исключений, а встроенная обработка исключений фиксирует любое неперехваченное исключение и отображает полезную страницу.
Обработка ошибок по умолчанию
Мы можем настроить параметры ошибок по умолчанию в файле конфигурации приложения, myapp / module / Application / config / module.config.php.
Пример частичного кода выглядит следующим образом:
'view_manager' => [
'display_not_found_reason' => true,
'display_exceptions' => true,
'doctype' => 'HTML5',
'not_found_template' => 'error/404',
'exception_template' => 'error/index',
'template_map' => [
'layout/layout' => __DIR__ . '/../view/layout/layout.phtml',
'application/index/index' => __DIR__ . '/../view/application/index/index.phtml',
'error/404' => __DIR__ . '/../view/error/404.phtml',
'error/index' => __DIR__ . '/../view/error/index.phtml',
],
'template_path_stack' => [
__DIR__ . '/../view',
],
],
Здесь display_exception, not_found_template, exception_template, error / 404 и error / index являются элементами конфигурации, связанными с ошибкой, и не требуют пояснений.
Самым важным элементом среди них является error/index. Этот шаблон отображается при возникновении исключения в системе. Мы можем изменить этот шаблон myapp / module / Application / view / error / index.phtml, чтобы контролировать количество отображаемых ошибок.
В этой главе мы узнаем, как создать полное приложение для сотрудников на основе MVC в Zend Framework. Следуйте инструкциям ниже.
Шаг 1: Module.php
Сначала мы должны создать модуль Employee внутри каталога - myapp / module / Employee / src /, а затем реализовать интерфейс ConfigProviderInterface.
Полный код для класса Module выглядит следующим образом:
<?php
namespace Employee;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
class Module implements ConfigProviderInterface {
public function getConfig() {
return include __DIR__ . '/../config/module.config.php';
}
}
Шаг 2: composer.json
Настроить Tutorial модуль в composer.json в разделе автозагрузки, используя следующий код.
"autoload": {
"psr-4": {
"Application\\": "module/Application/src/",
"Tutorial\\": "module/Tutorial/src/",
"Employee\\": "module/Employee/src/"
}
}
Теперь обновите приложение, используя команду composer update.
composer update
Команда Composer внесет необходимые изменения в приложение и покажет журналы, как показано в командной строке ниже.
Loading composer repositories with package information
Updating dependencies (including require-dev)
- Removing zendframework/zend-component-installer (0.3.0)
- Installing zendframework/zend-component-installer (0.3.1)
Downloading: 100%
- Removing zendframework/zend-stdlib (3.0.1)
- Installing zendframework/zend-stdlib (3.1.0)
Loading from cache
- Removing zendframework/zend-eventmanager (3.0.1)
- Installing zendframework/zend-eventmanager (3.1.0)
Downloading: 100%
- Removing zendframework/zend-view (2.8.0)
- Installing zendframework/zend-view (2.8.1)
Loading from cache
- Removing zendframework/zend-servicemanager (3.1.0)
- Installing zendframework/zend-servicemanager (3.2.0)
Downloading: 100%
- Removing zendframework/zend-escaper (2.5.1)
- Installing zendframework/zend-escaper (2.5.2)
Loading from cache
- Removing zendframework/zend-http (2.5.4)
- Installing zendframework/zend-http (2.5.5)
Loading from cache
- Removing zendframework/zend-mvc (3.0.1)
- Installing zendframework/zend-mvc (3.0.4)
Downloading: 100%
- Removing phpunit/phpunit (5.7.4)
- Installing phpunit/phpunit (5.7.5)
Downloading: 100%
Writing lock file
Generating autoload files
Шаг 3: module.config.php для модуля сотрудников
Создайте файл конфигурации модуля «module.config.php» в myapp / module / Employee / config с помощью следующего кода.
<?php
namespace Employee;
use Zend\ServiceManager\Factory\InvokableFactory;
use Zend\Router\Http\Segment;
return [
'controllers' => [
'factories' => [
Controller\EmployeeController::class => InvokableFactory::class,
],
],
'view_manager' => [
'template_path_stack' => ['employee' => __DIR__ . '/../view',],
],
];
Теперь настройте модуль Employee в файле конфигурации уровня приложения - myapp / config / modules.config.php.
return ['Zend\Router', 'Zend\Validator', 'Application', 'Tutorial', 'Employee'];
Шаг 4: EmployeeController
Создайте новый класс PHP, EmployeeController, расширив AbstractActionController и поместив его в каталог myapp / module / Employee / src / Controller.
Полный список кода выглядит следующим образом -
<?php
namespace Employee\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class EmployeeController extends AbstractActionController {
public function indexAction() {
return new ViewModel();
}
}
Шаг 5: Конфигурация маршрутизатора
Давайте добавим сегментный маршрут в наш модуль «Сотрудник». Обновите файл конфигурации модуля сотрудника, module.config.php, доступный в myapp / module / Employee / config.
<?php
namespace Employee;
use Zend\ServiceManager\Factory\InvokableFactory;
use Zend\Router\Http\Segment;
return [
'controllers' => [
'factories' => [
Controller\EmployeeController::class => InvokableFactory::class,
],
],
'router' => [
'routes' => [
'employee' => [
'type' => Segment::class,
'options' => [
'route' => '/employee[/:action[/:id]]',
'constraints' => [
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
],
'defaults' => [
'controller' => Controller\EmployeeController::class,
'action' => 'index',
],
],
],
],
],
'view_manager' => [
'template_path_stack' => [
'employee' => __DIR__ . '/../view',
],
],
];
Мы успешно добавили маршрутизацию для нашего модуля «Сотрудник». Следующим шагом является создание сценария просмотра для приложения Employee.
Шаг 6. Создайте ViewModel
Создайте файл с именем «index.phtml» в каталоге myapp / module / Employee / view / employee / employee.
Добавьте следующие изменения в файл -
<div class = "row content">
<h3>This is my first Zend application</h3>
</div>
Move to “EmployeeController.php” file and edit the following changes,
<?php
namespace Employee\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class EmployeeController extends AbstractActionController {
public function indexAction() {
return new ViewModel();
}
}
Наконец, мы успешно завершили модуль «Сотрудник». мы можем получить к нему доступ, используя следующий URL-адрес -http://localhost:8080/employee.
Результат
На следующем шаге мы выполним add, edit и deleteоперации с данными в приложении сотрудника. Чтобы выполнить эти операции, мы должны сначала создать модель базы данных. Это описано в следующем шаге.
Шаг 7: Создайте модель
Давайте создадим модель Employee в нашем модуле src directory. Как правило, модели группируются в папке Model (myapp / module / Employee / src / Model / Employee.php).
<?php
namespace Employee\Model;
class Employee {
public $id; public $emp_name;
public $emp_job;
}
Шаг 8: таблица MySQL
Создайте базу данных с именем tutorials на локальном сервере MYSQL, используя следующую команду -
create database tutorials;
Давайте создадим таблицу с именем employee в базе данных с помощью следующей команды SQL -
use tutorials;
CREATE TABLE employee (
id int(11) NOT NULL auto_increment,
emp_name varchar(100) NOT NULL,
emp_job varchar(100) NOT NULL,
PRIMARY KEY (id)
);
Вставьте данные в employee таблицу, используя следующий запрос -
INSERT INTO employee (emp_name, emp_job) VALUES ('Adam', 'Tutor');
INSERT INTO employee (emp_name, emp_job) VALUES ('Bruce', 'Programmer');
INSERT INTO employee (emp_name, emp_job) VALUES ('David', 'Designer');
Шаг 9: Обновите конфигурацию базы данных
Обновите файл глобальной конфигурации myapp / config / autoload / global.php, указав необходимую информацию о диске базы данных.
return [
'db' => [
'driver' => 'Pdo',
'dsn' => 'mysql:dbname = tutorials;host=localhost',
'driver_options' => [PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''],
],
];
Теперь обновите учетные данные базы данных в локальном файле конфигурации - myapp / config / autoload / local.php. Таким образом, мы можем разделить учетные данные для подключения к локальной и действующей базе данных.
<?php
return array(
'db' => array('username' => '<user_name>', 'password' => '<password>',),
);
Шаг 10. Реализуйте exchangeArray
Реализуйте функцию exchangeArray в модели Employee.
<?php
namespace Employee\Model;
class Employee {
public $id;
public $emp_name; public $emp_job;
public function exchangeArray($data) { $this->id = (!empty($data['id'])) ? $data['id'] : null;
$this->emp_name = (!empty($data['emp_name'])) ? $data['emp_name'] : null; $this->emp_job = (!empty($data['emp_job'])) ? $data['emp_job'] : null;
}
}
Шаг 11. Используйте TableGateway для получения данных о сотрудниках
Создайте класс EmployeeTable в самой папке Model. Это определено в следующем блоке кода.
<?php
namespace Employee\Model;
use Zend\Db\TableGateway\TableGatewayInterface;
class EmployeeTable {
protected $tableGateway; public function __construct(TableGatewayInterface $tableGateway) {
$this->tableGateway = $tableGateway;
}
public function fetchAll() {
$resultSet = $this->tableGateway->select();
return $resultSet;
}
}
Шаг 12: настройте класс EmployeeTable
Обновление службы сотрудника в module.php с помощью getServiceConfig () метод
<?php
namespace Employee;
use Zend\Db\Adapter\AdapterInterface;
use Zend\Db\ResultSet\ResultSet;
use Zend\Db\TableGateway\TableGateway;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
class Module implements ConfigProviderInterface {
public function getConfig() {
return include __DIR__ . '/../config/module.config.php';
}
public function getServiceConfig() {
return [
'factories' => [
Model\EmployeeTable::class => function ( $container) {
$tableGateway = $container>get( Model\EmployeeTableGateway::class);
$table = new Model\EmployeeTable($tableGateway);
return $table; }, Model\EmployeeTableGateway::class => function ($container) {
$dbAdapter = $container->get(AdapterInterface::class);
$resultSetPrototype = new ResultSet(); $resultSetPrototype->setArrayObjectPrototype(new Model\Employee());
return new TableGateway('employee', $dbAdapter, null, $resultSetPrototype);
},
],
];
}
}
Шаг 13: добавьте службу сотрудников в контроллер
Обновите раздел контроллера конфигурации модуля сотрудников в - myapp / module / config / module.config.php, как показано ниже.
'controllers' => [
'factories' => [
Controller\EmployeeController::class => function($container) { return new Controller\EmployeeController( $container->get(Model\EmployeeTable::class)
);
},
],
]
Шаг 14: добавьте конструктор для EmployeeController
Добавьте конструктор с помощью EmployeeTable в качестве аргумента и отредактируйте следующие изменения.
<?php
namespace Employee\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Employee\Model\Employee;
use Employee\Model\EmployeeTable;
class EmployeeController extends AbstractActionController {
private $table; public function __construct(EmployeeTable $table) {
$this->table = $table;
}
public function indexAction() {
$view = new ViewModel([ 'data' => $this->table->fetchAll(),
]);
return $view;
}
}
Шаг 15. Отобразите информацию о сотрудниках в скрипте представления «index.phtml»
Перейти к файлу - index.phtml и внесите следующие изменения -
<?php
$title = 'Employee application';
$this->headTitle($title);
?>
<table class="table">
<tr>
<th>Employee Name</th>
<th>Employee Job</th>
<th>Edit/Delete operations</th>
</tr>
<?php foreach ($data as $empdata) : ?>
<tr>
<td><?php echo $this->escapeHtml($empdata->emp_name);?></td>
<td><?php echo $this->escapeHtml($empdata->emp_job);?></td>
<td>
<a href="<?php echo $this->url('employee', array('action'=>'edit', 'id' =>$empdata->id));?>">Edit</a>
<a href="<?php echo $this->url('employee', array('action'=>'delete', 'id' => $empdata->id));?>">Delete</a>
</td>
</tr>
<?php endforeach; ?>
</table>
Теперь мы успешно создали модель базы данных и можем получать записи в приложении.
Запросите приложение, используя URL-адрес - http://localhost:8080/employee.
Результат
Следующий шаг объясняет insert, edit и delete операции с данными в модуле сотрудников.
Шаг 16. Создайте форму сотрудника
Создайте файл с именем EmployeeForm.phpв каталоге myapp / module / Employee / src / Form. Это описано в блоке кода ниже.
<?php
namespace Employee\Form;
use Zend\Form\Form;
class EmployeeForm extends Form {
public function __construct($name = null) { / / we want to ignore the name passed parent::__construct('employee'); $this->add(array(
'name' => 'id',
'type' => 'Hidden',
));
$this->add(array( 'name' => 'emp_name', 'type' => 'Text', 'options' => array( 'label' => 'Name', ), )); $this->add(array(
'name' => 'emp_job',
'type' => 'Text',
'options' => array(
'label' => 'Job',
),
));
$this->add(array(
'name' => 'submit',
'type' => 'Submit',
'attributes' => array(
'value' => 'Go',
'id' => 'submitbutton',
),
));
}
}
Шаг 17: обновите модель сотрудника
Обновите модель сотрудника и реализуйте InputFilterAwareInterface. Перейдите в каталог myapp / module / Employee / src / Employee / Model и добавьте следующие изменения вEmployee.phpfile.
<?php
namespace Employee\Model;
// Add these import statements
use Zend\InputFilter\InputFilter;
use Zend\InputFilter\InputFilterAwareInterface;
use Zend\InputFilter\InputFilterInterface;
class Employee implements InputFilterAwareInterface {
public $id;
public $emp_name; public $emp_job;
protected $inputFilter; public function exchangeArray($data) {
$this->id = (isset($data['id'])) ? $data['id'] : null; $this->emp_name = (isset($data['emp_name'])) ? $data['emp_name'] : null;
$this->emp_job = (isset($data['emp_job'])) ? $data['emp_job'] : null; } // Add content to these methods: public function setInputFilter(InputFilterInterface $inputFilter) {
throw new \Exception("Not used");
}
public function getInputFilter() {
if (!$this->inputFilter) { $inputFilter = new InputFilter();
$inputFilter->add(array( 'name' => 'id', 'required' => true, 'filters' => array( array('name' => 'Int'), ), )); $inputFilter->add(array(
'name' => 'emp_name',
'required' => true,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
array('name' => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'min' => 1,
'max' => 50,
),
),
),
));
$inputFilter->add(array( 'name' => 'emp_job', 'required' => true, 'filters' => array( array('name' => 'StripTags'), array('name' => 'StringTrim'), ), 'validators' => array( array('name' => 'StringLength', 'options' => array( 'encoding' => 'UTF-8', 'min' => 1, 'max' => 50, ), ), ), )); $this->inputFilter = $inputFilter; } return $this->inputFilter;
}
}
Шаг 18: добавьте addAction в контроллер сотрудников
Добавьте следующие изменения в EmployeeController класс.
<?php
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Employee\Model\Employee;
use Employee\Model\EmployeeTable;
use Employee\Form\EmployeeForm;
public function addAction() {
$form = new EmployeeForm(); $form->get('submit')->setValue('Add');
$request = $this->getRequest();
if ($request->isPost()) { $employee = new Employee();
$form->setInputFilter($employee->getInputFilter());
$form->setData($request->getPost());
if ($form->isValid()) { $employee->exchangeArray($form->getData()); $this->table->saveEmployee($employee); // Redirect to list of employees return $this->redirect()->toRoute('employee');
}
}
return array('form' => $form);
}
Шаг 19. Добавьте функцию сохранения в класс EmployeeTable
Добавьте следующие две функции в класс EmployeeTable - myapp / module / Employee / src / Model / EmployeeTable.php
public function getEmployee($id) {
$id = (int) $id;
$rowset = $this->tableGateway->select(array('id' => $id)); $row = $rowset->current(); if (!$row) {
throw new \Exception("Could not find row $id"); } return $row;
}
public function saveEmployee(Employee $employee) { $data = array (
'emp_name' => $employee->emp_name, 'emp_job' => $employee->emp_job,
);
$id = (int) $employee->id;
if ($id == 0) { $this->tableGateway->insert($data); } else { if ($this->getEmployee($id)) { $this->tableGateway->update($data, array('id' => $id));
} else {
throw new \Exception('Employee id does not exist');
}
}
}
Шаг 20: Создайте сценарий просмотра для метода AddAction, Add.phtml
Добавьте следующие изменения в файл «Add.phtml» в - myapp / module / view / employee / employee.
<?php
$title = 'Add new employee'; $this->headTitle($title); ?> <h1><?php echo $this->escapeHtml($title); ?></h1> <?php $form->setAttribute('action', $this->url('employee', array('action' => 'add'))); $form->prepare();
echo $this->form()->openTag($form);
echo $this->formHidden($form->get('id'));
echo $this->formRow($form->get('emp_name'))."<br>";
echo $this->formRow($form->get('emp_job'))."<br>";
echo $this->formSubmit($form->get('submit'));
echo $this->form()->closeTag();
Request the application using the url, http://localhost:8080/employee/add
Результат
Как только данные будут добавлены, они будут перенаправлены на домашнюю страницу.
Шаг 21: отредактируйте записи о сотрудниках
Выполним операции редактирования данных в модуле Сотрудник. Обновите следующие изменения вEmployeecontroller.php.
public function editAction() {
$id = (int) $this->params()->fromRoute('id', 0); if (!$id) {
return $this->redirect()->toRoute('employee', array( 'action' => 'add' )); } try { $employee = $this->table->getEmployee($id);
} catch (\Exception $ex) { return $this->redirect()->toRoute('employee', array(
'action' => 'index'
));
}
$form = new EmployeeForm(); $form->bind($employee); $form->get('submit')->setAttribute('value', 'Edit');
$request = $this->getRequest();
if ($request->isPost()) { $form->setInputFilter($employee->getInputFilter()); $form->setData($request->getPost()); if ($form->isValid()) {
$this->table->saveEmployee($employee);
// Redirect to list of employees
return $this->redirect()->toRoute('employee'); } } return array('id' => $id, 'form' => $form,);
}
Здесь мы ищем id, который находится в согласованном маршруте, а затем загрузите сведения о сотруднике для операции редактирования.
Шаг 22: Employee.php
Теперь добавьте следующие изменения в файл «Employee.php», который находится в каталоге - myapp / module / Employee / src / Employee / Model /.
public function getArrayCopy() {
return get_object_vars($this);
}
Здесь Zend \ Stdlib \ Hydrator \ ArraySerializable ожидает найти в модели два метода: getArrayCopy() и exchangeArray().
В котором exchangeArray () используется для итерации. Эта функция используется для привязки данных из таблицы сотрудников.
Теперь нам нужно создать сценарий просмотра для editAction().
Шаг 23: Создайте Edit.phtml
Создайте файл сценария просмотра в модуле / Employee / view / employee / employee / edit.phtml.
<?php
$title = 'Edit employee records'; $this->headTitle($title); ?> <h1><?php echo $this->escapeHtml($title); ?></h1> <?php $form = $this->form; $form->setAttribute('action', $this->url( 'employee', array('action' => 'edit', 'id' => $this->id,)
));
$form->prepare(); echo $this->form()->openTag($form); echo $this->formHidden($form->get('id')); echo $this->formRow($form->get('emp_name'))."<br>"; echo $this->formRow($form->get('emp_job'))."<br>"; echo $this->formSubmit($form->get('submit')); echo $this->form()->closeTag();
Редактирование сведений о сотруднике показано на следующем снимке экрана.
Как только данные будут отредактированы, они будут перенаправлены на домашнюю страницу.
Шаг 24: добавьте метод deleteEmployee
Добавьте метод deleteEmployee в класс EmployeeTable - myapp / module / Employee / src / Model / EmployeeTable.php
public function deleteEmployee($id) { $this->tableGateway->delete(['id' => (int) $id]);
}
Шаг 25: удалите записи о сотрудниках
Давайте теперь выполним операции удаления данных в модуле Employee. Добавьте следующий метод,deleteAction в классе EmployeeController.
public function deleteAction() {
$id = (int) $this->params()->fromRoute('id', 0); if (!$id) {
return $this->redirect()->toRoute('employee'); } $request = $this->getRequest(); if ($request->isPost()) {
$del = $request->getPost('del', 'No');
if ($del == 'Yes') { $id = (int) $request->getPost('id'); $this->table->deleteEmployee($id); } return $this->redirect()->toRoute('employee');
}
return array(
'id' => $id, 'employee' => $this->table->getEmployee($id)
);
}
Здесь метод deleteEmployee () удаляет сотрудника по его id и перенаправляет на страницу со списком сотрудников (домашнюю страницу).
Давайте теперь создадим соответствующие скрипты представления для метода deleteAction ().
Шаг 26: Создайте сценарий просмотра
Создайте файл с именем delete.phtml в - myapp / module / Employee / view / employee / employee / delete.phtml и добавьте в него следующий код.
<?php
$title = 'Delete an employee record';
$this->headTitle($title);
?>
<h1><?php echo $this->escapeHtml($title); ?></h1>
'<?php echo $this->escapeHtml($employee->emp_name); ?>' by
'<?php echo $this->escapeHtml($employee->emp_job); ?&'?
<?php
$url = $this->url('employee', array('action' => 'delete', 'id' => $this->id,)); ?> <form action ="<?php echo $url; ?>" method = "post">
<div>
<input type = "hidden" name = "id" value = "<?php echo (int) $employee->id; ?>" />
<input type = "submit" name = "del" value = "Yes" />
<input type = "submit" name = "del" value = "No" />
</div>
</form>
Теперь удалите любого сотрудника, использующего edit ссылку на домашней странице, и результат будет таким, как показано на следующем снимке экрана.
Результат
Мы успешно завершили работу над модулем «Сотрудник», реализовав все необходимые функции.
Заключение
В текущей конкурентной среде фреймворк Zend занимает первое место среди разработчиков. Он предоставляет абстракции для любой программы или любого типа приложения на языке PHP. Это зрелая структура, поддерживающая функции современного языка PHP. Это весело, профессионально, развивается и идет в ногу с современными технологиями.