Учебники

Zend Framework — Краткое руководство

Zend Framework — Введение

PHP Web Framework — это набор классов, который помогает разрабатывать веб-приложения. Zend является одним из самых популярных PHP-фреймворков. Это среда MVC с открытым исходным кодом для быстро развивающихся современных веб-приложений. 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, а именно пространства имен, лямбда-функции и замыкания .

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.

  • гибкость
  • Просто и продуктивно
  • Совместимость
  • Расширяемость — программист может легко расширить все классы фреймворка.
  • Портативность — поддерживает несколько сред

Zend Applications

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

  • Сайт компании McAfee
  • Сайт компании IBM
  • Magento — один из самых популярных интернет-магазинов.

Преимущества Zend Framework

Некоторые из преимуществ Zend Framework перечислены ниже.

  • Слабая связь — Zend предоставляет возможность удалять модули или компоненты, которые нам не нужны в приложении.

  • Производительность — Zend Framework высоко оптимизирован для производительности. Zend Framework 3 в 4 раза быстрее своей предыдущей версии.

  • Безопасность — Framework поддерживает стандартное шифрование.

  • Тестирование — PHPUnit интегрирован с Zend, так что вы можете легко протестировать фреймворк.

Слабая связь — Zend предоставляет возможность удалять модули или компоненты, которые нам не нужны в приложении.

Производительность — Zend Framework высоко оптимизирован для производительности. Zend Framework 3 в 4 раза быстрее своей предыдущей версии.

Безопасность — Framework поддерживает стандартное шифрование.

Тестирование — PHPUnit интегрирован с Zend, так что вы можете легко протестировать фреймворк.

В следующей главе мы узнаем, как установить Zend Framework.

Zend Framework — Установка

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

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

  • Установите последнюю версию PHP — чтобы получить максимальную выгоду от Zend Framework, установите последнюю версию PHP. Минимальная необходимая версия для Zend Framework 3 — PHP 5.6 или более поздняя.

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

Установите последнюю версию 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 может получить доступ к классам платформы. Хотя для этого есть несколько способов, ваш PHP include_path должен содержать путь к классам Zend Framework в каталоге / library в дистрибутиве. Этот метод применяется только к Zend Framework версии 2.4 и более ранним.

Композитор на основе установки

Чтобы легко установить Zend Framework, используйте инструмент Composer. Это предпочтительный способ установки последней версии Zend Framework. Чтобы установить все компоненты Zend Framework, используйте следующую команду Composer —

$ composer require zendframework/zendframework

Каждый модуль / компонент Zend Framework также может быть установлен индивидуально. Например, чтобы установить компонент MVC Zend Framework, используйте следующую команду composer

$ composer require zendframework/zend-mvc

Zend Framework — Скелетное приложение

Давайте создадим скелетное приложение, используя слой и модульные системы 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

$ cd path/to/install/myapp 
$ composer serve

Тогда вы увидите следующий ответ —

> php -S 0.0.0.0:8080 -t public/ public/index.php 

Это запустит встроенный сервер CLI PHP на порту 8080. После запуска сервера разработки вы можете посетить сайт по адресу (http: // localhost: 8080 /) . Встроенный CLI-сервер предназначен только для разработки.

CLI Server

Модульные тесты

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

$ 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>

Zend Framework — Архитектура MVC

Прежде чем перейти к этой главе, давайте кратко разберемся с MVC. Model View Controller — это программный подход, который отделяет логику приложения от представления. На практике это позволяет веб-страницам содержать минимальные сценарии PHP, поскольку презентация отделена от них.

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

  • Модель — Модель представляет структуру данных приложения. Как правило, классы моделей содержат функции, которые помогают извлекать, вставлять и обновлять бизнес-данные в внутренней базе данных (MySQL, PostgreSQL и т. Д.).

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

  • Контроллер — Контроллер является основным компонентом архитектуры MVC. Каждый запрос сначала попадает в контроллер. Другими словами, контроллер обрабатывает весь запрос и служит посредником между моделью, представлением и любыми другими ресурсами, необходимыми для обработки HTTP-запроса и генерации ответа.

Модель — Модель представляет структуру данных приложения. Как правило, классы моделей содержат функции, которые помогают извлекать, вставлять и обновлять бизнес-данные в внутренней базе данных (MySQL, PostgreSQL и т. Д.).

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

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

В следующей главе мы разберемся с различными концепциями Zend Framework.

Zend Framework — Концепции

Zend Framework — это коллекция из более 60 компонентов. Они слабо связаны друг с другом. Они могут использоваться как в качестве отдельного компонента, так и в качестве группы компонентов, работающих как единое целое.

Zend Framework предоставляет три наиболее важных компонента:

  • Зенд-ServiceManager
  • Zend-EventManager и
  • Зенд-ModuleManager.

Они предоставляют компонентам Zend возможность эффективной интеграции с другими компонентами.

  • Менеджер событий — дает возможность создавать программирование на основе событий. Это помогает создавать, внедрять и управлять новыми событиями.

  • Диспетчер сервисов — дает возможность использовать любые сервисы (классы PHP) из любой точки мира без особых усилий.

  • Диспетчер модулей — Возможность конвертировать коллекцию классов PHP с аналогичной функциональностью в единое целое, называемое модулем . Вновь созданные модули могут использоваться, обслуживаться и настраиваться как единое целое.

Менеджер событий — дает возможность создавать программирование на основе событий. Это помогает создавать, внедрять и управлять новыми событиями.

Диспетчер сервисов — дает возможность использовать любые сервисы (классы PHP) из любой точки мира без особых усилий.

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

Мы рассмотрим эти концепции подробно в следующих главах.

Zend Framework — Сервис-менеджер

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. Это дает возможность получить другие услуги.

  • запрашиваемое имя — это имя службы.

  • параметры — это дает дополнительные параметры, необходимые для службы.

container (ContainerInterface) — это базовый интерфейс ServiceManager. Это дает возможность получить другие услуги.

запрашиваемое имя — это имя службы.

параметры — это дает дополнительные параметры, необходимые для службы.

Давайте создадим простой класс, реализующий FactoryInterface, и посмотрим, как его зарегистрировать.

Тест класса — объект, который нужно получить

use stdClass;  
class Test { 
   public function __construct(stdClass $sc) { 
      // use $sc 
   } 
} 

Класс Test зависит от stdClass.

Class 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) 

Метод инициализатора

Метод Initializer — это специальная опция для добавления дополнительных зависимостей для уже созданных сервисов. Он реализует 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 
); 

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

Ленивые Услуги

Ленивый сервис — это один из тех сервисов, который не будет полностью инициализирован во время создания. Они просто ссылаются и инициализируются только тогда, когда это действительно необходимо. Одним из лучших примеров является соединение с базой данных, которое может понадобиться не во всех местах. Это дорогой ресурс, так как на его создание уходит много времени. Zend Framework предоставляет LazyServiceFactory, производный от DelegatorFactoryInterface , который может создавать ленивый сервис с помощью концепции делегатора и стороннего менеджера прокси, который называется менеджером прокси ocramius .

