Zend Framework - Szybki przewodnik
PHP Web Framework to zbiór klas, które pomagają w tworzeniu aplikacji internetowych. Zend to jeden z najpopularniejszych frameworków PHP. To jestopen-source MVC frameworkdo szybko rozwijających się, nowoczesnych aplikacji internetowych. Zend Framework ma kilka luźno powiązanych ze sobą komponentów, dlatego jest nazywany „Biblioteką komponentów”. Zend Framework zapewnia dowolny stos PHP i serwer Zend do uruchamiania aplikacji frameworkowych Zend.
Zend Studio to IDE, które zawiera funkcje do integracji z Zend Framework. Zapewnia widok MVC i generowanie kodu. Obecny framework Zend 3.0 zawiera nowe komponenty, takie jak serwer JSON RPC, konwerter XML na JSON, funkcjonalność PSR-7 i kompatybilność z PHP 7.
Zend Framework 2 to framework typu open source do tworzenia aplikacji i usług internetowych przy użyciu PHP 5.3+. Zend Framework 2 wykorzystuje w 100% kod zorientowany obiektowo i wykorzystuje większość nowych funkcji PHP 5.3, a mianowicieNamespaces, Lambda Functions i Closures.
Zend Framework 2 wyewoluował z Zend Framework 1, odnoszącego sukcesy frameworka PHP z ponad 15 milionami pobrań. Zend Server ma darmową wersję społecznościową i komercyjną.
Funkcje Zend Framework
Oto niektóre z najważniejszych cech Zend Framework -
- Czysta zorientowana obiektowo struktura aplikacji internetowych
- Zaawansowana implementacja MVC
- Obsługuje wiele baz danych, w tym PostgreSQL, SQLite itp.,
- Prosty interfejs API w chmurze
- Zarządzanie sesjami
- Szyfrowanie danych
- Elastyczny routing URI
- Zend zapewnia obsługę programowania RESTful API.
- Kod wielokrotnego użytku i łatwiejszy w utrzymaniu.
Dlaczego Zend Framework?
To, co sprawia, że Zend Framework jest jednym z najlepszych frameworków używanych przez programistów PHP, to to, że zapewnia czysty i stabilny kod wraz z prawami własności intelektualnej. Ułatwia również programowanie. Jest to szybki, łatwy do nauczenia i wygodny framework. Zend obsługuje silne narzędzia kryptograficzne i techniki haszowania haseł.
Cele Zend
Oto cele Zend Framework.
- Flexibility
- Proste i wydajne
- Compatibility
- Rozszerzalność - programista może łatwo rozszerzyć wszystkie klasy frameworka.
- Przenośność - obsługuje wiele środowisk
Aplikacje Zend
Następujące popularne produkty są tworzone przy użyciu Zend Framework.
- Witryna internetowa firmy McAfee
- Serwis WWW firmy IBM
- Magento - jedna z popularnych stron internetowych koszyka zakupów.
Zalety Zend Framework
Poniżej wymieniono niektóre zalety Zend Framework.
Loosely Coupled - Zend zapewnia opcję usuwania modułów lub komponentów, których nie potrzebujemy w aplikacji.
Performance- Zend Framework jest wysoce zoptymalizowany pod kątem wydajności. Zend Framework 3 jest 4x szybszy niż jego poprzednia wersja.
Security - Framework obsługuje standardowe szyfrowanie branżowe.
Testing - PHPUnit jest zintegrowany z Zendem, więc możesz łatwo przetestować framework.
W następnym rozdziale dowiemy się, jak zainstalować Zend Framework.
Aby zainstalować Zend Framework, musimy najpierw zainstalować Composer i najnowszą wersję PHP, jak pokazano w poniższych krokach.
Install Composer- Zend używa Composera do zarządzania swoimi zależnościami, więc upewnij się, że masz zainstalowany Composer na swoim komputerze. Jeśli Composer nie jest zainstalowany, odwiedź oficjalną stronę internetową Composer i zainstaluj go.
Install the latest version of PHP- Aby uzyskać maksymalne korzyści z Zend Framework, zainstaluj najnowszą wersję PHP. Minimalna wymagana wersja Zend Framework 3 to PHP 5.6 lub nowsza.
Zainstaluj Zend Framework
Zend Framework można zainstalować na dwa sposoby. Są następujące -
- Instalacja ręczna
- Instalacja oparta na komponencie
Omówmy szczegółowo obie te instalacje.
Instalacja ręczna
Pobierz najnowszą wersję Zend Framework, odwiedzając poniższy link - https://framework.zend.com/downloads/archives
Wypakuj zawartość pobranego pliku archiwum do folderu, w którym chcesz go zachować. Kiedy masz już kopię Zend Framework dostępną na twojej lokalnej maszynie, twoja aplikacja internetowa oparta na Zend Framework może uzyskać dostęp do klas frameworka. Chociaż istnieje kilka sposobów, aby to osiągnąć, plik PHPinclude_pathmusi zawierać ścieżkę do klas Zend Framework w katalogu / library w dystrybucji. Ta metoda dotyczy tylko Zend Framework w wersji 2.4 i wcześniejszych.
Instalacja oparta na komponencie
Aby łatwo zainstalować Zend Framework, użyj narzędzia Composer. Jest to preferowana metoda instalacji najnowszej wersji Zend Framework. Aby zainstalować wszystkie komponenty Zend Framework, użyj następującego polecenia Composer -
$ composer require zendframework/zendframework
Każdy moduł / komponent Zend Framework można również zainstalować indywidualnie. Na przykład, aby zainstalowaćMVC component Zend Framework, użyj następującego composer polecenie -
$ composer require zendframework/zend-mvc
Stwórzmy szkieletową aplikację, korzystając z warstwy Zend Framework MVC i systemów modułowych.
Instalacja za pomocą Composera
Najłatwiejszym sposobem stworzenia nowego projektu Zend Framework jest użycie Composera. Jest zdefiniowany jak poniżej -
$ cd /path/to/install $ composer create-project -n -sdev zendframework/skeleton-application myapp
Na ekranie zobaczysz następujący wynik -
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.
Po zainstalowaniu aplikacji możesz ją natychmiast przetestować przy użyciu PHP's built-in web server -
$ cd path/to/install/myapp $ composer serve
Wtedy zobaczysz następującą odpowiedź -
> php -S 0.0.0.0:8080 -t public/ public/index.php
Spowoduje to uruchomienie wbudowanego serwera CLI PHP na porcie 8080. Po uruchomieniu serwera deweloperskiego możesz odwiedzić witrynę pod adresem (http://localhost:8080/). Wbudowany serwer CLI jest przeznaczony tylko do programowania.
Testy jednostkowe
Aby uruchomić testy jednostkowe szkieletu, wpisz następujące polecenie w terminalu.
$ composer require --dev zendframework/zend-test
Spowoduje to następującą odpowiedź -
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
Teraz obsługa testowania jest włączona, więc możesz uruchomić test za pomocą następującego polecenia.
$ ./vendor/bin/phpunit
Serwer WWW Apache
Hostowanie aplikacji opartej na Zend Framework w środowisku produkcyjnym jest bardzo proste i nieskomplikowane. Po prostu utwórz plikVirtualHost w pliku konfiguracyjnym Apache i wskaż plik DocumentRoot do Public folder aplikacji Zend Framework.
Przykładowa konfiguracja (myapp) jest podana poniżej -
<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>
Zanim przejdziemy do tego rozdziału, przyjrzyjmy się pokrótce MVC. ZAModel View Controllerto podejście programowe, które oddziela logikę aplikacji od prezentacji. W praktyce pozwala na to, aby strony internetowe zawierały minimalne skrypty PHP, ponieważ prezentacja jest od nich oddzielona.
Krótki opis komponentów MVC jest następujący
Model- Model reprezentuje strukturę danych aplikacji. Zazwyczaj klasy modelu zawierają funkcje, które pomagająretrieve, insert i update business data w bazie danych zaplecza (MySQL, PostgreSQL itp.).
View- Widok to warstwa prezentacji aplikacji MVC. Pobiera dane modeli przez kontroler i wyświetla je w razie potrzeby. Jest luźno połączony zController i Model więc można go zmienić bez wpływu na Model i Kontrolera.
Controller- Kontroler jest głównym składnikiem architektury MVC. Każde żądanie najpierw trafia do kontrolera. Innymi słowy, administrator przetwarza wszystkie żądania i służy jako pośrednik między modelem, widokiem i innymi zasobami potrzebnymi doprocess the HTTP request i wygenerować odpowiedź.
W następnym rozdziale zrozumiemy różne koncepcje Zend Framework.
Zend Framework to zbiór ponad 60 komponentów. Są ze sobą luźno powiązane. Mogą być używane zarówno jako samodzielny komponent, jak również jako grupa komponentów pracujących jako pojedyncza jednostka.
Zend Framework dostarcza trzy najważniejsze komponenty, którymi są -
- zend-servicemanager
- zend-eventmanager i
- zend-modulemanager.
Zapewniają komponentom Zend możliwość efektywnej integracji z innymi komponentami.
Event Manager- Daje możliwość tworzenia programów opartych na zdarzeniach. Pomaga to w tworzeniu, wstrzykiwaniu i zarządzaniu nowymi zdarzeniami.
Service Manager - Daje możliwość korzystania z dowolnych usług (klas PHP) z dowolnego miejsca przy niewielkim wysiłku.
Module Manager - Możliwość konwersji zbioru klas PHP o podobnej funkcjonalności do pojedynczej jednostki o nazwie module. Nowo utworzone moduły mogą być używane, konserwowane i konfigurowane jako jedna jednostka.
Pojęcia te omówimy szczegółowo w kolejnych rozdziałach.
Zend Framework zawiera potężną implementację wzorca lokalizatora usług o nazwie zend-servicemanager. Framework Zend intensywnie wykorzystuje menadżera usług do wszystkich swoich funkcjonalności. Service Manager zapewnia abstrakcję wysokiego poziomu dla Zend Framework. Ładnie integruje się również ze wszystkimi innymi komponentami Zend Framework.
Zainstaluj program Service Manager
Składnik Service Manager można zainstalować przy użyciu composer narzędzie.
composer require zendframework/zend-servicemanager
Przykład
Po pierwsze, wszystkie usługi muszą być zarejestrowane w menedżerze usług. Po zarejestrowaniu usług w systemie zarządzania serwerami można uzyskać do nich dostęp w dowolnym momencie przy minimalnym wysiłku. Menedżer serwisu zapewnia wiele opcji rejestracji usługi. Prosty przykład jest następujący -
use Zend\ServiceManager\ServiceManager;
use Zend\ServiceManager\Factory\InvokableFactory;
use stdClass;
$serviceManager = new ServiceManager([
'factories' => [stdClass::class => InvokableFactory::class,],
]);
Powyższy kod rejestruje plik stdClass do systemu za pomocą Factoryopcja. Teraz możemy w dowolnym momencie pobrać wystąpienie klasy stdClass za pomocąget() metoda menedżera serwisu, jak pokazano poniżej.
use Zend\ServiceManager\ServiceManager;
$object = $serviceManager->get(stdClass::class);
Metoda get () współużytkuje pobrany obiekt, a więc obiekt zwracany przez wielokrotne wywołanie metody get () to jedno i to samo wystąpienie. Aby za każdym razem uzyskać inną instancję, menedżer usług udostępnia inną metodę, którą jestbuild() metoda.
use Zend\ServiceManager\ServiceManager;
$a = $serviceManager->build(stdClass::class); $b = $serviceManager->build(stdClass::class);
Rejestracja menedżera usług
Menedżer usług udostępnia zestaw metod rejestracji komponentu. Poniżej przedstawiono niektóre z najważniejszych metod -
- Metoda fabryczna
- Abstrakcyjna metoda fabryczna
- Metoda inicjatora
- Metoda fabryczna delegatora
Każdy z nich omówimy szczegółowo w kolejnych rozdziałach.
Metoda fabryczna
Fabryka to w zasadzie dowolna klasa wywoływalna lub dowolna klasa implementująca FactoryInterface (Zend \ ServiceManager \ Factory \ FactoryInterface).
Interfejs FactoryInterface ma jedną metodę -
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
Szczegóły argumentów FactoryInterface są następujące -
container (ContainerInterface)- Jest to podstawowy interfejs programu ServiceManager. Zapewnia możliwość skorzystania z innych usług.
requestedName - To nazwa usługi.
options - Daje dodatkowe opcje potrzebne do wykonania usługi.
Stwórzmy prostą klasę implementującą FactoryInterface i zobaczmy, jak zarejestrować klasę.
Test klasy - obiekt do pobrania
use stdClass;
class Test {
public function __construct(stdClass $sc) { // use $sc
}
}
Plik Test klasa zależy od stdClass.
Class TestFactory - Klasa do zainicjowania obiektu testowego
class TestFactory implements FactoryInterface {
public function __invoke(ContainerInterface $container, $requestedName,
array $options = null) { $dep = $container->get(stdClass::class); return new Test($dep);
}
}
TestFactory używa kontenera do pobrania stdClass, tworzy wystąpienie klasy Test i zwraca ją.
Rejestracja i korzystanie z Zend Framework
Zrozummy teraz, jak zarejestrować i używać Zend Framework.
serviceManager $sc = new ServiceManager([ 'factories' => [stdClass::class => InvokableFactory::class, Test::class => TestFactory::class] ]); $test = $sc->get(Test::class);
Kierownik serwisu zapewnia specjalną fabrykę o nazwie InvokableFactoryaby pobrać dowolną klasę, która nie ma zależności. Na przykładstdClass można skonfigurować przy użyciu InvokableFactory, ponieważ stdClass nie zależy od żadnej innej klasy.
serviceManager $sc = new ServiceManager([
'factories' => [stdClass::class => InvokableFactory::class]
]);
$stdC = $sc->get(stdClass::class);
Innym sposobem na pobranie obiektu bez implementacji FactoryInterface lub używając InvokableFactory korzysta z metody inline, jak podano poniżej.
$serviceManager = new ServiceManager([ 'factories' => [ stdClass::class => InvokableFactory::class, Test::class => function(ContainerInterface $container, $requestedName) { $dep = $container->get(stdClass::class); return new Test($dep);
},
],
]);
Abstrakcyjna metoda fabryczna
Czasami może zaistnieć potrzeba stworzenia obiektów, które poznajemy dopiero w czasie wykonywania. Ta sytuacja może być rozwiązana przy użyciuAbstractFactoryInterface, który pochodzi z interfejsu FactoryInterface.
AbstractFactoryInterface definiuje metodę, aby sprawdzić, czy obiekt można utworzyć w żądanym wystąpieniu, czy nie. Jeśli tworzenie obiektu jest możliwe, utworzy obiekt przy użyciu rozszerzenia__invokemethod interfejsu FactoryInterface i zwróć go.
Podpis obiektu AbstractFactoryInterface jest następujący -
public function canCreate(ContainerInterface $container, $requestedName)
Metoda inicjalizacji
Metoda inicjatora to specjalna opcja umożliwiająca wprowadzenie dodatkowej zależności dla już utworzonych usług. ImplementujeInitializerInterface a podpis jedynej dostępnej metody jest następujący -
public function(ContainerInterface $container, $instance)
function(ContainerInterface $container, $instance) {
if (! $instance instanceof EventManagerAwareInterface) { return; } $instance->setEventManager($container->get(EventManager::class));
}
W powyższym przykładzie metoda sprawdza, czy instancja jest typu EventManagerAwareInterface. Jeśli jest z rodzajuEventManagerAwareInterface, ustawia obiekt menedżera zdarzeń, w przeciwnym razie nie. Ponieważ metoda może ustawić zależność lub nie, nie jest niezawodna i powoduje wiele problemów w czasie wykonywania.
Metoda delegatora fabrycznego
Zend Framework obsługuje wzorce delegatorów DelegatorFactoryInterface. Może służyć do dekoracji serwisu.
Podpis tej funkcji jest następujący -
public function __invoke(ContainerInterface $container,
$name, callable $callback, array $options = null
);
Tutaj $callback jest odpowiedzialny za dekorowanie instancji usługi.
Lazy Services
Leniwa usługa to jedna z tych usług, które nie zostaną w pełni zainicjowane w momencie tworzenia. Są tylko przywoływane i inicjowane tylko wtedy, gdy jest to naprawdę potrzebne. Jednym z najlepszych przykładów jest połączenie z bazą danych, które może nie być potrzebne we wszystkich miejscach. Jest to kosztowny zasób, a jego tworzenie jest czasochłonne. Framework Zend zapewniaLazyServiceFactory pochodzi z DelegatorFactoryInterface, który może produkować leniwe usługi przy pomocy Delegator koncepcja i zewnętrzny menedżer proxy, który jest nazywany ocramius proxy manager.
Menedżer wtyczek
Plugin Manager rozszerza menedżera usług i zapewnia dodatkowe funkcje, takie jak walidacja instancji. Zend Framework intensywnie korzysta z menedżera wtyczek.
Na przykład wszystkie usługi walidacji są objęte rozszerzeniem ValidationPluginManager.
Opcja konfiguracji
Menedżer usług udostępnia kilka opcji rozszerzenia funkcji menedżera usług. Oni sąshared, shared_by_default i aliases. Jak omówiliśmy wcześniej, pobrane obiekty są domyślnie współużytkowane przez żądane obiekty i możemy użyć rozszerzeniabuild()metoda, aby uzyskać odrębny obiekt. Możemy również użyćsharedmożliwość określenia, która usługa ma być udostępniana. Plikshared_by_default jest taki sam jak shared funkcja, poza tym, że dotyczy wszystkich usług.
$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
]);
Plik aliasesmożna użyć do podania alternatywnej nazwy zarejestrowanym usługom. Ma to zarówno zalety, jak i wady. Z drugiej strony możemy podać alternatywne krótkie nazwy dla usługi. Ale jednocześnie nazwa może wyrwać się z kontekstu i wprowadzić błędy.
aliases' => ['std' => stdClass::class, 'standard' => 'std']
Wszystkie nowoczesne aplikacje wymagają solidnych i elastycznych komponentów eventowych. Zend Framework dostarcza jeden taki komponent,zend-eventmanager. Zend-eventmanager pomaga projektować architekturę wysokiego poziomu i obsługuje wzorzec przedmiot / obserwator oraz programowanie zorientowane na aspekt.
Zainstaluj Event Manager
Menedżera zdarzeń można zainstalować za pomocą Composer jak określono poniżej -
composer require zendframework/zend-eventmanager
Koncepcje Event Managera
Podstawowe koncepcje menedżera wydarzeń są następujące -
Event - Powiedzmy, że zdarzenie jest arbitralnie nazwane akcją greet.
Listener- Dowolne wywołanie zwrotne PHP. Są one dołączone do zdarzeń i są wywoływane, gdy zdarzenie zostanie wyzwolone. Domyślny podpis odbiornika to -
function(EventInterface $e)
EventInterface Class- Służy do określenia samego zdarzenia. Zawiera metody ustawiania i pobierania informacji o zdarzeniach, takich jak nazwa (set / getName), cel (get / setTarget) i parametr (get / setParams).
EventManager class- Instancja EventManager śledzi wszystkie zdefiniowane zdarzenia w aplikacji i odpowiadających jej odbiornikach. EventManager udostępnia metodę,attach dołącza detektor do zdarzenia i udostępnia metodę, triggeraby wywołać dowolne wcześniej zdefiniowane zdarzenie. Po wywołaniu wyzwalacza EventManager wywołuje dołączony do niego odbiornik.
EventManagerAwareInterface- Aby klasa obsługiwała programowanie oparte na zdarzeniach, musi zaimplementować interfejs EventManagerAwareInterface. Zapewnia dwie metody,setEventManager i getEventManager aby pobrać i ustawić menedżera wydarzeń.
Przykład
Napiszmy prostą aplikację konsoli PHP, aby zrozumieć koncepcję menedżera zdarzeń. Wykonaj czynności podane poniżej.
Utwórz folder „eventapp”.
zainstalować zend-eventmanager używając kompozytora.
Utwórz plik PHP Greeter.php wewnątrz folderu „eventapp”.
Utwórz zajęcia Greeter i zaimplementuj EventManagerAwareInterface.
require __DIR__ . '/vendor/autoload.php';
class Greeter implements EventManagerAwareInterface {
// code
}
Tutaj, require służy do automatycznego ładowania wszystkich zainstalowanych komponentów Composera.
Napisz setEventManager metoda w klasie Greeter jak pokazano poniżej -
public function setEventManager(EventManagerInterface $events) { $events->setIdentifiers([ __CLASS__, get_called_class(),]);
$this->events = $events;
return $this;
}
Ta metoda ustawia bieżącą klasę w podanym menedżerze zdarzeń (argument $ events), a następnie ustawia menedżera zdarzeń w zmiennej lokalnej $events.
Następnym krokiem jest napisanie pliku getEventManager metoda w klasie Greeter jak pokazano poniżej -
public function getEventManager() {
if (null === $this->events) {
$this->setEventManager(new EventManager()); } return $this->events;
}
Metoda pobiera menedżera zdarzeń ze zmiennej lokalnej. jeśli nie jest dostępny, tworzy instancję menedżera zdarzeń i zwraca ją.
Napisz metodę, greet, w klasie Greeter.
public function greet($message) { printf("\"%s\" from class\n", $message);
$this->getEventManager()->trigger(__FUNCTION__, $this, $message ]);
}
Ta metoda pobiera menedżera zdarzeń i uruchamia / wyzwala zdarzenia z nim związane.
Następnym krokiem jest utworzenie instancji Greeter class i dołącz detektor do swojej metody, 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);
});
Wywołanie zwrotne detektora wyświetla tylko nazwę zdarzenia, cel i podane parametry.
Pełna lista Greeter.php wygląda następująco -
<?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");
Teraz uruchom aplikację w wierszu poleceń php Greeter.php a wynik będzie następujący -
"Hello" from class
"Hello" from class
"greet" event of class "Greeter" is called. The parameter supplied is ["Hello"]
Powyższa przykładowa aplikacja wyjaśnia tylko podstawy menedżera wydarzeń. Menedżer wydarzeń zapewnia wiele bardziej zaawansowanych opcji, takich jakListener Priority, Custom Callback Prototype / Signature, Short Circuiting, itd. Menedżer zdarzeń jest szeroko stosowany we frameworku Zend MVC.
Zend Framework zapewnia potężny system modułów. System modułowy składa się z trzech komponentów. Są następujące -
Module Autoloader- Moduł Autoloader jest odpowiedzialny za lokalizowanie i ładowanie modułów z różnych źródeł. Może ładować moduły spakowane jakoPhar archivestakże. Implementacja modułu Autoloader znajduje się pod adresem myapp / vendor / zendframework / zend-loader / src / ModuleAutoloader.php.
Module Manager- Gdy moduł Autoloader zlokalizuje moduły, menedżer modułów odpala sekwencję zdarzeń dla każdego modułu. Implementacja Menedżera modułów znajduje się pod adresem myapp / vendor / zendframework / zendmodulemanager / src / ModuleManager.php.
Module Manager Listeners- Mogą być dołączane do zdarzeń uruchamianych przez Menedżera modułów. Dołączając do wydarzeń menedżera modułów, mogą robić wszystko, od rozwiązywania i ładowania modułów do wykonywania złożonej pracy dla każdego modułu.
System modułów sieciowych MVC
Aplikacja internetowa MVC w Zend Framework jest zwykle napisana jako Moduły. Pojedyncza witryna internetowa może zawierać jeden lub więcej modułów pogrupowanych według funkcjonalności. Zalecana struktura modułu zorientowanego na MVC jest następująca -
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>
Struktura jest taka sama, jak omówiona w poprzednim rozdziale, ale tutaj jest ogólna. Plikautoload_ files może być użyty jako domyślny mechanizm automatycznego ładowania klas dostępnych w module bez korzystania z zaawansowanego Module Manager dostępne w zend-modulemanager.
autoload_classmap.php - Zwraca tablicę nazw klas i odpowiadających im nazw plików.
autoload_function.php- Zwraca wywołanie zwrotne PHP. Może to wykorzystywać klasy zwrócone przez autoload_classmap.php.
autoload_register.php - Rejestruje wywołanie zwrotne PHP, które jest zwracane przez autoload_function.php.
Te pliki do automatycznego ładowania nie są wymagane, ale zalecane. W aplikacji szkieletowej nie używaliśmy rozszerzeniaautoload_ files.
Klasa modułu
Należy nazwać klasę Module Module a przestrzeń nazw klasy modułu powinna być Module name. Pomoże to Zend Framework w łatwym rozwiązaniu i załadowaniu modułu. PlikApplication kod modułu w aplikacji szkieletowej (myapp), myapp / module / Application / src / Module.php wygląda następująco -
namespace Application;
class Module {
const VERSION = '3.0.2dev';
public function getConfig() {
return include __DIR__ . '/../config/module.config.php';
}
}
Menedżer modułów Zend Framework wywoła rozszerzenie getConfig() działa automatycznie i wykona niezbędne kroki.
W tym rozdziale zrozumiemy strukturę aplikacji Zend Framework. Strukturamyapp aplikacja jest następująca -
├── 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
Aplikacja Zend Framework składa się z różnych folderów. Są następujące -
Application- Ten katalog zawiera Twoją aplikację. Będzie zawierał system MVC, a także konfiguracje, używane usługi i plik bootstrap.
Config - Ten katalog zawiera pliki konfiguracyjne aplikacji.
Data - Ten katalog zapewnia miejsce do przechowywania danych aplikacji, które są nietrwałe i prawdopodobnie tymczasowe.
Module - Moduły pozwalają programiście zgrupować zestaw powiązanych kontrolerów w logicznie zorganizowaną grupę.
Public- To jest katalog główny aplikacji. Uruchamia aplikację Zend. Zawiera również zasoby aplikacji, takie jak JavaScript, CSS, obrazy itp.
Vendor - Ten katalog zawiera zależności kompozytora.
Struktura modułów aplikacji
To jest główny katalog Twojej aplikacji. Zend Framework 2 wprowadza potężny i elastyczny system modułów do efektywnej organizacji aplikacji. PlikApplicationmoduł aplikacji szkieletowej (myapp) zapewnia ładowanie, konfigurację błędów i routingu dla całej aplikacji. StrukturaApplication moduł jest jak pokazano poniżej -
├── 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
Omówmy szczegółowo każdy z tych katalogów modułów -
Application- To jest katalog główny modułu. Nazwa folderu będzie zgodna z nazwą modułu, a nazwa jest również używana jako przestrzeń nazw PHP dla wszystkich klas zdefiniowanych w module. Będzie zawierał system MVC, a także konfiguracje, używane usługi i plik bootstrap.
Config - Niezależna konfiguracja modułu.
Src - Główna logika biznesowa aplikacji.
View- Zawiera pliki projektu / prezentacji (HTML). Na przykład index.phtml.
src/Module.php- To serce modułu. Działa jako „kontroler frontowy” modułu. Proces Zendsrc/Module.php plik przed przetworzeniem jakichkolwiek klas PHP w tym module.
Application/config/module.config.php - Jest zaimplementowany do konfiguracji routera i automatycznego ładowania plików.
Application/view/layout- Układy reprezentują wspólne części wielu widoków. Na przykład nagłówek i stopka strony. Domyślnie układy powinny być przechowywane wviews/layoutsfolder.
Wszystkie moduły mają taką samą lub podobną strukturę jak powyższy moduł aplikacji .
W tym rozdziale nauczymy się, jak stworzyć moduł oparty na MVC w Zend Framework. Stwórzmy moduł o nazwie asTutorial aby zrozumieć proces tworzenia modułu.
Utwórz nową klasę PHP o nazwie Module wewnątrz katalogu –myapp / module / Tutorial / src / i zaimplementuj interfejs ConfigProviderInterface.
Zestaw Tutorial jako przestrzeń nazw dla Module klasa.
Napisz funkcję publiczną getConfig w Module class i zwróć plik konfiguracyjny dla Tutorial Moduł.
Kompletny kod dla Module klasa jest następująca -
<?php
namespace Tutorial;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
class Module implements ConfigProviderInterface {
public function getConfig() {
return include __DIR__ . '/../config/module.config.php';
}
}
Skonfiguruj Tutorial moduł w composer.json pod autoload sekcji przy użyciu następującego kodu.
"autoload": {
"psr-4": {
"Application\\": "module/Application/src/",
"Tutorial\\": "module/Tutorial/src/"
}
}
Zaktualizuj aplikację za pomocą kompozytora update polecenie, jak pokazano poniżej.
composer update
Plik composer polecenie dokona niezbędnych zmian w aplikacji i wyświetli dzienniki w wierszu polecenia, jak pokazano poniżej -
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
Utwórz plik konfiguracyjny modułu „module.config.php” w /config/ z następującym kodem -
<?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',],
],
];
Plik konfiguracyjny składa się z trzech części i są one następujące -
Controller configuration - Określ kontrolery dostępne w module.
Routing configuration - Określ, w jaki sposób kontrolery w module mają być przekształcane w adresy URL.
View configuration - Określ konfigurację związaną z wyświetlaniem silnika, taką jak lokalizacja widoków itp.
Skonfiguruj Tutorial moduł w pliku konfiguracyjnym na poziomie aplikacji - myapp / config / modules.config.php.
return ['Zend\Router', 'Zend\Validator', 'Application', 'Tutorial'];
Uruchom aplikację, wykonując composer serve w katalogu głównym folderu aplikacji.
Pomyślnie dodaliśmy nowy moduł, ale nadal musimy dodać Controller, Routing i Views aby pomyślnie uruchomić Tutorial moduł.
Jak wspomniano wcześniej, plik controllerodgrywa ważną rolę w Zend MVC Framework. Wszystkie strony internetowe w aplikacji muszą być obsługiwane przez kontroler.
W Zend MVC Framework kontrolery są obiektami implementującymi - Zend / Stdlib / DispatchableInterface. PlikDispatchableInterface ma jedną metodę, dispatch, który pobiera Request obiekt jako wejście, wykonaj jakąś logikę i zwraca Response obiekt jako wyjście.
dispatch(Request $request, Response $response = null)
Prosty przykład obiektu kontrolera zwracającego „Hello World” jest następujący:
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!");
}
}
Plik DispatchableInterfacejest podstawowa i potrzebuje wielu innych interfejsów do pisania kontrolerów wysokiego poziomu. Oto niektóre z takich interfejsów -
InjectApplicationEventInterface - Służy do wstrzykiwania zdarzeń (Zend EventManager)
ServiceLocatorAwareInterface - Służy do lokalizowania usług (Zend ServiceManager)
EventManagerAwareInterface - Służy do zarządzania wydarzeniami (Zend EventManager)
Mając to na uwadze, Zend Framework dostarcza wiele gotowych kontrolerów implementujących te interfejsy. Najważniejsze kontrolery opisano poniżej.
AbstractActionController
AbstractActionController (Zend / Mvc / Controller / AbstractActionController) jest najczęściej używanym kontrolerem w Zend MVC Framework. Posiada wszystkie niezbędne funkcje do napisania typowej strony internetowej. Pozwala trasom (routing dopasowuje adres URL żądania do kontrolera i jedną z jego metod) na dopasowanie adresuaction. Po dopasowaniu metoda nazwana na podstawie akcji zostanie wywołana przez kontroler.
Na przykład, jeśli trasa test jest dopasowana i trasa, test zwroty hello do działania, a następnie helloAction zostanie wywołana metoda.
Napiszmy nasze TutorialController używając AbstractActionController.
Utwórz nową klasę PHP o nazwie TutorialController poprzez rozszerzenie AbstractActionController i umieść go w module/Tutorial/src/Controller/ informator.
Ustaw Tutorial\Controller jako przestrzeń nazw.
Napisać indexAction metoda.
Zwróć ViewModel obiekt z indexActionmetoda. PlikViewModel obiekt służy do wysyłania danych ze sterownika do podglądu silnika, o czym przekonamy się w kolejnych rozdziałach.
Pełna lista kodów jest następująca -
?php
namespace Tutorial\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class TutorialController extends AbstractActionController {
public function indexAction() {
return new ViewModel();
}
}
Pomyślnie dodaliśmy nowy TutorialController.
AbstractRestfulController
AbstractRestfulController (Zend \ Mvc \ Controller \ AbstractRestfulController) sprawdza HTTP method przychodzącego żądania i dopasowuje akcję (metodę) z uwzględnieniem metod HTTP
Na przykład żądanie z metodą GET HTTP jest zgodne z getList() metoda lub get() metoda, jeśli id parametr znajduje się w żądaniu.
AbstractConsoleController
AbstractConsoleController (Zend \ Mvc \ Controller \ AbstractConsoleController) jest podobny do AbstractActionController, z wyjątkiem tego, że działa tylko w środowisku konsoli zamiast w przeglądarce.
Mapy tras Request URIdo metody konkretnego administratora. W tym rozdziale zobaczymy, jak zaimplementować trasy w Zend Framework.
Ogólnie każdy identyfikator URI składa się z trzech części -
- Segment nazwy hosta,
- Segment ścieżki i
- Segment zapytania.
Na przykład w URI / URL - http://www.example.com/index?q=data, www.example.com to segment nazwy hosta, index to segment ścieżki, a q=datato segment zapytania. Ogólnie rzecz biorąc, routing sprawdzaPage segmentprzeciwko zestawowi ograniczeń. Jeśli jakieś ograniczenie pasuje, zwraca zestaw wartości. Jedną z głównych wartości jest kontroler.
Routing sprawdza również segment hosta, segment zapytania, metody żądania HTTP, żądania nagłówków HTTP itp. W określonej sytuacji.
Route & RouteStack
Trasa jest głównym obiektem routingu. Zend Framework ma specjalny interfejs dla obiektu trasy,RouteInterface. Wszystkie obiekty trasy muszą implementować interfejs RouteInterface. Pełna lista interfejsu RouteInterface jest następująca -
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 = []);
}
Główną metodą jest match. Ta metoda dopasowania sprawdza dane żądanie pod kątem zdefiniowanego w nim ograniczenia. Jeśli zostanie znalezione jakiekolwiek dopasowanie, zwracaRouteMatchobiekt. Ten obiekt RouteMatch zawiera szczegóły dopasowanego żądania jako parametry. Te parametry można wyodrębnić zRouteObject używając getParams metoda.
Pełna lista RouteObject jest następująca -
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);
}
Ogólnie rzecz biorąc, typowa aplikacja MVC ma wiele tras. Każda z tych tras zostanie przetworzona w kolejności LIFO, a pojedyncza trasa zostanie dopasowana i zwrócona. Jeśli żadna trasa nie zostanie dopasowana / zwrócona, aplikacja zwraca błąd „Nie znaleziono strony”. Zend Framework zapewnia interfejs do przetwarzania tras,RouteStackInterface. Ten RouteStackInterface ma opcję dodawania / usuwania tras.
Pełna lista RouteStackInterface jest następująca -
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);
}
Framework Zend zapewnia dwie implementacje RouteStack interfejs i są one następujące -
- SimpleRouteStack
- TreeRouteStack
Typ tras
Framework Zend dostarcza wiele gotowych obiektów tras dla wszystkich sytuacji w przestrzeni nazw "Zend \ Mvc \ Router \ Http". Wystarczy wybrać i użyć odpowiedniego obiektu trasy do danej sytuacji.
Dostępne trasy są następujące -
Hostname - Służy do dopasowywania części hosta identyfikatora URI.
Literal - Służy do dopasowania dokładnego identyfikatora URI.
Method - Służy do dopasowania metody HTTP żądania przychodzącego.
Part - Służy do dopasowania części segmentu ścieżki URI przy użyciu logiki niestandardowej.
Regex - Służy do dopasowania segmentu ścieżki URI za pomocą wzorca Regex.
Schema - Używany do dopasowania schematu URI, takiego jak http, https itp.
Segment - Służy do dopasowania ścieżki URI przez podzielenie jej na wiele segmentów.
Zobaczmy, jak napisać najczęściej używany literał i segment Route. Trasy są zwykle określone w pliku konfiguracyjnym każdego modułu -module.config.php.
Dosłowna trasa
Zazwyczaj zapytania dotyczące tras są wykonywane w kolejności LIFO. Trasa literalna służy do dokładnego dopasowania ścieżki identyfikatora URI.
Jest zdefiniowany jak pokazano poniżej -
$route = Literal::factory(array(
'route' => '/path',
'defaults' => array('controller' => 'Application\Controller\IndexController',
'action' => 'index',),
));
Powyższa trasa jest zgodna z /path w adresie URL żądania i zwraca index jako action i IndexController jako kontroler.
Trasa segmentu
Segmentowana trasa jest używana zawsze, gdy Twój adres URL ma zawierać zmienne parametry.
Opisano to jak podano poniżej -
$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',),
));
Tutaj segmenty są oznaczone dwukropkiem, po którym następują znaki alfanumeryczne. Jeśli pozostawisz segment, który jest opcjonalny, jest on ujęty w nawiasy. Z każdym segmentem mogą być skojarzone ograniczenia. Każde ograniczenie jest wyrażeniem regularnym.
Konfigurowanie trasy w module samouczka
Dodajmy trasę segmentową w naszym module Tutorial. Zaktualizuj plik konfiguracyjny modułu samouczka -module.config.php dostępne o 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',],
],
];
Pomyślnie dodaliśmy routing dla naszego Tutorialmoduł. Jesteśmy tylko o krok do przodu w ukończeniu naszego modułu samouczka. Musimy dodaćView dla naszego modułu, o którym dowiemy się w następnym rozdziale.
Warstwa widoku to warstwa prezentacji aplikacji MVC. Oddziela logikę aplikacji od logiki prezentacji. W typowej aplikacji internetowej PHP cała logika biznesowa i projekt są mieszane. Mieszanie umożliwia szybszy rozwój w małym projekcie. Ale zawodzi żałośnie w dużym projekcie, w którym zaangażowanych jest wiele architektury wysokiego poziomu. Aby zmienić projekt aplikacji internetowej, programista musi również popracować nad logiką biznesową. Może to mieć katastrofalne skutki, powodując złamanie logiki biznesowej.
Zend Framework zapewnia dobrze przemyślaną, przejrzystą, elastyczną i rozszerzalną warstwę widoku. Warstwa widoku jest dostępna jako osobny moduł,Zend/View i dobrze integruje się z Zend/Mvcmoduł. Warstwa widoku Zend jest podzielona na wiele komponentów, które dobrze ze sobą współdziałają.
Jego różne składniki są następujące -
Variables Containers - Przechowuje dane warstwy widoku.
View Models - Posiada zmienne pojemniki i szablon projektu.
Renderers - Przetwarzaj dane i szablon z View Model i wyprowadź reprezentację projektu, być może ostateczny wynik HTML.
Resolvers - Rozpoznaje szablon dostępny w modelu widoku w taki sposób, aby moduł renderujący mógł je wykorzystać.
View (Zend\View\View) - Mapuje żądanie do modułu renderującego, a następnie moduł renderujący do odpowiedzi.
Rendering Strategies - Używany przez View do mapowania żądania do renderera.
Response Strategies - Używany przez View do mapowania renderera na odpowiedź.
Warstwa widoku, View przetwarza plik ViewModel, rozwiązuje szablon przy użyciu pliku Resolver, wyrenderuj go za pomocą Rendering Strategy i na koniec wyprowadza go za pomocą Response Renderer.
Wyświetl konfigurację warstw
Podobnie jak kontroler, warstwę widoku można skonfigurować w pliku konfiguracyjnym modułu o nazwie - module.config.php. Główna konfiguracja polega na określeniu, gdzie będą umieszczane szablony. Można to osiągnąć dodając następującą konfigurację w „module.config.php”.
'view_manager' => [
'template_path_stack' => ['tutorial' => __DIR__ . '/../view',],
]
Domyślnie warstwa widoku ma domyślne zachowanie dla wszystkich swoich składników. Na przykład plikViewModelrozwiązuje nazwę szablonu akcji kontrolera w katalogu głównym szablonów za pomocą reguły „nazwa-modułu-małymi literami / nazwa-kontrolera-małych liter / nazwa-akcji-małych liter”. Można to jednak zastąpić przezsetTemplate() Metoda ViewModel.
Kontrolery i warstwa widoku
Domyślnie kontroler nie musi przesyłać żadnych danych do warstwy widoku. Wystarczy napisać szablon w odpowiednim miejscu.
Na przykład w naszym przykładzie TutorialController, szablon należy umieścić w myapp/module/Tutorial/view/tutorial/tutorial/index.phtml. Plikindex.phtmlodwołuje się do szablonu opartego na PHP i będzie on renderowany przez PHPRenderer. Istnieją inne renderery, takie jakJsonRenderer dla json wyjście i FeedRenderer dla rss i atom wynik.
Pełna lista jest następująca -
<?php
namespace Tutorial\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class TutorialController extends AbstractActionController {
public function indexAction() {
}
}
Szablon aplikacji Zend
<div class = "row content">
<h3>This is my first Zend application</h3>
</div>
Wreszcie pomyślnie ukończyliśmy Tutorial moduł i możemy uzyskać do niego dostęp przez url - http://localhost:8080/tutorial.
Przekazywanie danych do warstwy widoku
Najprostszym sposobem wysłania danych do warstwy widoku jest użycie ViewModelargumenty. ZmienionyindexAction metoda jest następująca -
public function indexAction() {
$view = new ViewModel([ 'message' => 'Hello, Tutorial' ]); return $view;
}
Teraz zmień index.phtml plik w następujący sposób -
<div class = "row content">
<h3>This is my first Zend application</h3>
<h4><?php echo $this->message?></h4>
</div>
Zobacz pomocników
Pomocnik widoku służy do pisania małych, atomowych funkcji, które mają być używane w szablonach. Framework Zend zapewnia interfejs Zend \ View \ Helper \ HelperInterface do pisania standardowych helperów.
HelperInterface ma tylko dwie metody,
setView() - Ta metoda akceptuje instancję / implementację Zend \ View \ Renderer \ RendererInterface.
getView() - Służy do pobierania tej instancji.
Pełna lista kodów HelperInterface wygląda następująco -
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();
}
Aby użyć pomocnika w skrypcie widoku, uzyskaj do niego dostęp za pomocą $this->helperName().
Wbudowani pomocnicy
Zend Framework zapewnia wiele wbudowanych funkcji pomocniczych do różnych celów. Niektóre z pomocników widoku dostępnych wzend-mvc są następujące -
URL
Pomocnik adresu URL służy do generowania adresów URL zgodnych z trasami zdefiniowanymi w aplikacji.
Definicja pomocnika adresu URL to -
$this->url($name, $params, $options, $reuseMatchedParameters)
Na przykład w module samouczka trasa nosi nazwę tutorial i ma dwa parametry action i id. Możemy użyć pomocnika URL do wygenerowania dwóch różnych adresów URL, jak pokazano poniżej -
<a href = "<? = $this->url('tutorial'); ?>">Tutorial Index</a>
<a href = "<? = $this->url('tutorial', ['action' => 'show', 'id' =>10]); ?>">
Details of Tutorial #10
</a>
Wynik będzie następujący -
<a href = "/tutorial">Tutorial Index</a>
<a href = "/tutorial/show/10"> Details of Tutorial #10</a>
Symbol zastępczy
Pomocnik symbolu zastępczego służy do utrwalania zawartości między skryptami widoku i instancjami widoku. Zapewnia opcję początkowego ustawienia danych, a następnie wykorzystania ich na późniejszych etapach.
Na przykład możemy ustawić, powiedzmy company name a następnie używaj go we wszystkich innych miejscach.
<?php $this->placeholder('companyname')->set("TutorialsPoint") ?>
<?= $this->placeholder('companyname'); ?>
Symbol zastępczy zapewnia niektóre z zaawansowanych opcji generowania złożonej zawartości z tablicy i obiektów PHP. Ma również opcję przechwytywania określonej sekcji samego szablonu.
Na przykład poniższy kod przechwytuje wynik szablonu między i przechowuje go w pliku productlist symbol zastępczy.
Class – Product
class Product {
public $name;
public $description;
}
Controller
$p1 = new Product();
$p1->name = 'Car'; $p1->description = 'Car';
$p2 = new Product(); $p2->name = 'Cycle';
$p2->description = 'Cycle'; $view = new ViewModel(['products' => $products]);
Template
<!-- start capture -->
<?php $this->placeholder('productlist')->captureStart();
foreach ($this->products as $product): ?>
<div>
<h2><?= $product->name ?></h2> <p><?= $product->description ?></p>
</div>
<?php endforeach; ?>
<?php $this->placeholder('productlist')->captureEnd() ?> <!-- end capture --> <?= $this->placeholder('productlist') ?>
Result
<div class = "foo">
<h2>Car</h2>
<p>Car</p>
</div>
<div class = "foo">
<h2>Cycle</h2>
<p>Cycle</p>
</div>
Doctype
Pomocnik Doctype służy do generowania różnych typów dokumentów HTML. Jest to konkretna implementacjaPlaceholderpomocnik. Doctype można ustawić w pliku bootstrap i pliku konfiguracyjnym.
Podstawowe użycie pokazano poniżej -
Application Bootstrap file
use Zend\View\Helper\Doctype;
$doctypeHelper = new Doctype(); $doctypeHelper->doctype('XHTML5');
Module Configuration
// module/Application/config/module.config.php:
return [
/* ... */
'view_manager' => [
'doctype' => 'html5',
/* ... */
],
];
Template
<?php echo $this->doctype() ?>
HeadTitle
Helper HeadTitle służy do generowania elementu tytułu HTML. Jest to konkretna realizacjaPlaceholderpomocnik. Zend zapewnia opcję ustawienia tytułu w pliku konfiguracyjnym modułu i można go ustawić na dowolnym poziomie, takim jak witryna, moduł, kontroler, akcja itp. Częściowy kod tytułu nagłówka jest następujący -
Module
headTitleHelper->append($action);
$headTitleHelper->append($controller);
$headTitleHelper->append($module);
$headTitleHelper->append($siteName);
Template
<?= $this->headTitle() ?>
Result
action - controller - module - Zend Framework
HeadMeta
Helper HeadMeta służy do generowania metatagów html. Jest to konkretna implementacja pomocnika Placeholder.
Template -
<?php
$this->headMeta()->appendName('keywords', 'turorialspoint, zend framework, php');
echo $this->headMeta()
?>
Result
<meta name = "keywords" content = "tutorialspoint, zend framework, php" />
HeadLink
Helper HeadLink służy do generowania linków html w celu włączenia zasobów zewnętrznych. Jest to konkretna implementacja pomocnika Placeholder.
Template
<?php
// setting links in a view script:
$this->headLink(['rel' => 'icon', 'href' => '/img/favicon.ico'], 'PREPEND')
->appendStylesheet('/styles/site.css')
->prependStylesheet('/styles/mystyle.css', 'screen', true, ['id' => 'mystyle']);
// rendering the links from the layout:
echo $this->headLink();
?>
Result
<link href = "/styles/mystyle.css" media = "screen" rel = "stylesheet"
type = "text/css" id = "mystyle">
<link href = "/img/favicon.ico" rel = "icon">
<link href = "/styles/site.css" media = "screen" rel = "stylesheet" type = "text/css">
HeadStyle
Pomocnik HeadStyle służy do generowania wbudowanych stylów CSS. Jest to konkretna implementacja pomocnika Placeholder.
Template
<?php $this->headStyle()->appendStyle($styles); ?> <?php echo $this->headStyle() ?>
HeadScript
HeadScript służy do generowania skryptu wbudowanego lub do dołączania skryptów zewnętrznych. Jest to konkretna implementacja pomocnika Placeholder.
Template
<? $this->headScript()->appendFile(‘/js/sample.js’);?> <?php echo $this->headScript() ?>
InlineScript
InlineScript służy do generowania skryptu w sekcji head i body szablonu html. Pochodzi z HeadScript.
HTMLList
HTMLList służy do generowania uporządkowanej i nieuporządkowanej listy. Definicja HTMLList jest następująca -
Definition
htmlList($items, $ordered, $attribs, $escape)
Template
$items = [ '2015', ['March', 'November'], '2016', ]; echo $this->htmlList($items);
Result
<ul>
<li>2015
<ul>
<li>March</li>
<li>November</li>
</ul>
</li>
<li>2016</li>
</ul>
Cykl
Cykl służy do generowania alternatyw w środowisku pętli. Posiada funkcję assign, next i prev.
Controller
$view = new ViewModel(['message' => 'Hello, Tutorial', 'data' => array('One', 'Two')]);
Template
<?php $this->cycle()->assign(['#F0F0F0', '#FFF'], 'colors'); ?> <table> <?php foreach ($this->data as $datum): ?> <tr style = "background-color: <?= $this->cycle()->setName('colors')>next() ?>">
<td><?= $this->escapeHtml($datum) ?></td>
</tr>
<?php endforeach ?>
</table>
Result
<table>
<tr style = "background-color: #F0F0F0">
<td>One</td>
</tr>
<tr style = "background-color: #FFF">
<td>Two</td>
</tr>
</table>
Oto kilka innych ważnych wbudowanych pomocników -
BasePath - BasePath służy do generowania ścieżki do folderu publicznego katalogu głównego aplikacji.
Partial - Częściowe jest używane do renderowania określonego szablonu w jego własnym zakresie zmiennych.
PartialLoop - PartialLoop jest podobny do Partial, ale używany w środowisku zapętlonym.
Identity - Tożsamość służy do pobierania tożsamości zalogowanego użytkownika z usługi uwierzytelniania.
JSON- JSON jest używany w spokojnym środowisku, w którym dane wyjściowe są w formacie JSON. Emituje odpowiedni nagłówek HTTP i wyłącza koncepcję układu.
W Zend Framework wciąż dostępnych jest wiele pomocników, takich jak i18n helper, form helpers, pagination helpers, navigation helpersitp.
Tworzenie pomocników widoku
Zend Framework zapewnia wbudowany AbstractHelper realizowanie HelperInterface napisać pomocników widoku.
Kroki związane z pisaniem nowego pomocnika są następujące -
Step 1 - Rozszerz klasę Zend \ View \ Helper \ AbstractHelper.
Step 2 - Zastąp __invoke() funkcjonować.
Step 3 - Ustaw konfigurację w module.config.php file.
Step 4 - Użyj pomocnika widoku w skryptach widoku.
Stwórzmy teraz plik TestHelper
Utwórz folder pomocnika pod adresem myapp/module/Tutorial/src/View directory. pisaćTestHelper wewnątrz katalogu Helpera, TestHelper.php.
Pełna lista jest następująca -
<?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');
}
}
Ustaw konfigurację w module.config.php.
'view_helpers' => [
'aliases' => [
'testHelper' => View\Helper\TestHelper::class,
],
'factories' => [
View\Helper\TestHelper::class => InvokableFactory::class,
],
],
Użyj nowo utworzonego pliku TestHelper w about zobacz skrypt.
<?= $this->testHelper() ?>
Układ reprezentuje wspólne części wielu widoków, na przykład nagłówek i stopkę strony. Domyślnie układy powinny być przechowywane wview/layout teczka.
Konfiguracja układu jest zdefiniowana w obszarze view_manager w module.config.php.
Domyślna konfiguracja aplikacji szkieletowej jest następująca -
'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',
),
Tutaj template_mapsłuży do określenia układu. Jeśli układ nie zostanie znaleziony, zwróci błąd. Przyjrzyjmy się głównemu układowi aplikacji szkieletowej.
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>
Kiedy analizujesz układ, głównie używa on pomocników widoku, które omówiliśmy w poprzednim rozdziale. Gdy przyjrzymy się bliżej, układ używa specjalnej zmiennej,$this->content. Ta zmienna jest ważna, ponieważ zostanie zastąpiona przez skrypt widoku (szablon) aktualnie żądanej strony.
Tworzenie nowego układu
Stwórzmy nowy układ dla naszego modułu Tutorial.
Na początek stwórzmy plik tutorial.css file w katalogu „public / css”.
body {
background-color: lightblue;
}
h1 {
color: white;
text-align: center;
}
Utwórz nowy plik układu newlayout.phtmlw / myapp / module / Tutorial / view / layout / i skopiuj zawartość z istniejącego układu. Następnie dodajtutorial.css arkusz stylów przy użyciu HeadLink helper w sekcji nagłówka układu.
<?php echo $this->headLink()->appendStylesheet('/css/tutorial.css');?>
Dodaj nowy about łącze w sekcji nawigacji za pomocą URL pomocnik.
<li><a href = "<?= $this->url('tutorial', ['action' => 'about']) ?>">About</a></li>
Ta strona układu jest wspólna dla aplikacji modułu samouczka. Zaktualizujview_manager sekcji pliku konfiguracyjnego modułu samouczka.
'view_manager' => array(
'template_map' => array(
'layout/layout' => __DIR__ . '/../view/layout/newlayout.phtml'),
'template_path_stack' => array('tutorial' => __DIR__ . '/../view',),
)
Dodaj aboutAction funkcja w TutorialController.
public function aboutAction() {
}
Dodaj about.phtml w myapp / module / Tutorial / view / tutorial / tutorial / z następującą zawartością.
<h2>About page</h2>
Teraz możesz wreszcie uruchomić aplikację - http://localhost:8080/tutorial/about.
W tym rozdziale omówimy różne modele i bazę danych Zend Framework.
Modele w Zend Framework
Model definiuje logiczną reprezentację danych aplikacji. Na przykład w aplikacji koszyka na zakupy - modelami są Produkt, Klient, Koszyk i Zamówienia. Definiują właściwości jednostki, którą posiada. Niektóre koncepcje modeli są następujące -
Kontrolerzy komunikują się z modelami i proszą ich o pobranie potrzebnych informacji. Te pobrane informacje są następnie przekazywane przez kontroler do widoku. Wreszcie, View wyrenderuje model jako dane prezentacyjne użytkownika.
Bardzo rzadko model wchodzi w interakcję bezpośrednio z widokiem, ale czasami może się to zdarzyć.
Modelki mogą rozmawiać ze sobą i nie są samodzielne. Mają ze sobą relacje. Te relacje ułatwiają i przyspieszają uzyskiwanie informacji przez kontroler, ponieważ nie musi on wchodzić w interakcje z różnymi modelami; modele mogą to zrobić samodzielnie.
Przyjrzyjmy się prostemu modelowi - MyModel
<?php
namespace Tutorial\Model;
class Book {
public $id; public $author;
public $title;
}
Baza danych w Zend Framework
Framework Zend zapewnia prostą i bogatą w funkcje klasę Zend \ Db \ TableGateway \ TableGateway do znajdowania, wstawiania, aktualizowania i usuwania danych z tabeli bazy danych.
Zobaczmy, jak podłączyć MySqlservice poprzez sterownik PHP PDO w frameworku Zend, wykonując następujące kroki.
Krok 1: Utwórz bazę danych w MySQL
Utwórz bazę danych tutorialsna lokalnym serwerze MySQL. Możemy użyćphpmyadminlub inne narzędzia GUI MySQL przeznaczone do tego celu. UżyjmyMySQL clientw wierszu polecenia. Połącz się z serwerem mysql i uruchom następujące polecenie, aby utworzyć pliktutorial Baza danych.
create database tutorials
Krok 2: Utwórz tabelę w bazie danych samouczków
Stwórzmy teraz bazę danych book w tutorials db za pomocą następującego polecenia 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)
);
Krok 3: Wypełnij dane w tabeli książek
Wypełnij booktabela z przykładowymi danymi. Użyj następującego polecenia 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');
Krok 4: Zaktualizuj połączenie z bazą danych
Zaktualizuj globalny plik konfiguracyjny, który jest - myapp / config / autoload / global.php, wprowadzając niezbędne informacje o dysku bazy danych.
<?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',
),
),
);
Krok 5: Zaktualizuj poświadczenia bazy danych
Zaktualizuj referencje bazy danych w lokalnym pliku konfiguracyjnym, czyli - myapp / config / autoload / local.php. W ten sposób możemy oddzielić poświadczenia połączenia z lokalną i aktywną bazą danych.
<?php
return array(
'db' => array(
'username' => '<user_name>',
'password' => '<password>',
),
);
Krok 6: Utwórz model książki
Stwórzmy Model, Book w naszym module srcinformator. Ogólnie modele są zgrupowane w folderze Model - /myapp/module/Tutorial/src/Model/Book.php.
<?php
namespace Tutorial\Model;
class Book {
public $id;
public $author; public $title;
}
Krok 7: Zaimplementuj tablicę exchangeArray w modelu książki
Plik TableGateway współdziała z modelem za pośrednictwem exchangeArrayfunkcjonować. Standardowym argumentem funkcji exchangeArray jest zestaw wyników bazy danych przechowywany jako tablica PHP. UżywającexchangeArrayfunction, właściwość modelu można łatwo zsynchronizować z odpowiednią tabelą bazy danych.
Zaktualizuj model, Book jak pokazano poniżej -
<?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;
}
}
Krok 8: Użyj TableGateway, aby pobrać książkę
Utwórz zajęcia, BookTableaby pobrać informacje o książce z bazy danych. Utwórz klasę BookTable wModel sam folder.
<?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;
}
}
Użyliśmy select()metody klasy TableGateway w celu pobrania informacji o książce z bazy danych. Ale nie użyliśmy żadnego odniesienia do tabeli -bookw kodzie. TableGateway ma charakter ogólny i może pobierać dane z dowolnej tabeli przy użyciu określonej konfiguracji. Zwykle te konfiguracje są wykonywane wmodule.config.php plik, który omówimy w kolejnych krokach.
Krok 9: Skonfiguruj klasę BookTable
Zaktualizuj moduł samouczka, Module.php z getServiceConfig() metoda.
<?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);
},
],
];
}
}
Tutaj zarejestrowaliśmy BookTableza pomocą menedżera usług. Klasa BookTable służy do pobierania informacji o książce i rejestrując ją, możemy uzyskać do niej dostęp w dowolnym miejscu. Ponieważ zarejestrowane usługi są udostępniane, zwiększają wydajność, zmniejszają zużycie pamięci itp.
Kolejna pozycja, Klasa Model \ BookTableGateway :: jest obiektem TableGateway specjalizującym się w Book model i jest zależnością BookTable.
Krok 10: Zaktualizuj konfigurację TutorialController
Potrzebujemy BookTableusługa w kontrolerze samouczka, aby pobrać informacje o książce. Aby uzyskać usługę BookTable, zarejestruj ją jako zależność konstruktora w TutorialController.
Ta zależność od konstruktora pomaga uzyskać usługę BookTable, gdy sam kontroler jest na etapie inicjalizacji. Zaktualizuj sekcję kontrolera konfiguracji modułu samouczka,module.config.php jak pokazano niżej.
'controllers' => [
'factories' => [
Controller\TutorialController::class => function($container) {
return new Controller\TutorialController(
$container->get(Model\BookTable::class)
);
},
],
],
Krok 11: Zaktualizuj kontroler samouczka
Odbywa się to poprzez przestrzeganie następujących trzech kroków.
- Dodaj konstruktora z BookTable jako argumentem.
private $table;
public function __construct(BookTable $table) { $this->table = $table;
}
Pobierz informacje o książce za pomocą BookTable's fetchAll() metody i zarejestruj ją w widoku.
public function indexAction() {
$view = new ViewModel([
'data' => $this->table->fetchAll(), ]); return $view;
}
Wyświetl informacje o książce w skrypcie widoku.
<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>
Krok 12: Uruchom aplikację
Sprawdź aplikację, uruchamiając - http://localhost:8080/tutorial.
Jak omówiono w poprzednim rozdziale, framework Zend zapewnia ogólny sposób dostępu do bazy danych przy użyciu Database Driverpojęcie. Praca z bazą danych zależy wyłącznie od informacji o sterowniku, więc połączenie z inną bazą danych wymaga tylko zmiany informacji o sterowniku.
Zmieńmy teraz book przykład, aby połączyć się z postgresql bazy danych z następującymi krokami.
Step 1 - Utwórz bazę danych, samouczki w lokalnej bazie danych postgresql za pomocą następującego polecenia -
CREATE DATABASE tutorials
Step 2 - Dodaj bookstół. Przejdź do nowej bazy danych i wykonaj skrypt tworzenia tabeli.
\c tutorials
CREATE TABLE book (
id SERIAL NOT NULL,
author varchar(100) NOT NULL,
title varchar(100) NOT NULL,
PRIMARY KEY (id)
);
Step 3 - Dodaj informacje o przykładowej książce za pomocą następującego skryptu -
INSERT INTO book (author, title) VALUES ('Dennis Ritchie', 'C Programming');
INSERT INTO book (author, title) VALUES ('James gosling', 'Java Programming');
INSERT INTO book (author, title) VALUES ('Rasmus Lerdorf', 'Programming PHP');
Step 4 - Zmień informacje o kierowcy w global.config file.
<?php
return array (
'db' => array (
'driver' => 'Pdo',
'dsn' => 'pgsql:dbname = tutorials;host = localhost',
'driver_options' => array (
),
),
);
Step 5 - Zmień poświadczenia bazy danych w pliku local.config plik.
return array (
'db' => array(
'username' => '<username>',
'password' => '<password>',
),
);
Step 6 - Na koniec uruchom aplikację http://localhost:8080/tutorial. Wynik jest taki sam jak w przypadku aplikacji MySQL.
Zend Framework dostarcza oddzielny komponent, zend-formprzyspieszyć proces tworzenia i walidacji formularzy. Łączy model i warstwę widoku. Zawiera zestaw elementów formularza do tworzenia pełnoprawnego formularza html z predefiniowanych modeli, plikuInputFilter klasy, aby sprawdzić poprawność modelu względem formularza i opcji, aby powiązać dane z formularza z modelem i odwrotnie.
Zainstaluj składnik formularza
Komponent formularza Zend można zainstalować przy użyciu Composer polecenie jak określono poniżej -
composer require zendframework/zend-form
Framework formularzy Zend ma trzy podskładniki do zarządzania formularzami. Są one szczegółowo opisane poniżej -
Elements - Służy do definiowania pojedynczej kontrolki wejściowej HTML odwzorowanej na właściwość w modelu.
Fieldset - Służy do grupowania elementów i innych fieldset w sposób zagnieżdżony.
Form - Służy do tworzenia formularza html i składa się z elementów i zestawów pól.
Formularze Zend są zwykle tworzone w ramach module//src/Form informator.
Przykład
Stwórzmy teraz prosty formularz do dodania bookdo bazy danych. Aby to zrobić, powinniśmy postępować zgodnie z następującymi krokami -
Krok 1: Utwórz BookForm
Utwórz „BookForm.php” w katalogu * myapp / module / Tutorial / src / Form ”. Dodaj następujące zmiany w pliku -
<?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',
),
));
}
}
Plik Form class zapewnia add methodaby zmapować model i odpowiadające mu szczegóły formularza. stworzyliśmyBookForm poprzez rozszerzenie Form class i dodałem szczegóły formularza dla Book Model.
Krok 2: Zaktualizuj model książki Book.php
Zaktualizuj model, ‘Book’ z filtrem i walidacją, jak określono poniżej -
<?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;
}
}
Każdy model powinien implementować InputFilterAwareInterface. InputFilterAwareInterface udostępnia dwie metody,setInputFilter() i getInputFilter().
GetInputFilter służy do pobierania szczegółów walidacji modelu. Framework Zend zapewnia bogaty zestaw filtrów i walidatorów do walidacji formularza. Niektóre z filtrów i walidatorów używanych w modelu książki są następujące:
StripTags - Usuń niechciany kod HTML.
StringTrim - Usuń niepotrzebne odstępy.
StringLength validator - Upewnij się, że użytkownik nie wprowadza więcej znaków niż określony limit.
Krok 3: Zaktualizuj klasę BookTable
Zawierać saveBook metoda dodania książki do bazy danych.
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');
}
}
}
}
Krok 4: Zaktualizuj klasę TutorialController
Dodaj nową akcję addAction do kontrolera samouczka - 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);
}
Plik addAction metoda wykonuje następujące procesy -
Pobiera obiekt żądania.
Sprawdza, czy metoda http żądania to post metoda.
Jeśli metoda http żądania nie jest post, po prostu renderuje szablon, add.phtml
Jeśli metoda http żądania nie jest post, to ustawia inputfilter, pobiera dane żądania i ustawia je w pliku wejściowym.
Sprawdza, czy formularz jest prawidłowy przy użyciu isValid() metoda klasy Form.
Jeśli formularz jest nieprawidłowy, ponownie renderuje szablon, add.phtml
Jeśli formularz jest prawidłowy, zapisuje książkę w bazie danych i przekierowuje na stronę główną.
Krok 5: Dodaj szablon add.phtml
Utwórz szablon - add.phtml w 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();
}
Tutaj renderujemy formularz książki przy użyciu rozszerzenia Form instancja, $form.
Krok 6: Uruchom aplikację
Teraz możemy uruchomić aplikację - http://localhost:8080/tutorial/add.
Form Page
Validate Error Page
Przesyłanie plików jest jedną z głównych koncepcji programowania formularzy. Framework Zend zapewnia wszystkie niezbędne elementy do przesyłania plików przezzend-form i zend-inputfilter składnik.
Klasa FileInput
Komponent zend-inputfilter udostępnia klasę Zend \ InputFilter \ FileInput do obsługi elementu wejściowego pliku html - <input type = 'file' />. PlikFileInputjest podobny do innych filtrów wejściowych z kilkoma wyjątkami. Są następujące -
Ponieważ PHP zapisuje szczegóły przesłanego pliku w formacie $_FILES globalnej tablicy, FileInput gromadzi informacje o przesłanym pliku tylko za pośrednictwem $ _FILES.
Walidację należy przeprowadzić, zanim klasa FileInput przetworzy dane. Zachowanie jest odwrotne do innych filtrów wejściowych.
Zend \ Validator \ File \ UploadFile jest domyślnym używanym walidatorem. PlikUploadFile sprawdza poprawność danych wejściowych pliku.
Aby dodać typ wysyłania pliku do formularza, musimy użyć typu wejściowego File. Częściowy kod jest następujący -
$form->add(array(
'name' => 'imagepath',
'type' => 'File',
'options' => array('label' => 'Picture',),
));
Inną klasą używaną do przesyłania plików jest Zend \ Filter \ File \ RenameUpload. PlikRenameUploadsłuży do przenoszenia przesłanego pliku do wybranej lokalizacji. Klasa częściowa do użycia filtru plików jest następująca -
$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);
Tutaj opcje RenameUpload są następujące -
target - Ścieżka docelowa przesłanego pliku.
randomize - Dodaj losowy ciąg, aby zapobiec powielaniu przesłanego pliku.
use_upload_extension - Dołącz rozszerzenie pliku do przesłanego pliku do celu.
Przesyłanie plików - przykład roboczy
Zmodyfikujmy moduł samouczka i dołączmy funkcję przesyłania zdjęć.
Zmodyfikuj tabelę bazy danych
Dodajmy imagepath kolumnę do tabeli książki, wykonując następujące polecenie SQL -
ALTER TABLE `book` ADD `imagepath` VARCHAR(255) NOT NULL AFTER 'imagepath';
Zaktualizuj BookForm.php
Dodaj element wejściowy pliku, aby przesłać zdjęcie w formie książki - myapp / module / Tutorial / src / Model / BookForm.php.
Uwzględnij następujący kod w __constructmethod klasy BookForm.
$this->add(array(
'name' => 'imagepath',
'type' => 'File',
'options' => array ('label' => 'Picture',),
));
Zaktualizuj Book.php
Wykonaj następujące zmiany w klasie Book - myapp / module / Tutorial / src / Model / Book.php.
Dodaj nową właściwość imagepath do zdjęcia.
public $imagepath;
Zaktualizuj getInputFilter metoda, jak pokazano poniżej -
Dodaj FileInput filtr dla elementu wejściowego pliku.
Ustaw UploadFile walidacja w celu sprawdzenia poprawności elementu wejściowego pliku.
Skonfiguruj RenameUpload przenieść przesłany plik do właściwego miejsca docelowego.
Częściowa lista kodów jest następująca -
$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);
Zaktualizuj exchangeArray metoda uwzględniania imagepathwłasność. Imagepath może pochodzić z formularza lub bazy danych. Jeśli ścieżka obrazu pochodzi z formularza, formatem będzie tablica z następującą specyfikacją -
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>
}
}
Jeśli ścieżka obrazu pochodzi z bazy danych, będzie to prosty ciąg. Częściowy listing kodu do przeanalizowania ścieżki obrazu jest następujący -
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;
}
Pełna lista Book model wygląda następująco -
<?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;
}
}
}
Zaktualizuj BookTable.php
Zaktualizowaliśmy BookForm i Book model. Teraz aktualizujemyBookTable i zmodyfikuj plik saveBookmetoda. To wystarczy, aby umieścić wpis imagepath w tablicy danych,$data.
Częściowa lista kodów jest następująca -
$data = array('author' => $book->author, 'title' => $book->title,
'imagepath' => $book->imagepath
);
Pełna lista kodu BookTable klasa jest następująca -
<?php
namespace Tutorial\Model;
use Zend\Db\TableGateway\TableGatewayInterface;
class BookTable {
protected $tableGateway;
public function __construct(TableGatewayInterface $tableGateway) { $this->tableGateway = $tableGateway; } public function fetchAll() { $resultSet = $this->tableGateway->select(); return $resultSet;
}
public function getBook($id) { $id = (int) $id; $rowset = $this->tableGateway->select(array('id' => $id));
$row = $rowset->current();
if (!$row) { throw new \Exception("Could not find row $id");
}
return $row; } public function saveBook(Book $book) {
$data = array ( 'author' => $book->author,
'title' => $book->title, 'imagepath' => $book->imagepath
);
$id = (int) $book->id;
if ($id == 0) { $this->tableGateway->insert($data); } else { if ($this->getBook($id)) { $this->tableGateway->update($data, array('id' => $id));
} else {
throw new \Exception('Book id does not exist');
}
}
}
}
Update addAction in the TutorialController.php: Informacje o przesyłaniu plików będą dostępne w formacie $_FILES globalna tablica i można uzyskać do niej dostęp za pomocą Request's getFiles()metoda. Dlatego połącz zarówno opublikowane dane, jak i informacje o przesyłaniu plików, jak pokazano poniżej.
$post = array_merge_recursive(
$request->getPost()->toArray(), $request->getFiles()->toArray()
);
Pełna lista addAction() metoda jest następująca -
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);
}
Zaktualizuj widok pliku add.phtml
Na koniec zmień „add.phtml” i dołącz element wejściowy pliku imagepath, jak pokazano poniżej -
echo $this->formRow($form->get('imagepath'))."<br>";
Pełna lista jest następująca -
<?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();
}
Uruchom aplikację
Na koniec uruchom aplikację pod adresem http://localhost:8080/tutorial/add i dodaj nowe rekordy.
Wynik będzie taki, jak pokazano na poniższych zrzutach ekranu -
Form Page
Index Page
AJAX to nowoczesna technologia w programowaniu internetowym. Zapewnia opcje asynchronicznego wysyłania i odbierania danych na stronie internetowej, bez odświeżania strony. Framework Zend zapewnia opcję pracy zjson modeluj przez zend-view i zend-jsonskładnik. W tym rozdziale nauczmy się programowania Zend AJAX.
Zainstaluj składnik JSON
Komponent json Zend można zainstalować przy użyciu Composer polecenie jak określono poniżej -
composer require zendframework/zend-json
Pojęcie
Framework Zend zapewnia dwie metody łatwego pisania aplikacji WWW obsługującej AJAX. Są następujące -
Plik isXmlHttpRequest() metoda w Requestobiekt - jeśli zostanie wysłane żądanie AJAX, metoda isXmlHttpRequest () obiektu żądania zwraca wartość true, w przeciwnym razie false. Ta metoda służy do poprawnej obsługi żądań AJAX po stronie serwera.
if ($request->isXmlHttpRequest()) {
// Ajax request
} else {
// Normal request
}
Zend / View / Model / JsonModel - The JsonModel jest alternatywą dla ViewModeldo użytku wyłącznie w scenariuszach AJAX i REST API. JsonModel wraz zJsonStrategy (do skonfigurowania w bloku menedżera widoków modułu) koduje dane modelu do Json i zwraca go jako odpowiedź zamiast widoków (phtml).
AJAX - przykład roboczy
Dodajmy nową stronę Ajax, ajaxw module samouczka i asynchronicznie pobierz informacje o książce. Aby to zrobić, powinniśmy postępować zgodnie z następującymi krokami.
Krok 1: Dodaj JsonStrategy w konfiguracji modułu
Zaktualizuj blok menedżera widoków w pliku konfiguracyjnym modułu samouczka - myapp / module / Tutorial / config / module.config.php. Następnie,JsonStrategy będzie pracować z JsonModel do kodowania i wysyłania danych json.
'view_manager' => [
'template_map' => array
('layout/layout' => __DIR__ . '/../view/layout/newlayout.phtml'),
'template_path_stack' => [
'tutorial' => __DIR__ . '/../view',
],
'strategies' => array('ViewJsonStrategy',),
],
Krok 2: Dodaj metodę ajaxAction w TutorialController.php
Dodaj metodę ajaxAction do TutorialController.php z następującym kodem -
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;
}
Tutaj ajaxAction sprawdzi, czy przychodzące żądanie jest AJAX, czy nie. Jeśli przychodzące żądanie to AJAX, plikJsonModelzostanie utworzona. W przeciwnym razie normalnyViewModel zostanie utworzona.
W obu przypadkach informacje o książce zostaną pobrane z bazy danych i umieszczone w modelu. Jeśli model to JsonModel, toJsonStrategy zostanie wywołany i zakoduje dane jako json i zwróci jako odpowiedź.
Plik $query->get('showJson') == 1jest używany do celów debugowania. Poprostu dodajshowJson=1 w adresie URL, a strona wyświetli dane json.
Krok 3: Dodaj ajax.phtml
Teraz dodaj skrypt widoku ajax.phtmldla metody ajaxAction. Ta strona będzie miała link z etykietą -Load book information.
Kliknięcie tego linku spowoduje wykonanie żądania AJAX, które pobierze informacje o książce jako dane Json i wyświetli informacje o książce w postaci sformatowanej tabeli. Przetwarzanie AJAX odbywa się za pomocąJQuery.
Pełna lista kodów jest następująca -
<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>
Krok 4: Uruchom aplikację
Na koniec uruchom aplikację - http://localhost:8080/tutorial/ajax i kliknij łącze Załaduj informacje o książce.
Wynik będzie taki, jak pokazano poniżej -
Ajax Page -
Ajax Page with Book Information
Ajax page with debugging information
Cookie to bardzo ważna koncepcja w aplikacji internetowej. Zapewnia opcję utrwalania danych użytkownika, zwykle niewielkiej ilości informacji w samej przeglądarce przez ograniczony czas.
Plik cookie służy do utrzymywania stanu aplikacji internetowej. Framework Zend zapewnia moduł cookie wewnątrzzend-httpskładnik. Ten zend-http zapewnia abstrakcję HTTP i jego implementację.
Instalowanie składnika HTTP
Komponent HTTP można łatwo zainstalować przy użyciu Composer jak określono w poniższym kodzie.
composer require zendframework/zend-http
Concept
The zend-http provides the Zend\Http\Cookies class to manage cookies. It is used along with the Zend\Http\Client class, which is used to send a request to a web server. Cookies can be initialized as shown in the code below −
use Zend\Http\Cookies
$c = new Cookies();
When the HTTP client (Zend\Http\Client) first sends a URI request to the web server, it does not have any cookie. Once the request is received by the web server, it includes the cookie in its response object as the HTTP Header, Set-Cookie and sends it to the HTTP client. The HTTP client will extract the cookie from the http response and resent it as same HTTP Header in the subsequent request. Generally, each cookie will be mapped to a domain and a path of the domain.
The methods available in Cookies class are as follows −
addCookie(uri) − It is used to add a cookie into the request object of the given URI.
getCookie(cookieName, $cookieForm) − It is used to get the cookie, $cookieName available in the given URI, $uri. The third argument is how the cookie will be returned, either string or array.
fromResponse(uri) − It is used to extract cookies from the response object of the given URI.
addCookiesFromResponse − It is same as fromResponse, but it extracts and adds it again into the request object of the given URI.
isEmpty() − It is used to find whether the given Cookie object has any cookie or not.
reset() − It is used to clear all the cookies in the given URI.
In the next chapter, we will discuss regarding session management in the Zend Framework.
A Session is a very important concept in a web application. It provides the option to persist the user's data in the web server for a limited period of time. Zend framework provides a separate component, zend-session to handle the session information.
Install a Session Component
Session component can be installed using the Composer as specified below −
composer require zendframework/zend-session
Session Components
Zend framework provides six components to handle session management. All these components have been explained below −
Zend\Session\Container − The main API to read and write the session information.
Zend\Session\SessionManager − It is used to manage the entire lifecycle of a session.
Zend\Session\Storage − This is used to specify how the session data will be stored in the memory.
Zend\Session\SaveHandler − It is used to store and retrieve the session data into a physical location like RDBMS, Redis, MangoDB, etc.
Zend\Session\Validator − This is used to protect session from hijacking by cross-checking initial and subsequent request's remote address and user agent.
Zend\Session\Config\SessionConfig − It is used to configure how the session should behave.
The default configuration is enough to work with a session. Using the above components, all aspects of a session can be handled easily.
Session Component Example
Let us adhere to the following points to create a new page to understand a session in Zend framework. By default, it is enough to create an instance of a Container class to manage sessions.
Create a new action, sessionAction in TutorialController.
Initialize a Container object.
$c = new Container();
Check whether an arbitrary key count exists. If the key is not available, initialize the count with value 1. If it is available, increment the value as shown in the following code.
if (!isset($c->count)) { $c->count = 0;
} else {
$c->count++;
}
Register the count in the ViewModel.
Create a template file for – sessionAction, session.phtml in myapp/module/Tutorial/view/tutorial/tutorial/session.phtml and then render the count value.
Refreshing the page will increase the value of count in the session. The complete listing is as follows −
TutorialController.php
public function sessionAction() {
$c = new Container();
if (!isset($c->count)) { $c->count = 0;
} else {
$c->count++; } $view = new ViewModel([
'count' => $c->count, ]); return $view;
}
session.pthml
Session data, COUNT = <?= $this->count ?>
Sample Result
Session data, Count = 5
Authentication is one of the most significant and must-have feature in any web application. Zend Framework provides a separate component to handle authentication, which is called as the zend-authentication.
Install an Authentication Component
The authentication component can be installed using the following Composer command.
composer require zendframework/zend-authentication
Concept
Usually, a developer writes a php function to authenticate the user details against a datasource. Once the authentication is done, the authentication details are persisted for subsequent requests. Zend Framework generalizes this concept and provides two classes, which are explained below −
Class 1 Zend\Authentication\Adaptor\AdaptorInterface
This class provides a single method, authenticate to write the authentication logic. The authenticate method returns an instance of Zend\Authentication\Result class.
This Result object holds the authentication status; identity if the authentication succeeds and an error message, if the authentication fails. The signature of the authenticate interface and result class is as follows −
AdaptorInterface
namespace Zend\Authentication\Adaptor;
public function authenticate() {
// code
}
Result class
namespace Zend\Authentication;
class Result {
public function __construct($code, $identity, array $messages = []);
}
The Zend Framework provides a default implementation to authenticate against the database, ldap, http basic and digest credentials. An Adaptor authenticates but does not persist the details for any future requests.
Class 2 Zend\Authentication\AuthenticationService
The AuthenticationService is the main component, which uses the already configured adaptor for authentication purposes. Once the authentication is done, it persists the authentication details and provides methods, hasIdentity() to check whether an identity is available, getIdentity() to get the authentication details and clearIdentity() to clear the authentication details.
The partial code listing to use this AuthenticationService is as follows −
$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();
The stuff related to authorization are packaged as two separate modules, which are – zend-permissions-acl and zend-permissions-rbac. The zend-permissions-acl is based on the Access control list and the zend-permissions-rbac is based on the role based access control list. They provide high-level abstraction of ACL & RBAC concept and aids in writing the enterprise grade application.
The Zend Framework provides a separate component called as zend-mail to send email messages. The zend-mail component also provides an option to read and write email messages with attachments both in text and html format. Sending an email in Zend is much easier and simple to configure.
Let us go through the email concepts, basic settings, advanced settings such as SMTP transport, etc., in this chapter.
Install Mail Component
The mail component can be installed using the following Composer command.
composer require zendframework/zend-mail
Basic Email Configuration
A basic email consists of one or more recipients, a subject, a body and a sender. Zend provides Zend\Mail\Message class to create a new email message. To send an email using the zend-mail, you must specify at least one recipient as well as a message body.
The partial code to create a new mail message is as follows −
use Zend\Mail;
$mail = new Mail\Message(); $mail->setSubject('Zend email sample');
$mail->setBody('This is content of the mail message'); $mail->setFrom('[email protected]', "sender-name");
$mail->addTo('[email protected]', "recipient-name");
Zend provides Zend\Mail\Sendmail class to send the mail message. Sendmail uses the php native mail function, mail to send the mail message and we can configure the transport layer using php configuration file.
The partial coding using Sendmail is as follow −
$transport = new Mail\Transport\Sendmail();
$transport->send($mail);
The zend-mail provides many transport layer and each may require many additional parameters such as username, password, etc
Email Management Methods
Some of the notable email management methods are as follows −
isValid − Messages without a ‘From’ address is invalid.
isValid() : bool
setEncoding − Set the message encoding.
setEncoding(string $encoding) : void
getEncoding − Get the message encoding.
getEncoding() : string
setHeaders − Compose headers.
setHeaders(Zend\Mail\Headers $headers) : void
getHeaders − Access headers collection.
getHeaders() : Zend\Mail\Headers
setFrom − Set (overwrite) From addresses. It contains a key/value pairs where the key is the human readable name and the value is the email address.
setFrom(
string|AddressInterface|array|AddressList|Traversable $emailOrAddressList, string|null $name
) : void
addFrom − Add a ‘From’ address.
addFrom(
string|AddressInterface|array|AddressList|Traversable $emailOrAddressOrList, string|null $name
) : void
getFrom − Retrieve list of ‘From’ senders.
getFrom() : AddressList
setTo - Overwrite the address list in the To recipients.
setTo(
string|AddressInterface|array|AddressList|Traversable $emailOrAddressList, null|string $name
) : void
setSubject − Set the message subject header value.
setSubject(string $subject) :void
setBody − Set the message body.
setBody(null|string|Zend\Mime\Message|object $body) : void
Warstwa transportowa SMTP
Plik zend-mail udostępnia opcje wysyłania wiadomości e-mail przy użyciu serwera SMTP za pośrednictwem Zend\Mail\Transport\Smtpclass. To jest jakSendmail poza tym, że ma kilka dodatkowych opcji konfiguracji hosta SMTP, portu, nazwy użytkownika, hasła itp.
Częściowy kod jest następujący -
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);
Tutaj,
name - nazwa hosta SMTP.
host - Zdalna nazwa hosta lub adres IP.
port - Port, na którym nasłuchuje host zdalny.
Koncepcja poczty - przykład
Postępujmy zgodnie z poniższymi punktami, aby napisać prostą aplikację konsoli php, aby zrozumieć koncepcję poczty.
Utwórz folder „mailapp”.
zainstalować zend-mail za pomocą narzędzia kompozytora.
Utwórz plik php Mail.php wewnątrz folderu „mailapp”.
Utwórz wiadomość za pomocą Zend\Mail\Message.
$message = new Message(); $message->addTo('[email protected]');
$message->addFrom('[email protected]'); $message->setSubject('Hello!');
$message->setBody("My first Zend-mail application!");
Utwórz warstwę transportową SMTP i dodaj niezbędną konfigurację.
// 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);
Wyślij wiadomość e-mail za pomocą send metoda.
$transport->send($message);
Pełna lista Mail.php jest następująca -
<?php
require __DIR__ . '/vendor/autoload.php';
use Zend\Mail\Message;
use Zend\Mail\Transport\Smtp as SmtpTransport;
use Zend\Mail\Transport\SmtpOptions;
$message = new Message();
$message->addTo('[email protected]'); $message->addFrom('[email protected]');
$message->setSubject('Hello!'); $message->setBody("My first Zend-mail application!");
// Setup SMTP transport using LOGIN authentication
$transport = new SmtpTransport(); $options = new SmtpOptions([
'name' => 'localhost',
'host' => 'smtp.gmail.com', // or any SMTP server
'port' => 465, // port on which the SMTP server is listening
'connection_class' => 'login',
'connection_config' => [
'username' => '<your username>', 'password' => '<your password>',
'ssl' => 'ssl'],
]);
$transport->setOptions($options);
$transport->send($message);
Teraz uruchom aplikację w wierszu polecenia php Mail.php. Spowoduje to wysłanie poczty zgodnie z konfiguracją w aplikacji.
Ogólnie rzecz biorąc, możemy debugować aplikację PHP przy użyciu rozszerzenia advanced debugger tool lub za pomocą prostych poleceń, takich jak echo i die. W scenariuszu webowym musimy przetestować logikę biznesową oraz warstwę prezentacji. Formularze w aplikacji internetowej można testować, wprowadzając odpowiednie dane testowe, aby upewnić się, że działają one zgodnie z oczekiwaniami.
Projekt strony internetowej można przetestować ręcznie za pomocą przeglądarki. Tego typu procesy testowe można zautomatyzować za pomocą testów jednostkowych. Test jednostkowy jest niezbędny w dużych projektach. Te testy jednostkowe pomogą zautomatyzować proces testowania i ostrzec programistę, gdy coś pójdzie nie tak.
Konfigurowanie PHPUnit
Framework Zend integruje się z frameworkiem testów jednostkowych PHPUnit. Aby napisać test jednostkowy dla frameworka Zend, musimy skonfigurować PHPUnit, co można łatwo zrobić za pomocą następującego polecenia Composer.
$ composer require --dev phpunit/phpunit
Po wykonaniu powyższego polecenia otrzymasz odpowiedź, jak pokazano w poniższym bloku kodu.
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
Teraz, gdy otworzysz plik „composer.json”, zobaczysz następujące zmiany -
"require-dev": {
"phpunit/phpunit": "^5.7"
}
TestCase i Assertions
Framework Zend zapewnia klasy pomocnicze do testowania kontrolera. PlikTestCase jest głównym składnikiem w a PHPUnit Framework do pisania przypadków testowych, a Zend Framework zapewnia abstrakcyjną implementację TestCase, która jest nazywana AbstractHttpControllerTestCase.
Ten AbstractHttpControllerTestCase zapewnia różne Assertmetody i można je pogrupować według funkcjonalności. Są następujące -
Request Assertions- Służy do potwierdzenia żądania http. Na przykład assertControllerName.
CSS Select Assertions - Służy do sprawdzania odpowiedzi HTML za pomocą modelu HTML DOM.
XPath Assertions - Alternatywa dla asercji wyboru CSS opartych na XPath.
Redirect Assertions - Służy do sprawdzania przekierowania strony.
Response Header Assertions - Służy do sprawdzania nagłówka odpowiedzi, takiego jak kod stanu (assertResponseStatusCode)
Utwórz katalog testów
Test jednostkowy można napisać oddzielnie dla każdego modułu. Całe kodowanie związane z testami należy utworzyć wewnątrztest folder w katalogu głównym modułu.
Na przykład, aby napisać test dla TutorialController dostępnego w module Tutorial, klasę testową należy umieścić w katalogu myapp / module / Tutorial / test / Controller /.
Przykład
Napiszmy klasę testową do testowania jednostkowego TutorialController.
Na początek powinniśmy napisać klasę o nazwie TutorialControllerTest i rozszerzyć ją na AbstractHttpControllerTestCase.
Następnym krokiem jest napisanie pliku Setupmetodę konfiguracji środowiska testowego. Można to zrobić, dzwoniąc dosetApplicationConfig i przekazując nasz główny plik konfiguracyjny aplikacji myapp / config / application.config.php
public function setUp() {
$configOverrides = [];
$this->setApplicationConfig(ArrayUtils::merge( include __DIR__ . '/../../../../config/application.config.php', $configOverrides
));
parent::setUp();
}
Napisz jedną lub więcej metod i wywołaj różne metody assert w zależności od wymagań.
$this->assertMatchedRouteName('tutorial');
Napisaliśmy klasę testową, a pełna lista jest następująca -
<?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');
}
}
Teraz otwórz wiersz polecenia, przejdź do katalogu głównego aplikacji i wykonaj plik phpunit wykonywalny dostępny wewnątrz vendor teczka.
cd /path/to/app
./vendor/bin/phpunit ./vendor/bin/phpunit module/
Tutorial/test/Controller/TutorialControllerTest.php
Wynik będzie taki, jak pokazano w poniższym bloku kodu -
PHPUnit 5.7.5 by Sebastian Bergmann and contributors.
.1 / 1 (100%)
Time: 96 ms, Memory: 8.00MB
OK (1 test, 5 assertions)
Awaria systemu musi być skutecznie usuwana, aby system działał płynnie. Zend Framework zawieradefault error trappingktóry drukuje i rejestruje błędy w momencie ich wystąpienia. Ten sam program obsługi błędów jest używany do przechwytywaniaExceptions.
Procedura obsługi błędów wyświetla błędy, gdy debugowanie jest prawdziwe i rejestruje błąd, gdy debugowanie jest fałszywe. Zend Framework ma kilka klas wyjątków, a wbudowana obsługa wyjątków wychwyci każdy nieprzechwycony wyjątek i wyrenderuje użyteczną stronę.
Domyślna obsługa błędów
Domyślne ustawienia błędów możemy skonfigurować w pliku konfiguracyjnym aplikacji myapp / module / Application / config / module.config.php.
Przykładowy kod częściowy jest następujący -
'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',
],
],
Tutaj display_exception, not_found_template, wyjątek_template, error / 404 i błąd / indeks są elementami konfiguracji związanymi z błędami i są oczywiste.
Najważniejszą z nich jest error/index. To jest szablon wyświetlany, gdy w systemie wystąpi wyjątek. Możemy zmodyfikować ten szablon, myapp / module / Application / view / error / index.phtml, aby kontrolować ilość wyświetlanych błędów.
W tym rozdziale dowiemy się, jak stworzyć kompletną aplikację pracowniczą opartą na MVC w Zend Framework. Wykonaj czynności podane poniżej.
Krok 1: Module.php
Najpierw należy utworzyć moduł Employee w katalogu - myapp / module / Employee / src /, a następnie zaimplementować interfejs ConfigProviderInterface.
Pełny kod dla klasy Module jest następujący -
<?php
namespace Employee;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
class Module implements ConfigProviderInterface {
public function getConfig() {
return include __DIR__ . '/../config/module.config.php';
}
}
Krok 2: composer.json
Skonfiguruj Tutorial moduł w composer.json w sekcji automatycznego ładowania przy użyciu następującego kodu.
"autoload": {
"psr-4": {
"Application\\": "module/Application/src/",
"Tutorial\\": "module/Tutorial/src/",
"Employee\\": "module/Employee/src/"
}
}
Teraz zaktualizuj aplikację za pomocą polecenia aktualizacji kompozytora.
composer update
Polecenie Composer dokona niezbędnych zmian w aplikacji i wyświetli dzienniki, jak pokazano w wierszu polecenia poniżej.
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
Krok 3: module.config.php dla modułu pracownika
Utwórz plik konfiguracyjny modułu „module.config.php” w katalogu myapp / module / Employee / config z następującym kodem.
<?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',],
],
];
Teraz skonfiguruj moduł Pracownik w pliku konfiguracyjnym na poziomie aplikacji - myapp / config / modules.config.php.
return ['Zend\Router', 'Zend\Validator', 'Application', 'Tutorial', 'Employee'];
Krok 4: EmployeeController
Utwórz nową klasę PHP, EmployeeController, rozszerzając AbstractActionController i umieść ją w katalogu myapp / module / Employee / src / Controller.
Pełna lista kodów jest następująca -
<?php
namespace Employee\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class EmployeeController extends AbstractActionController {
public function indexAction() {
return new ViewModel();
}
}
Krok 5: Konfiguracja routera
Dodajmy trasę segmentu w naszym module Pracownik. Zaktualizuj plik konfiguracyjny modułu pracownika, module.config.php, dostępny pod adresem 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',
],
],
];
Pomyślnie dodaliśmy routing dla naszego modułu Pracownik. Następnym krokiem jest utworzenie skryptu widoku dla aplikacji Pracownik.
Krok 6: Utwórz ViewModel
Utwórz plik o nazwie „index.phtml” w katalogu myapp / module / Employee / view / worker / worker.
Dodaj następujące zmiany w pliku -
<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();
}
}
W końcu pomyślnie ukończyliśmy moduł Pracownik. możemy uzyskać do niego dostęp za pomocą następującego adresu URL -http://localhost:8080/employee.
Wynik
W następnym kroku wykonamy add, edit i deleteoperacje na danych w aplikacji pracowniczej. Aby wykonać te operacje, powinniśmy najpierw utworzyć model bazy danych. Zostanie to opisane w następnym kroku.
Krok 7: Utwórz model
Stwórzmy w naszym module model Pracownika src directory. Ogólnie modele są pogrupowane w folderze Model (myapp / module / Employee / src / Model / Employee.php)
<?php
namespace Employee\Model;
class Employee {
public $id; public $emp_name;
public $emp_job;
}
Krok 8: Tabela MySQL
Utwórz bazę danych o nazwie jako tutorials na lokalnym serwerze MYSQL za pomocą następującego polecenia -
create database tutorials;
Utwórzmy tabelę o nazwie jako employee w bazie danych za pomocą polecenia 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)
);
Wstaw dane do employee tabela przy użyciu następującego zapytania -
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');
Krok 9: Zaktualizuj konfigurację bazy danych
Zaktualizuj plik konfiguracji globalnej myapp / config / autoload / global.php, wprowadzając niezbędne informacje o dysku bazy danych.
return [
'db' => [
'driver' => 'Pdo',
'dsn' => 'mysql:dbname = tutorials;host=localhost',
'driver_options' => [PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''],
],
];
Teraz zaktualizuj referencje bazy danych w lokalnym pliku konfiguracyjnym - myapp / config / autoload / local.php. W ten sposób możemy oddzielić poświadczenia połączenia z lokalną i aktywną bazą danych.
<?php
return array(
'db' => array('username' => '<user_name>', 'password' => '<password>',),
);
Krok 10: Wdrożenie exchangeArray
Zaimplementuj funkcję exchangeArray w modelu pracownika.
<?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;
}
}
Krok 11: Użyj TableGateway, aby pobrać dane pracownika
Utwórz klasę EmployeeTable w samym folderze Model. Jest zdefiniowany w poniższym bloku kodu.
<?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;
}
}
Krok 12: Skonfiguruj klasę EmployeeTable
Zaktualizuj obsługę pracowników w Module.php za pomocą metody 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);
},
],
];
}
}
Krok 13: Dodaj usługę pracownika w kontrolerze
Zaktualizuj sekcję kontrolera konfiguracji modułu pracownika w - myapp / module / config / module.config.php, jak pokazano poniżej.
'controllers' => [
'factories' => [
Controller\EmployeeController::class => function($container) { return new Controller\EmployeeController( $container->get(Model\EmployeeTable::class)
);
},
],
]
Krok 14: Dodaj konstruktora dla EmployeeController
Dodaj konstruktora za pomocą EmployeeTable jako argument i edytuj następujące zmiany.
<?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;
}
}
Krok 15: Wyświetl informacje o pracowniku w skrypcie widoku „index.phtml”
Przenieś do pliku - index.phtml i wprowadź następujące zmiany -
<?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>
Teraz pomyślnie utworzyliśmy model bazy danych i możemy pobrać rekordy w aplikacji.
Poproś o aplikację przy użyciu adresu URL - http://localhost:8080/employee.
Wynik
Następny krok zawiera wyjaśnienie dotyczące insert, edit i delete operacje na danych w module pracownika.
Krok 16: Utwórz formularz pracownika
Utwórz plik o nazwie EmployeeForm.phpw katalogu myapp / module / Employee / src / Form. Jest to opisane w poniższym bloku kodu.
<?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',
),
));
}
}
Krok 17: Zaktualizuj model pracownika
Zaktualizuj model pracownika i zaimplementuj interfejs InputFilterAwareInterface. Przejdź do katalogu myapp / module / Employee / src / Employee / Model i dodaj następujące zmiany wEmployee.phpfile.
<?php
namespace Employee\Model;
// Add these import statements
use Zend\InputFilter\InputFilter;
use Zend\InputFilter\InputFilterAwareInterface;
use Zend\InputFilter\InputFilterInterface;
class Employee implements InputFilterAwareInterface {
public $id;
public $emp_name; public $emp_job;
protected $inputFilter; public function exchangeArray($data) {
$this->id = (isset($data['id'])) ? $data['id'] : null; $this->emp_name = (isset($data['emp_name'])) ? $data['emp_name'] : null;
$this->emp_job = (isset($data['emp_job'])) ? $data['emp_job'] : null; } // Add content to these methods: public function setInputFilter(InputFilterInterface $inputFilter) {
throw new \Exception("Not used");
}
public function getInputFilter() {
if (!$this->inputFilter) { $inputFilter = new InputFilter();
$inputFilter->add(array( 'name' => 'id', 'required' => true, 'filters' => array( array('name' => 'Int'), ), )); $inputFilter->add(array(
'name' => 'emp_name',
'required' => true,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
array('name' => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'min' => 1,
'max' => 50,
),
),
),
));
$inputFilter->add(array( 'name' => 'emp_job', 'required' => true, 'filters' => array( array('name' => 'StripTags'), array('name' => 'StringTrim'), ), 'validators' => array( array('name' => 'StringLength', 'options' => array( 'encoding' => 'UTF-8', 'min' => 1, 'max' => 50, ), ), ), )); $this->inputFilter = $inputFilter; } return $this->inputFilter;
}
}
Krok 18: Dodaj addAction w kontrolerze pracownika
Dodaj następujące zmiany w EmployeeController klasa.
<?php
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Employee\Model\Employee;
use Employee\Model\EmployeeTable;
use Employee\Form\EmployeeForm;
public function addAction() {
$form = new EmployeeForm(); $form->get('submit')->setValue('Add');
$request = $this->getRequest();
if ($request->isPost()) { $employee = new Employee();
$form->setInputFilter($employee->getInputFilter());
$form->setData($request->getPost());
if ($form->isValid()) { $employee->exchangeArray($form->getData()); $this->table->saveEmployee($employee); // Redirect to list of employees return $this->redirect()->toRoute('employee');
}
}
return array('form' => $form);
}
Krok 19: Dodaj funkcję zapisywania w klasie EmployeeTable
Dodaj następujące dwie funkcje do klasy 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');
}
}
}
Krok 20: Utwórz skrypt widoku dla metody AddAction, Add.phtml
Dodaj następujące zmiany w pliku „Add.phtml” w - myapp / module / view / worker / worker.
<?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
Wynik
Po dodaniu danych nastąpi przekierowanie na stronę główną.
Krok 21: Edytuj rekordy pracowników
Wykonajmy edycję operacji na danych w module Pracownik. Zaktualizuj następujące zmiany wEmployeecontroller.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,);
}
Tutaj szukamy pliku id, który znajduje się w dopasowanej marszruty, a następnie załaduj dane pracownika do operacji edycji.
Krok 22: Employee.php
Teraz dodaj następujące zmiany w pliku „Employee.php”, który znajduje się w katalogu - myapp / module / Employee / src / Employee / Model /.
public function getArrayCopy() {
return get_object_vars($this);
}
Tutaj Zend \ Stdlib \ Hydrator \ ArraySerializable oczekuje, że znajdzie w modelu dwie metody: getArrayCopy() i exchangeArray().
W którym do iteracji używana jest metoda exchangeArray (). Ta funkcja służy do wiązania danych z tabeli pracowników.
Teraz musimy stworzyć skrypt widoku dla editAction().
Krok 23: Utwórz plik Edit.phtml
Utwórz plik skryptu widoku w module / Employee / view / worker / worker / 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();
Edytowanie danych pracownika pokazano na poniższym zrzucie ekranu.
Po edycji danych nastąpi przekierowanie do strony głównej.
Krok 24: Dodaj metodę deleteEmployee
Dodaj metodę deleteEmployee do klasy EmployeeTable - myapp / module / Employee / src / Model / EmployeeTable.php
public function deleteEmployee($id) { $this->tableGateway->delete(['id' => (int) $id]);
}
Krok 25: Usuń rekordy pracowników
Wykonajmy teraz operacje usuwania danych w module Pracownik. Dodaj następującą metodę,deleteAction w klasie 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)
);
}
Tutaj metoda deleteEmployee () usuwa pracownika przez jego id i przekierowuje na stronę z listą pracowników (strona główna).
Utwórzmy teraz odpowiednie skrypty widoku dla metody deleteAction ().
Krok 26: Utwórz skrypt widoku
Utwórz plik o nazwie delete.phtml w - myapp / module / Employee / view / worker / worker / delete.phtml i dodaj w nim następujący kod.
<?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>
Teraz usuń dowolnego pracownika za pomocą edit link na stronie głównej, a wynik będzie taki, jak pokazano na poniższym zrzucie ekranu.
Wynik
Pomyślnie ukończyliśmy moduł Pracownik, wdrażając wszystkie niezbędne funkcje.
Wniosek
W obecnym konkurencyjnym środowisku framework Zend jest umieszczany na pierwszym miejscu przez dewelopera. Dostarcza abstrakcji do dowolnego programu lub dowolnego typu aplikacji w języku PHP. Jest to dojrzały framework i obsługuje nowoczesne funkcje języka PHP. Jest zabawny, profesjonalny, ewoluuje i dotrzymuje kroku aktualnej technologii.