Менеджер плагинов

Менеджер плагинов расширяет менеджер сервисов и предоставляет дополнительные функции, такие как проверка экземпляров. Zend Framework широко использует менеджер плагинов.

Например, все службы проверки подпадают под ValidationPluginManager .

Вариант конфигурации

Диспетчер сервисов предоставляет некоторые опции для расширения возможностей диспетчера сервисов. Они являются общими, shared_by_default и псевдонимами . Как мы уже говорили ранее, извлеченные объекты по умолчанию распределяются между запрашиваемыми объектами, и мы можем использовать метод build () для получения отдельного объекта. Мы также можем использовать параметр общего доступа, чтобы указать, какой сервис будет использоваться совместно. Shared_by_default — это то же самое, что и общая функция, за исключением того, что она применяется ко всем сервисам.

$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' => ['std' => stdClass::class, 'standard' => 'std'] 

Zend Framework — менеджер событий

Все современные приложения нуждаются в надежных и гибких компонентах событий. Zend Framework предоставляет один такой компонент, zend-eventmanager . Zend-eventmanager помогает проектировать архитектуру высокого уровня и поддерживает шаблон субъекта / наблюдателя и аспектно-ориентированное программирование.

Установить менеджер событий

Менеджер событий может быть установлен с помощью Composer, как указано ниже —

composer require zendframework/zend-eventmanager 

Концепции менеджера событий

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

  • Событие — Событие называется произвольно, например, приветствие .

  • Listener — любой обратный вызов PHP. Они привязаны к событиям и вызываются при их запуске. Подпись слушателя по умолчанию —

Событие — Событие называется произвольно, например, приветствие .

Listener — любой обратный вызов PHP. Они привязаны к событиям и вызываются при их запуске. Подпись слушателя по умолчанию —

function(EventInterface $e)
  • Класс EventInterface — используется для указания самого события. У него есть методы для установки и получения информации о событии, например, имя (set / getName), цель (get / setTarget) и параметр (get / setParams).

  • Класс EventManager — Экземпляр EventManager отслеживает все определенные события в приложении и его соответствующих слушателях. EventManager предоставляет метод прикрепления для присоединения слушателя к событию, а также метод, запускающий любое предопределенное событие. После вызова триггера EventManager вызывает подключенный к нему слушатель.

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

Класс EventInterface — используется для указания самого события. У него есть методы для установки и получения информации о событии, например, имя (set / getName), цель (get / setTarget) и параметр (get / setParams).

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

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

пример

Давайте напишем простое консольное приложение PHP, чтобы понять концепцию менеджера событий. Следуйте инструкциям ниже.

  • Создайте папку «Eventapp».

  • Установите zend-eventmanager, используя композитор.

  • Создайте PHP-файл Greeter.php в папке eventapp.

  • Создайте класс Greeter и реализуйте EventManagerAwareInterface .

Создайте папку «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; 
}

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

Напишите метод, поприветствуйте , в классе Greeter .

public function greet($message) { 
   printf("\"%s\" from class\n", $message); 
   $this->getEventManager()->trigger(__FUNCTION__, $this, $message ]); 
} 

Этот метод получает менеджер событий и запускает / запускает события, связанные с ним.

Следующим шагом является создание экземпляра класса Greeter и присоединение слушателя к его методу 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"] 

Приведенный выше пример приложения объясняет только основы менеджера событий. Менеджер событий предоставляет множество более сложных опций, таких как приоритет прослушивателя, прототип / подпись настраиваемого обратного вызова, короткое замыкание и т. Д. Менеджер событий широко используется в среде Zend MVC.

Zend Framework — модульная система

Zend Framework предоставляет мощную модульную систему. Модульная система состоит из трех компонентов. Они заключаются в следующем —

  • Модульный автозагрузчик — Модульный автозагрузчик отвечает за поиск и загрузку модулей из различных источников. Он также может загружать модули, упакованные как Phar-архивы . Реализация модуля автозагрузчика находится по адресу myapp / vendor / zendframework / zend-loader / src / ModuleAutoloader.php.

  • Диспетчер модулей — как только модуль автозагрузки обнаружит модули, диспетчер модулей запускает последовательность событий для каждого модуля. Реализация менеджера модулей находится по адресу myapp / vendor / zendframework / zendmodulemanager / src / ModuleManager.php.

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

Модульный автозагрузчик — Модульный автозагрузчик отвечает за поиск и загрузку модулей из различных источников. Он также может загружать модули, упакованные как Phar-архивы . Реализация модуля автозагрузчика находится по адресу myapp / vendor / zendframework / zend-loader / src / ModuleAutoloader.php.

Диспетчер модулей — как только модуль автозагрузки обнаружит модули, диспетчер модулей запускает последовательность событий для каждого модуля. Реализация менеджера модулей находится по адресу myapp / vendor / zendframework / zendmodulemanager / src / ModuleManager.php.

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

MVC Web Module System

Веб-приложение 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_ могут использоваться в качестве механизма по умолчанию для автозагрузки классов, доступных в модуле, без использования расширенного менеджера модулей, доступного в zend-modulemanager .

  • autoload_classmap.php — возвращает массив имени класса и соответствующего имени файла.

  • autoload_function.php — возвращает обратный вызов PHP. Это может использовать классы, возвращаемые autoload_classmap.php.

  • autoload_register.php — регистрирует обратный вызов PHP, который возвращается autoload_function.php.

autoload_classmap.php — возвращает массив имени класса и соответствующего имени файла.

autoload_function.php — возвращает обратный вызов PHP. Это может использовать классы, возвращаемые autoload_classmap.php.

autoload_register.php — регистрирует обратный вызов PHP, который возвращается autoload_function.php.

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

Модульный класс

Класс модуля должен называться модулем, а пространство имен класса модуля должно быть именем модуля . Это поможет Zend Framework легко разрешить и загрузить модуль. Код модуля приложения в скелетном (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 — Структура приложения

В этой главе давайте разберемся со структурой приложения 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 состоит из разных папок. Они заключаются в следующем —

  • Приложение — этот каталог содержит ваше приложение. Он будет содержать систему MVC, а также конфигурации, используемые службы и файл начальной загрузки.

  • Config — этот каталог содержит файлы конфигурации приложения.

  • Данные — этот каталог предоставляет место для хранения данных приложения, которые являются нестабильными и, возможно, временными.

  • Модуль — Модули позволяют разработчику группировать набор связанных контроллеров в логически организованную группу.

  • Общедоступный — это корень документа приложения. Запускает приложение Zend. Он также содержит ресурсы приложения, такие как JavaScript, CSS, изображения и т. Д.

  • Поставщик — Этот каталог содержит зависимости композитора.

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

Config — этот каталог содержит файлы конфигурации приложения.

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

Модуль — Модули позволяют разработчику группировать набор связанных контроллеров в логически организованную группу.

Общедоступный — это корень документа приложения. Запускает приложение Zend. Он также содержит ресурсы приложения, такие как JavaScript, CSS, изображения и т. Д.

Поставщик — Этот каталог содержит зависимости композитора.

Структура прикладных модулей

Это основной каталог вашего приложения. Zend Framework 2 представляет мощную и гибкую модульную систему для эффективной организации приложения. Модуль Application скелетного приложения (myapp) обеспечивает загрузку, настройку ошибок и маршрутизацию для всего приложения. Структура модуля приложения выглядит так:

├── 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

Давайте рассмотрим каждый из этих каталогов модулей подробно —

  • Приложение — это корневой каталог модуля. Имя папки будет соответствовать имени модуля, а имя также используется в качестве пространства имен PHP для всех классов, определенных внутри модуля. Он будет содержать систему MVC, а также конфигурации, используемые службы и файл начальной загрузки.

  • Config — Независимая конфигурация модуля.

  • Src — основная бизнес-логика приложения.

  • Просмотр — содержит файлы дизайна / презентации (HTML). Например, index.phtml.

  • src / Module.php — это сердце модуля. Он работает как «фронт-контроллер» для модуля. Zend обрабатывает файл src / Module.php перед обработкой любых классов PHP в этом модуле.

  • Application / config / module.config.php — это реализовано для конфигурации маршрутизатора и автоматической загрузки файлов.

  • Приложение / представление / макет — макеты представляют общие части нескольких представлений. Например, верхний и нижний колонтитулы страницы. По умолчанию макеты должны храниться в папке views / layouts .

Приложение — это корневой каталог модуля. Имя папки будет соответствовать имени модуля, а имя также используется в качестве пространства имен PHP для всех классов, определенных внутри модуля. Он будет содержать систему MVC, а также конфигурации, используемые службы и файл начальной загрузки.

Config — Независимая конфигурация модуля.

Src — основная бизнес-логика приложения.

Просмотр — содержит файлы дизайна / презентации (HTML). Например, index.phtml.

src / Module.php — это сердце модуля. Он работает как «фронт-контроллер» для модуля. Zend обрабатывает файл src / Module.php перед обработкой любых классов PHP в этом модуле.

Application / config / module.config.php — это реализовано для конфигурации маршрутизатора и автоматической загрузки файлов.

Приложение / представление / макет — макеты представляют общие части нескольких представлений. Например, верхний и нижний колонтитулы страницы. По умолчанию макеты должны храниться в папке views / layouts .

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

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

В этой главе мы узнаем, как создать модуль на основе MVC в Zend Framework. Давайте создадим модуль, называемый Tutorial, чтобы понять процесс создания модуля.

  • Создайте новый класс PHP с именем Module в каталоге –myapp / module / Tutorial / src / и реализуйте интерфейс ConfigProviderInterface.

  • Установите Tutorial в качестве пространства имен для класса Module .

  • Напишите публичную функцию getConfig в классе Module и верните файл конфигурации для учебного модуля.

Создайте новый класс PHP с именем Module в каталоге –myapp / module / Tutorial / src / и реализуйте интерфейс ConfigProviderInterface.

Установите Tutorial в качестве пространства имен для класса Module .

Напишите публичную функцию getConfig в классе Module и верните файл конфигурации для учебного модуля.

Полный код для класса 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": { 
   "psr-4": { 
      "Application\\": "module/Application/src/", 
      "Tutorial\\": "module/Tutorial/src/" 
   } 
}

Обновите приложение с помощью команды обновления composer, как показано ниже.

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',], 
   ], 
];

Файл конфигурации состоит из трех частей, и они следующие:

  • Конфигурация контроллера — укажите контроллеры, доступные внутри модуля.

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

  • Просмотр конфигурации — укажите конфигурацию, относящуюся к просмотру движка, например расположение просмотров и т. Д.

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

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

Просмотр конфигурации — укажите конфигурацию, относящуюся к просмотру движка, например расположение просмотров и т. Д.

Сконфигурируйте модуль Tutorial в файле конфигурации уровня приложения — myapp / config / modules.config.php.

return ['Zend\Router', 'Zend\Validator', 'Application', 'Tutorial'];

Запустите приложение, выполнив команду composer в корне папки приложения.

Мы успешно добавили новый модуль, но нам все еще нужно добавить Controller, Routing и Views, чтобы успешно запустить модуль Tutorial .

Zend Framework — Контроллеры

Как обсуждалось ранее, контроллер играет важную роль в 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)

InjectApplicationEventInterface — используется для внедрения событий (Zend EventManager)

ServiceLocatorAwareInterface — используется для поиска сервисов (Zend ServiceManager)

EventManagerAwareInterface — используется для управления событиями (Zend EventManager)

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

AbstractActionController

AbstractActionController (Zend / Mvc / Controller / AbstractActionController) является наиболее часто используемым контроллером в Zend MVC Framework. Он имеет все необходимые функции для написания типичной веб-страницы. Это позволяет маршрутам (маршрутизация соответствует URL-адресу запроса к контроллеру и одному из его методов), чтобы соответствовать действию . При совпадении метод, названный в честь действия, будет вызываться контроллером.

Например, если сопоставлен тест маршрута и маршрут возвращает тест hello for action, будет вызван метод helloAction .

Давайте напишем наш TutorialController, используя AbstractActionController .

  • Создайте новый класс PHP с именем TutorialController , расширив AbstractActionController и поместите его в каталог module / Tutorial / src / Controller / .

  • Установите Tutorial \ Controller в качестве пространства имен.

  • Напишите метод indexAction .

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

Создайте новый класс 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 .

AbstractRestfulController

AbstractRestfulController (Zend \ Mvc \ Controller \ AbstractRestfulController) проверяет метод HTTP входящего запроса и сопоставляет действие (метод) с учетом методов HTTP

Например, запрос с методом GET HTTP либо совпадает с методом getList () или методом get () , если в запросе найден параметр id .

AbstractConsoleController

AbstractConsoleController (Zend \ Mvc \ Controller \ AbstractConsoleController) похож на AbstractActionController за исключением того, что он работает только в среде консоли, а не в браузере.

Zend Framework — Маршрутизация

Маршрутизация отображает URI запроса на метод конкретного контроллера. В этой главе мы увидим, как реализовать маршруты в Zend Framework.

В общем, любой URI состоит из трех частей:

  • Сегмент имени хоста,
  • Сегмент пути и
  • Сегмент запросов.

Например, в URI / URL — http://www.example.com/index?q=data, www.example.com — это сегмент имени хоста, index — это сегмент пути, а q = data — это сегмент запроса. Как правило, маршрутизация проверяет сегмент страницы против набора ограничений. Если какое-либо ограничение совпадает, то оно возвращает набор значений. Одним из основных значений является контроллер.

Маршрутизация также проверяет сегмент хоста, сегмент запроса, методы HTTP запроса, HTTP-заголовки запроса и т. Д. В определенной ситуации.

Route & 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 = []); 
}

Основным методом является совпадение . Этот метод сопоставления проверяет данный запрос на соответствие определенному в нем ограничению. Если какое-либо совпадение найдено, возвращается объект 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». Достаточно выбрать и использовать подходящий объект маршрута для данной ситуации.

Доступны следующие маршруты:

  • Имя хоста — используется для соответствия хост-части URI.

  • Literal — используется для точного соответствия URI.

  • Метод — используется для соответствия HTTP-метода входящего запроса.

  • Часть — используется для соответствия части сегмента пути URI с использованием пользовательской логики.

  • Regex — используется для сопоставления сегмента пути URI по шаблону Regex.

  • Схема — используется для соответствия схеме URI, такой как http, https и т. Д.

  • Сегмент — используется для сопоставления пути URI путем разбиения его на несколько сегментов.

Имя хоста — используется для соответствия хост-части URI.

Literal — используется для точного соответствия URI.

Метод — используется для соответствия HTTP-метода входящего запроса.

Часть — используется для соответствия части сегмента пути URI с использованием пользовательской логики.

Regex — используется для сопоставления сегмента пути URI по шаблону Regex.

Схема — используется для соответствия схеме URI, такой как http, https и т. Д.

Сегмент — используется для сопоставления пути URI путем разбиения его на несколько сегментов.

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

Буквальный маршрут

Как правило, маршруты запрашиваются в порядке LIFO. Литеральный маршрут предназначен для точного соответствия пути URI.

Это определено как показано ниже —

$route = Literal::factory(array( 
   'route' => '/path', 
   'defaults' => array('controller' => 'Application\Controller\IndexController', 
      'action' => 'index',), 
));

Приведенный выше маршрут соответствует пути / в URL- адресе запроса и возвращает index в качестве действия и 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',], 
   ], 
];

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

Zend Framework — Просмотр слоя

Уровень представления — это уровень представления приложения MVC. Он отделяет логику приложения от логики представления. В типичном веб-приложении на PHP вся бизнес-логика и дизайн смешаны. Смешивание обеспечивает более быструю разработку в небольшом проекте. Но это с треском проваливается в большом проекте, где задействовано много архитектуры высокого уровня. Чтобы изменить дизайн веб-приложения, разработчик должен также поработать над бизнес-логикой. Это может привести к катастрофическим последствиям, приводящим к нарушению бизнес-логики.

Zend Framework предоставляет продуманный, чистый, гибкий и расширяемый слой View. Слой View доступен в виде отдельного модуля Zend / View и прекрасно интегрируется с модулем Zend / Mvc . Zend View Layer разделен на несколько компонентов, хорошо взаимодействующих друг с другом.

Его различные компоненты следующие:

  • Контейнеры переменных — содержит данные слоя представления.

  • Просмотр моделей — содержит переменные контейнеры и шаблон дизайна.

  • Средства визуализации — обрабатывают данные и шаблон из View Model и выводят представление проекта, возможно, окончательный вывод html.

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

  • Просмотр (Zend \ View \ View) — сопоставляет запрос с средством визуализации, а затем с средством визуализации в ответ.

  • Стратегии рендеринга — Используется View для отображения запроса к рендереру.

  • Стратегии отклика — используются представлением для сопоставления рендерера с откликом.

Контейнеры переменных — содержит данные слоя представления.

Просмотр моделей — содержит переменные контейнеры и шаблон дизайна.

Средства визуализации — обрабатывают данные и шаблон из View Model и выводят представление проекта, возможно, окончательный вывод html.

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

Просмотр (Zend \ View \ View) — сопоставляет запрос с средством визуализации, а затем с средством визуализации в ответ.

Стратегии рендеринга — Используется View для отображения запроса к рендереру.

Стратегии отклика — используются представлением для сопоставления рендерера с откликом.

Слой вида View обрабатывает ViewModel , разрешает шаблон с помощью Resolver , визуализирует его с помощью стратегии рендеринга и, наконец, выводит его с помощью Response Renderer .

Просмотр конфигурации слоя

Как и контроллер, слой View можно настроить в файле конфигурации модуля, который называется — module.config.php . Основная конфигурация — указать, где будут размещаться шаблоны. Это может быть достигнуто путем добавления следующей конфигурации в «module.config.php».

'view_manager' => [ 
   'template_path_stack' => ['tutorial' => __DIR__ . '/../view',], 
] 

По умолчанию слой View имеет поведение по умолчанию для всех его компонентов. Например, ViewModel разрешает имя шаблона действия контроллера внутри корня шаблона по правилу «нижний регистр-имя-модуля / нижний регистр-имя-контроллера / нижний регистр-действие-имя». Однако это может быть переопределено методом setTemplate () в ViewModel.

Контроллеры и View Layer

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

Например, в нашем примере, 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>

Просмотр помощников

View Helper используется для написания небольших элементарных функций, которые будут использоваться в шаблонах. Zend Framework предоставляет интерфейс Zend \ View \ Helper \ HelperInterface для написания стандартных помощников вида.

HelperInterface имеет только два метода,

  • setView () — этот метод принимает экземпляр / реализацию Zend \ View \ Renderer \ RendererInterface.

  • getView () — используется для получения этого экземпляра.

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)

Например, в учебном модуле маршрут называется учебным и имеет два параметра 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> 

Заполнитель

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

Например, мы можем установить, скажем, название компании, а затем использовать его во всех других местах.

<?php $this->placeholder('companyname')->set("TutorialsPoint") ?>  
<?= $this->placeholder('companyname'); ?>

Заполнитель предоставляет некоторые дополнительные параметры для генерации сложного содержимого из массива и объектов PHP. Он также имеет возможность захватить определенный раздел самого шаблона.

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

Класс — Продукт

class Product { 
   public $name; 
   public $description; 
} 

контроллер

$p1 = new Product(); 
$p1->name = 'Car';  
$p1->description = 'Car';  
$p2 = new Product(); 
$p2->name = 'Cycle'; 
$p2->description = 'Cycle';  
$view = new ViewModel(['products' => $products]); 

шаблон

<!-- 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') ?> 

Результат

<div class = "foo"> 
   <h2>Car</h2> 
   <p>Car</p> 
</div>
<div class = "foo"> 
   <h2>Cycle</h2> 
   <p>Cycle</p> 
</div> 

Doctype

Помощник Doctype используется для создания различных HTML-типов документов. Это конкретная реализация помощника Placeholder . Тип документа может быть установлен в файле начальной загрузки и в файле конфигурации.

Основное использование показано ниже —

Загрузочный файл приложения

use Zend\View\Helper\Doctype;  
$doctypeHelper = new Doctype(); 
$doctypeHelper->doctype('XHTML5'); 

Конфигурация модуля

// module/Application/config/module.config.php: 
return [ 
   /* ... */ 
   'view_manager' => [ 
      'doctype' => 'html5', 
      /* ... */ 
   ], 
]; 

шаблон

<?php echo $this->doctype() ?> 

HeadTitle

Помощник HeadTitle используется для создания элемента заголовка HTML. Это конкретная реализация помощника Placeholder . Zend предоставляет возможность установить заголовок в файле конфигурации модуля, и его можно установить на любом уровне, например, сайт, модуль, контроллер, действие и т. Д. Частичный код для HeadTitle выглядит следующим образом:

модуль

headTitleHelper->append($action); 
$headTitleHelper->append($controller); 
$headTitleHelper->append($module); 
$headTitleHelper->append($siteName);

шаблон

<?= $this->headTitle() ?>

Результат

action - controller - module - Zend Framework

HeadMeta

Помощник HeadMeta используется для создания мета-тегов HTML. Это конкретная реализация помощника Placeholder.

Шаблон

<?php 
   $this->headMeta()->appendName('keywords', 'turorialspoint, zend framework, php');  
   echo $this->headMeta() 
?>

Результат

<meta name = "keywords" content = "tutorialspoint, zend framework, php" />

HeadLink

Помощник HeadLink используется для генерации HTML-ссылок для включения внешних ресурсов. Это конкретная реализация помощника Placeholder.

шаблон

<?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(); 
?>

Результат

<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.

шаблон

<?php $this->headStyle()->appendStyle($styles); ?>  
<?php echo $this->headStyle() ?>

HeadScript

HeadScript используется для создания встроенного сценария или для включения внешних сценариев. Это конкретная реализация помощника Placeholder.

шаблон

<? $this->headScript()->appendFile(‘/js/sample.js’);?>  
<?php echo $this->headScript() ?>

InlineScript

InlineScript используется для генерации скрипта в секции head и body шаблона html. Он получен из HeadScript.

HtmlList

HTMLList используется для создания упорядоченного и неупорядоченного списка. Определение HTMLList следующее —

Определение

htmlList($items, $ordered, $attribs, $escape) 

шаблон

$items = [ 
   '2015', 
   ['March', 'November'], 
   '2016', 
];  
echo $this->htmlList($items);

Результат

<ul> 
   <li>2015 
      <ul> 
         <li>March</li> 
         <li>November</li> 
      </ul> 
   </li> 
   <li>2016</li> 
</ul>

цикл

Цикл используется для генерации альтернатив в циклической среде. У него есть функция assign, next и prev.

контроллер

$view = new ViewModel(['message' => 'Hello, Tutorial', 'data' => array('One', 'Two')]);

шаблон

<?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>

Результат

<table> 
   <tr style = "background-color: #F0F0F0"> 
      <td>One</td> 
   </tr> 
   <tr style = "background-color: #FFF"> 
      <td>Two</td> 
   </tr> 
</table>

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

  • BasePath — BasePath используется для генерации пути к общей папке корня приложения.

  • Частичный — Частичный используется для визуализации определенного шаблона в его собственной области видимости переменной.

  • PartialLoop — PartialLoop похож на Partial, но используется в циклической среде.

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

  • JSON — JSON используется в спокойной среде, где выходные данные представлены в формате JSON. Он излучает правильный заголовок HTTP и отключает концепцию макета.

BasePath — BasePath используется для генерации пути к общей папке корня приложения.

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

PartialLoop — PartialLoop похож на Partial, но используется в циклической среде.

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

JSON — JSON используется в спокойной среде, где выходные данные представлены в формате JSON. Он излучает правильный заголовок HTTP и отключает концепцию макета.

В Zend Framework все еще есть много помощников, таких как помощник i18n, помощники по формам, помощники по разбиению на страницы, помощники по навигации и т. Д.

Создание помощников вида

Zend Framework предоставляет встроенный AbstractHelper, реализующий HelperInterface для написания помощников вида.

Шаги, связанные с написанием нового помощника, следующие:

  • Шаг 1 — Расширение класса Zend \ View \ Helper \ AbstractHelper.

  • Шаг 2 — Переопределите функцию __invoke () .

  • Шаг 3 — Установите конфигурацию в файле module.config.php .

  • Шаг 4 — Использование помощника вида в скриптах вида.

Шаг 1 — Расширение класса Zend \ View \ Helper \ AbstractHelper.

Шаг 2 — Переопределите функцию __invoke () .

Шаг 3 — Установите конфигурацию в файле module.config.php .

Шаг 4 — Использование помощника вида в скриптах вида.

Давайте теперь создадим TestHelper

Создайте папку Helper в каталоге myapp / module / Tutorial / src / View . Напишите 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() ?> 

Zend Framework — Макет

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

Конфигурация 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 в каталоге «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.

Модели в Zend Framework

Модель определяет логическое представление данных приложения. Например, в приложении «корзина» — «Продукт», «Клиент», «Корзина» и «Заказы». Они определяют свойства объекта, который он содержит. Некоторые из концепций моделей следующие:

  • Контроллеры связываются с моделями и просят их получить необходимую им информацию. Эта полученная информация затем передается контроллером в представление. Наконец, View будет отображать модель в качестве потребляемых пользователем презентационных данных.

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

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

Контроллеры связываются с моделями и просят их получить необходимую им информацию. Эта полученная информация затем передается контроллером в представление. Наконец, 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, выполнив следующие шаги.

Шаг 1: Создать базу данных в MySQL

Создавайте учебники по базам данных на локальном сервере MySQL. Для этой цели мы можем использовать phpmyadmin или любые другие инструменты MySQL GUI. Давайте использовать клиент MySQL в командной строке. Подключитесь к серверу mysql и выполните следующую команду, чтобы создать учебную базу данных.

create database tutorials

Шаг 2: Создать таблицу в уроках БД

Давайте теперь создадим книгу базы данных в учебниках 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: Заполните данные в таблице книг

Заполните таблицу книг образцами данных. Используйте следующую команду 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: Создать модель для книги

Давайте создадим модель, книгу в каталоге нашего модуля src . Обычно модели группируются в папке «Модель» — /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. Используя функцию exchangeArray , свойство модели можно легко синхронизировать с соответствующей таблицей базы данных.

Обновите модель, книга, как показано ниже —

<?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 для извлечения информации о книге из базы данных. Но мы не использовали никаких ссылок на таблицу в коде. 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: Обновление учебного контроллера

Это сделано, придерживаясь следующих трех шагов.

  • Добавить конструктор с BookTable в качестве аргумента.
private $table;
public function __construct(BookTable $table) { 
   $this->table = $table; 
}
  • Получить информацию о книге, используя метод fetchAll () BookTable, и зарегистрировать ее в представлении.

Получить информацию о книге, используя метод fetchAll () BookTable, и зарегистрировать ее в представлении.

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 — разные базы данных

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

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

Шаг 1 — Создайте базу данных, учебники в локальной базе данных postgresql, используя следующую команду —

CREATE DATABASE tutorials

Шаг 2 — Добавить книгу стол. Перейдите в новую базу данных и выполните сценарий создания таблицы.

\c tutorials 
CREATE TABLE book ( 
   id SERIAL NOT NULL, 
   author varchar(100) NOT NULL, 
   title varchar(100) NOT NULL, 
   PRIMARY KEY (id) 
); 

Шаг 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');

Шаг 4 — Измените информацию о драйвере в файле global.config .

<?php 
return array ( 
   'db' => array ( 
      'driver' => 'Pdo', 
      'dsn' => 'pgsql:dbname = tutorials;host = localhost', 
      'driver_options' => array ( 
      ), 
   ), 
); 

Шаг 5 — Измените учетные данные базы данных в файле local.config .

return array ( 
   'db' => array( 
      'username' => '<username>', 
      'password' => '<password>', 
   ), 
);

Шаг 6 — Наконец, запустите приложение http: // localhost: 8080 / tutorial . Результат такой же, как у приложения MySQL.

Zend Framework — Формы и проверка

Zend Framework предоставляет отдельный компонент, Zend- Form для ускорения процесса создания и проверки формы. Он соединяет модель и видовой слой. Он предоставляет набор элементов формы для создания полноценной HTML-формы из предопределенных моделей, класс InputFilter для проверки модели по форме и параметры для привязки данных из формы к модели и наоборот.

Установить компонент формы

Компонент формы Zend можно установить с помощью команды Composer, как указано ниже:

composer require zendframework/zend-form 

Фреймворк форм Zend имеет три подкомпонента для управления формами. Они как описано ниже подробно —

  • Элементы — используются для определения отдельного элемента управления вводом html, сопоставленного со свойством в модели.

  • Fieldset — используется для группирования элементов и другого набора полей вложенным способом.

  • Форма — используется для создания HTML-формы и состоит из элементов и наборов полей.

Элементы — используются для определения отдельного элемента управления вводом html, сопоставленного со свойством в модели.

Fieldset — используется для группирования элементов и другого набора полей вложенным способом.

Форма — используется для создания HTML-формы и состоит из элементов и наборов полей.

Zend Forms обычно создаются в каталоге модуля // src / Form .

пример

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

Шаг 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 для сопоставления модели и соответствующих деталей формы. мы создали BookForm , расширив класс Form и добавив детали формы для модели Book .

Шаг 2: Обновите модель книги, Book.php

Обновите модель, «Книга» с фильтром и проверкой, как указано ниже —

<?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 — убедитесь, что пользователь не вводит больше символов, чем указанное ограничение.

StripTags — Удалить нежелательный HTML.

StringTrimудаляет ненужные пробелы.

Валидатор StringLength — убедитесь, что пользователь не вводит больше символов, чем указанное ограничение.

Шаг 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-метод запроса пост- методом.

  • Если http-метод запроса не post , он просто отображает шаблон, add.phtml

  • Если http-метод запроса не post , тогда он устанавливает inputfilter , получает данные запроса и устанавливает их в inputfiler.

  • Проверяет, является ли форма действительной, используя метод isValid () класса Form.

  • Если форма недействительна, она снова отображает шаблон, add.phtml

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

Получает объект запроса.

Проверяет, является ли http-метод запроса пост- методом.

Если http-метод запроса не post , он просто отображает шаблон, add.phtml

Если http-метод запроса не post , тогда он устанавливает inputfilter , получает данные запроса и устанавливает их в inputfiler.

Проверяет, является ли форма действительной, используя метод 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 .

Форма страницы

Форма страницы

Страница подтверждения ошибки

Страница ошибок

Zend Framework — загрузка файлов

Загрузка файлов является одной из основных концепций в программировании форм. 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 проверяет детали ввода файла.

Поскольку 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 — добавьте расширение файла к загруженному файлу к цели.

target — целевой путь к загруженному файлу.

randomize — добавить случайную строку, чтобы предотвратить дублирование загруженного файла.

use_upload_extension — добавьте расширение файла к загруженному файлу к цели.

Загрузка файла — рабочий пример

Давайте изменим учебный модуль и добавим функцию загрузки изображений.

Изменить таблицу базы данных

Давайте добавим столбец imagepath в таблицу book, выполнив следующую команду 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 для картинки.

Добавьте новое свойство imagepath для картинки.

public $imagepath; 
  • Обновите метод getInputFilter, как показано ниже —

    • Добавьте фильтр FileInput для элемента ввода файла.

    • Установите проверку UploadFile для проверки элемента ввода файла.

    • Сконфигурируйте RenameUpload для перемещения загруженного файла в нужное место назначения.

Обновите метод 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 . Путь к изображению может исходить из формы или базы данных. Если путь к изображению происходит из формы, форматом будет массив со следующей спецификацией:

Обновите метод 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> 
   } 
}
  • Если imagepath исходит из базы данных, это будет простая строка. Частичный список кода для разбора imagepath выглядит следующим образом:

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

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; 
}

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

<?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 . Теперь мы обновляем BookTable и модифицируем метод saveBook . Этого достаточно, чтобы включить запись imagepath в массив данных, $ 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'); 
         } 
      } 
   } 
}

Обновите addAction в TutorialController.php : Информация о загрузке файла будет доступна в глобальном массиве $ _FILES, и к ней можно получить доступ с помощью метода 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» и включите элемент ввода файла imagepath, как показано ниже —

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 и добавьте новые записи.

Результат будет таким, как показано на следующих скриншотах:

Форма страницы

Пример новой книги

Главная страница

Главная страница

Zend Framework — Ajax

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-запроса на стороне сервера.

Метод isXmlHttpRequest () в объекте Request. Если выполняется запрос AJAX, метод isXmlHttpRequest () объекта запроса возвращает значение true, в противном случае — значение false. Этот метод используется для правильной обработки AJAX-запроса на стороне сервера.

if ($request->isXmlHttpRequest()) { 
   // Ajax request 
} else { 
   // Normal request 
}
  • Zend / View / Model / JsonModel — JsonModel является альтернативой ViewModel, которая используется исключительно для сценариев AJAX и REST API. JsonModel вместе с JsonStrategy (для настройки в блоке менеджера представлений модуля) кодирует данные модели в Json и возвращает их в качестве ответа вместо представлений (phtml).

Zend / View / Model / JsonModel — 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 будет создан. В противном случае будет создана нормальная модель представления.

В обоих случаях информация о книге будет выбрана из базы данных и заполнена в модели. Если модель является JsonModel, то будет вызвана JsonStrategy , и она будет кодировать данные как json и возвращать как ответ.

$ Query-> get (‘showJson’) == 1 используется для целей отладки. Просто добавьте showJson = 1 в URL, и на странице отобразятся данные json.

Шаг 3: Добавьте ajax.phtml

Теперь добавьте скрипт представления ajax.phtml для метода ajaxAction. На этой странице будет ссылка с меткой — Загрузить информацию о книге .

При щелчке по этой ссылке выполняется запрос 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

Страница Ajax с информацией о книге

Информация о книге

Страница Ajax с отладочной информацией

Отладочная информация

Zend Framework — Управление cookie

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 , который используется для отправки запроса на веб-сервер. Cookies могут быть инициализированы, как показано в коде ниже —

use Zend\Http\Cookies  
$c = new Cookies(); 

Когда HTTP-клиент (Zend \ Http \ Client) сначала отправляет URI-запрос веб-серверу, у него нет файла cookie. Как только запрос получен веб-сервером, он включает cookie в свой объект ответа как заголовок HTTP, Set-Cookie и отправляет его клиенту HTTP. HTTP-клиент извлечет куки-файл из ответа 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.

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 Framework предоставляет отдельный компонент, Zend -session для обработки информации о сеансе.

Установите компонент сеанса

Сессионный компонент может быть установлен с помощью Composer, как указано ниже —

composer require zendframework/zend-session 

Сессионные компоненты

Zend Framework предоставляет шесть компонентов для управления сессиями. Все эти компоненты были объяснены ниже —

  • Zend \ Session \ Container — основной API для чтения и записи информации о сеансе.

  • Zend \ Session \ SessionManager — используется для управления всем жизненным циклом сеанса.

  • Zend \ Session \ Storage — используется для указания того, как данные сеанса будут храниться в памяти.

  • Zend \ Session \ SaveHandler — используется для хранения и извлечения данных сеанса в физическом месте, таком как RDBMS, Redis, MangoDB и т. Д.

  • Zend \ Session \ Validator — используется для защиты сессии от перехвата путем перекрестной проверки удаленного адреса исходного и последующего запроса и пользовательского агента.

  • Zend \ Session \ Config \ SessionConfig — используется для настройки поведения сессии.

Zend \ Session \ Container — основной API для чтения и записи информации о сеансе.

Zend \ Session \ SessionManager — используется для управления всем жизненным циклом сеанса.

Zend \ Session \ Storage — используется для указания того, как данные сеанса будут храниться в памяти.

Zend \ Session \ SaveHandler — используется для хранения и извлечения данных сеанса в физическом месте, таком как RDBMS, Redis, MangoDB и т. Д.

Zend \ Session \ Validator — используется для защиты сессии от перехвата путем перекрестной проверки удаленного адреса исходного и последующего запроса и пользовательского агента.

Zend \ Session \ Config \ SessionConfig — используется для настройки поведения сессии.

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

Пример компонента сеанса

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

  • Создайте новое действие sessionAction в TutorialController .

  • Инициализируйте объект- контейнер .

Создайте новое действие sessionAction в TutorialController .

Инициализируйте объект- контейнер .

$c = new Container();
  • Проверьте, существует ли произвольное количество ключей. Если ключ недоступен, инициализируйте счет со значением 1. Если он доступен, увеличьте значение, как показано в следующем коде.

Проверьте, существует ли произвольное количество ключей. Если ключ недоступен, инициализируйте счет со значением 1. Если он доступен, увеличьте значение, как показано в следующем коде.

if (!isset($c->count)) { 
   $c->count = 0; 
} else { 
   $c->count++; 
} 
  • Зарегистрируйте счетчик в ViewModel.

  • Создайте файл шаблона для — sessionAction, session.phtml в myapp / module / Tutorial / view / tutorial / tutorial / session.phtml и затем отобразите значение счетчика .

  • Обновление страницы увеличит значение счетчика в сеансе. Полный список выглядит следующим образом —

Зарегистрируйте счетчик в ViewModel.

Создайте файл шаблона для — sessionAction, session.phtml в myapp / module / Tutorial / view / tutorial / tutorial / session.phtml и затем отобразите значение счетчика .

Обновление страницы увеличит значение счетчика в сеансе. Полный список выглядит следующим образом —

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 ?>

Образец результата

Session data, Count = 5

Zend Framework — Аутентификация

Аутентификация является одной из наиболее важных и обязательных функций в любом веб-приложении. Zend Framework предоставляет отдельный компонент для обработки аутентификации, который называется zend-аутентификация .

Установите компонент аутентификации

Компонент аутентификации может быть установлен с помощью следующей команды Composer .

composer require zendframework/zend-authentication

концепция

Обычно разработчик пишет функцию php для аутентификации пользовательских данных в источнике данных. Как только аутентификация выполнена, детали аутентификации сохраняются для последующих запросов. Zend Framework обобщает эту концепцию и предоставляет два класса, которые описаны ниже:

Класс 1 Zend \ Authentication \ Adapter \ AdaptorInterface

Этот класс предоставляет один метод аутентификации для записи логики аутентификации. Метод authenticate возвращает экземпляр класса Zend \ Authentication \ Result .

Этот объект Result содержит статус аутентификации; идентификатор, если аутентификация прошла успешно, и сообщение об ошибке, если аутентификация не удалась. Подпись интерфейса проверки подлинности и класса результата выглядит следующим образом:

AdaptorInterface

namespace Zend\Authentication\Adaptor; 
public function authenticate() { 
   // code 
}

Результат класса

namespace Zend\Authentication; 
class Result { 
   public function __construct($code, $identity, array $messages = []); 
}

Zend Framework предоставляет реализацию по умолчанию для аутентификации по базе данных, ldap, http basic и digest. Адаптер аутентифицирует, но не сохраняет детали для любых будущих запросов.

Класс 2 Zend \ Authentication \ AuthenticationService

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 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('sender@example.com', "sender-name"); 
$mail->addTo('recipient@test.com', "recipient-name"); 

Zend предоставляет класс Zend \ Mail \ Sendmail для отправки почтового сообщения. Sendmail использует функцию php mail, mail для отправки почтового сообщения, и мы можем настроить транспортный уровень, используя файл конфигурации php.

Частичное кодирование с использованием Sendmail выглядит следующим образом:

$transport = new Mail\Transport\Sendmail(); 
$transport->send($mail);

Zend-mail предоставляет множество транспортных уровней, и каждому может потребоваться множество дополнительных параметров, таких как имя пользователя, пароль и т. Д.

Методы управления электронной почтой

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

  • isValid — Сообщения без адреса «От» недействительны.

isValid — Сообщения без адреса «От» недействительны.

isValid() : bool
  • setEncoding — установить кодировку сообщения.

setEncoding — установить кодировку сообщения.

setEncoding(string $encoding) : void
  • getEncoding — получает кодировку сообщения.

getEncoding — получает кодировку сообщения.

getEncoding() : string
  • setHeadersсоставить заголовки.

setHeadersсоставить заголовки.

setHeaders(Zend\Mail\Headers $headers) : void
  • getHeaders — Доступ к коллекции заголовков.

getHeaders — Доступ к коллекции заголовков.

getHeaders() : Zend\Mail\Headers
  • setFrom — Установить (перезаписать) из адресов. Он содержит пары ключ / значение, где ключ — это удобочитаемое имя, а значение — адрес электронной почты.

setFrom — Установить (перезаписать) из адресов. Он содержит пары ключ / значение, где ключ — это удобочитаемое имя, а значение — адрес электронной почты.

setFrom( 
   string|AddressInterface|array|AddressList|Traversable $emailOrAddressList, 
      string|null $name 
) : void 
  • addFrom — добавить адрес «От».

addFrom — добавить адрес «От».

addFrom( 
   string|AddressInterface|array|AddressList|Traversable $emailOrAddressOrList, 
      string|null $name 
) : void 
  • getFrom — Получить список отправителей.

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 — Установить значение заголовка темы сообщения.

setSubject(string $subject) :void 
  • setBody — Установить тело сообщения.

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-адрес.

  • порт — порт, на котором слушает удаленный хост.

name — имя хоста SMTP.

host — Удаленное имя хоста или IP-адрес.

порт — порт, на котором слушает удаленный хост.

Концепция Почты — Пример

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

  • Создайте папку «mailapp».

  • Установите Zend-Mail с помощью инструмента composer.

  • Создайте php-файл Mail.php в папке «mailapp».

  • Создайте сообщение, используя Zend \ Mail \ Message .

Создайте папку «mailapp».

Установите Zend-Mail с помощью инструмента composer.

Создайте php-файл Mail.php в папке «mailapp».

Создайте сообщение, используя Zend \ Mail \ Message .

$message = new Message(); 
$message->addTo('user1@gmail.com'); 
$message->addFrom('user2@gmail.com'); 
$message->setSubject('Hello!'); 
$message->setBody("My first Zend-mail application!"); 
  • Создайте транспортный уровень SMTP и добавьте необходимую конфигурацию.

Создайте транспортный уровень 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); 
  • Отправьте письмо, используя метод отправки .

Отправьте письмо, используя метод отправки .

$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('user1@gmail.com'); 
$message->addFrom('user2@gmail.com'); 
$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 . Это отправит письмо, как настроено в приложении.

Zend Framework — модульное тестирование

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

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

Настройка PHPUnit

Zend Framework интегрируется с платформой модульного тестирования PHPUnit. Чтобы написать модульный тест для инфраструктуры Zend, нам нужно настроить 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 Framework предоставляет вспомогательные классы для модульного тестирования контроллера. TestCase является основным компонентом в среде PHPUnit для написания тестовых случаев, а Zend Framework предоставляет абстрактную реализацию TestCase, которая называется AbstractHttpControllerTestCase .

Этот AbstractHttpControllerTestCase предоставляет различные методы Assert и может группироваться по функциональности. Они заключаются в следующем —

  • Запрос подтверждения — используется для подтверждения http-запроса. Например, assertControllerName.

  • CSS Select Assertions — Используется для проверки HTML ответа с использованием модели DOM HTML.

  • Утверждения XPath — альтернатива выбранным утверждениям CSS на основе XPath.

  • Утверждения о перенаправлении — используются для проверки перенаправления страницы.

  • Утверждения заголовка ответа — используются для проверки заголовка ответа, например кода состояния (assertResponseStatusCode)

Запрос подтверждения — используется для подтверждения http-запроса. Например, assertControllerName.

CSS Select Assertions — Используется для проверки HTML ответа с использованием модели DOM HTML.

Утверждения XPath — альтернатива выбранным утверждениям CSS на основе XPath.

Утверждения о перенаправлении — используются для проверки перенаправления страницы.

Утверждения заголовка ответа — используются для проверки заголовка ответа, например кода состояния (assertResponseStatusCode)

Создать каталог тестов

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

Например, чтобы написать тест для TutorialController, доступный в модуле Tutorial, необходимо поместить класс test в каталог myapp / module / Tutorial / test / Controller /.

пример

Давайте напишем тестовый класс для модульного тестирования TutorialController .

Для начала мы должны написать класс с именем TutorialControllerTest и расширить его до AbstractHttpControllerTestCase.

Следующим шагом является написание метода установки для настройки тестовой среды. Это можно сделать, вызвав метод 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 — Обработка ошибок

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

Обработчик ошибок отображает ошибки, когда отладка истинна, и регистрирует ошибки, когда отладка ложна. В 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 являются элементами конфигурации, относящимися к ошибкам, и не требуют пояснений.

Наиболее важным элементом среди них является ошибка / индекс . Этот шаблон показывается, когда в системе возникает исключение. Мы можем изменить этот шаблон, myapp / module / Application / view / error / index.phtml, чтобы контролировать количество отображаемой ошибки.

Zend Framework — рабочий пример

В этой главе мы узнаем, как создать полное приложение Employee на основе 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 внесет необходимые изменения в приложение и покажет журналы, как показано в командной строке ниже.

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 для модуля Employee

Создайте файл конфигурации модуля «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: Настройка маршрутизатора

Давайте добавим сегментный маршрут в наш модуль Employee. Обновите файл конфигурации модуля сотрудника, 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. Следующим шагом является создание сценария представления для приложения 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();  
   } 
}

Наконец, мы успешно завершили модуль Employee. мы можем получить к нему доступ, используя следующий URL — http: // localhost: 8080 / employee .

Результат

Шаблон приложения

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

Шаг 7: Создать модель

Давайте создадим модель Employee в нашем каталоге src модуля. Обычно модели группируются в папке «Модель» (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;

Давайте создадим таблицу с именем сотрудника в базе данных, используя следующую команду 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) 
);

Вставьте данные в таблицу сотрудников, используя следующий запрос —

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 .

Результат

Успешная база данных

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

Шаг 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.php .

<?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; 
 использовать Zend \ View \ Model \ ViewModel; 
 используйте Employee \ Model \ Employee;       
 использовать Employee \ Model \ EmployeeTable;    
 использовать Employee \ Form \ EmployeeForm;

 публичная функция addAction () { 
    $ form = new EmployeeForm ();  
    $ Форма-> Get ( 'Submit') -> SetValue ( 'Add');  
    $ request = $ this-> getRequest (); 
   
    if ($ request-> isPost ()) { 
       $ employee = new Employee (); 
       $ Форма-> SetInputFilter ($ employee-> getInputFilter ()); 
       $ Форма-> УстановитьДанные ($ request-> getPost ());  
      
       if ($ form-> isValid ()) { 
          $ Employee-> exchangeArray ($ форма-> GetData ()); 
          $ This-> table-> saveEmployee ($ сотрудника);  
         
          // Перенаправление на список сотрудников 
          return $ this-> redirect () -> toRoute ('employee'); 
       } 
    } 
    возвращаемый массив ('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. Создайте скрипт View для метода 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: Редактировать записи сотрудников

Давайте выполним операции редактирования данных в модуле Employee. Обновите следующие изменения в 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,); 
}

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

Шаг 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 () удаляет сотрудника по его идентификатору и перенаправляет на страницу со списком сотрудников (домашняя страница).

Теперь давайте создадим соответствующие скрипты вида для метода 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>  

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

Результат

Удаленная запись

Мы успешно завершили модуль Employee, реализовав все необходимые функции.

Заключение

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