Zend Framework - Hướng dẫn nhanh

PHP Web Framework là một tập hợp các lớp giúp phát triển một ứng dụng web. Zend là một trong những framework PHP phổ biến nhất. Nó là mộtopen-source MVC frameworkcho các ứng dụng web hiện đại, đang phát triển nhanh chóng. Zend Framework có một số thành phần được ghép nối lỏng lẻo, vì vậy nó được gọi là “Thư viện thành phần”. Zend Framework cung cấp bất kỳ ngăn xếp PHP và máy chủ Zend nào để chạy các ứng dụng khung Zend.

Zend Studio là một IDE bao gồm các tính năng để tích hợp với Zend Framework. Nó cung cấp chế độ xem MVC và tạo mã. Zend framework 3.0 hiện tại bao gồm các thành phần mới như máy chủ JSON RPC, trình chuyển đổi XML sang JSON, chức năng PSR-7 và khả năng tương thích với PHP 7.

Zend Framework 2 là một khuôn khổ mã nguồn mở để phát triển các ứng dụng và dịch vụ web sử dụng PHP 5.3+. Zend Framework 2 sử dụng 100% mã hướng đối tượng và sử dụng hầu hết các tính năng mới của PHP 5.3, cụ thể làNamespaces, Lambda FunctionsClosures.

Zend Framework 2 phát triển từ Zend Framework 1, một khuôn khổ PHP thành công với hơn 15 triệu lượt tải xuống. Zend Server có phiên bản cộng đồng miễn phí và phiên bản thương mại.

Các tính năng của Zend Framework

Một số tính năng nổi bật của Zend Framework như sau:

  • Khung ứng dụng web hướng đối tượng thuần túy
  • Triển khai MVC nâng cao
  • Hỗ trợ nhiều cơ sở dữ liệu bao gồm PostgreSQL, SQLite, v.v.,
  • API đám mây đơn giản
  • Quản lý phiên
  • Mã hóa dữ liệu
  • Định tuyến URI linh hoạt
  • Zend cung cấp hỗ trợ phát triển RESTful API.
  • Mã có thể tái sử dụng và dễ bảo trì hơn.

Tại sao Zend Framework?

Điều làm cho Zend Framework trở thành một trong những khuôn khổ hàng đầu được các nhà phát triển PHP sử dụng là - nó cung cấp mã sạch và ổn định hoàn chỉnh với các quyền sở hữu trí tuệ. Nó cũng giúp lập trình dễ dàng hơn. Nó nhanh chóng, dễ học và khuôn khổ thuận tiện. Zend hỗ trợ các công cụ mật mã mạnh mẽ và kỹ thuật băm mật khẩu.

Mục tiêu Zend

Sau đây là các mục tiêu của Zend Framework.

  • Flexibility
  • Đơn giản và hiệu quả
  • Compatibility
  • Khả năng mở rộng - Lập trình viên có thể dễ dàng mở rộng tất cả các lớp khung.
  • Khả năng di chuyển - Hỗ trợ nhiều môi trường

Ứng dụng Zend

Các sản phẩm phổ biến sau đây được phát triển bằng cách sử dụng Zend Framework.

  • Trang web của Công ty McAfee
  • Trang web của Công ty IBM
  • Magento - một trong những trang web giỏ hàng phổ biến.

Ưu điểm của Zend Framework

Dưới đây là một số ưu điểm của Zend Framework.

  • Loosely Coupled - Zend cung cấp tùy chọn để xóa các mô-đun hoặc thành phần mà chúng tôi không cần trong ứng dụng.

  • Performance- Zend Framework được tối ưu hóa cao cho hiệu suất. Zend Framework 3 nhanh hơn 4 lần so với phiên bản trước của nó.

  • Security - Framework hỗ trợ mã hóa tiêu chuẩn công nghiệp.

  • Testing - PHPUnit được tích hợp với Zend để bạn có thể dễ dàng kiểm tra framework.

Trong chương tiếp theo, chúng ta sẽ học cách cài đặt Zend Framework.

Để cài đặt Zend Framework, trước tiên chúng ta phải cài đặt Composer và phiên bản PHP mới nhất như trong các bước sau.

  • Install Composer- Zend sử dụng Composer để quản lý các phần phụ thuộc của nó, vì vậy hãy đảm bảo rằng bạn đã cài đặt Composer trên máy của mình. Nếu Composer chưa được cài đặt, hãy truy cập trang web chính thức của Composer và cài đặt nó.

  • Install the latest version of PHP- Để có được lợi ích tối đa của Zend Framework, hãy cài đặt phiên bản PHP mới nhất. Phiên bản yêu cầu tối thiểu cho Zend Framework 3 là PHP 5.6 trở lên.

Cài đặt Zend Framework

Zend Framework có thể được cài đặt theo hai cách. Chúng như sau:

  • Hướng dẫn cài đặt
  • Cài đặt dựa trên trình soạn nhạc

Hãy để chúng tôi thảo luận chi tiết về cả hai cách cài đặt này.

Hướng dẫn cài đặt

Tải xuống phiên bản mới nhất của Zend Framework bằng cách truy cập liên kết sau: https://framework.zend.com/downloads/archives

Giải nén nội dung của tệp lưu trữ đã tải xuống vào thư mục bạn muốn giữ nó. Sau khi bạn có sẵn bản sao của Zend Framework trong máy cục bộ của mình, ứng dụng web dựa trên Zend Framework của bạn có thể truy cập các lớp khung. Mặc dù có một số cách để đạt được điều này, nhưng PHP của bạninclude_pathcần phải chứa đường dẫn đến các lớp Zend Framework trong thư mục / library trong bản phân phối. Phương pháp này chỉ áp dụng cho Zend Framework phiên bản 2.4 trở về trước.

Cài đặt dựa trên nhà soạn nhạc

Để dễ dàng cài đặt Zend Framework, hãy sử dụng công cụ Composer. Đây là phương pháp ưa thích để cài đặt phiên bản mới nhất của Zend Framework. Để cài đặt tất cả các thành phần của Zend Framework, hãy sử dụng lệnh Composer sau:

$ composer require zendframework/zendframework

Mỗi thành phần / mô-đun Zend Framework cũng có thể được cài đặt riêng lẻ. Ví dụ, để cài đặtMVC component của Zend Framework, sử dụng phần sau composer lệnh -

$ composer require zendframework/zend-mvc

Hãy để chúng tôi tạo một ứng dụng khung bằng hệ thống mô-đun và lớp Zend Framework MVC.

Cài đặt bằng Composer

Cách dễ nhất để tạo một dự án Zend Framework mới là sử dụng Composer. Nó được định nghĩa như sau:

$ cd /path/to/install $ composer create-project -n -sdev zendframework/skeleton-application myapp

Bạn sẽ thấy kết quả sau trên màn hình của mình:

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.

Bây giờ ứng dụng đã được cài đặt, bạn có thể kiểm tra nó ngay lập tức bằng cách sử dụng PHP's built-in web server -

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

Sau đó, bạn sẽ thấy phản hồi sau:

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

Thao tác này sẽ khởi động máy chủ CLI tích hợp sẵn PHP trên cổng 8080. Khi máy chủ phát triển được khởi động, bạn có thể truy cập trang web tại (http://localhost:8080/). Máy chủ CLI tích hợp chỉ dành cho phát triển.

Kiểm tra đơn vị

Để chạy kiểm tra đơn vị khung, hãy nhập lệnh sau vào thiết bị đầu cuối của bạn.

$ composer require --dev zendframework/zend-test

Nó sẽ tạo ra phản hồi sau:

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

Giờ đây, hỗ trợ thử nghiệm đã được bật để bạn có thể chạy thử nghiệm bằng lệnh sau.

$ ./vendor/bin/phpunit

Máy chủ web Apache

Lưu trữ ứng dụng dựa trên Zend Framework trong môi trường sản xuất rất đơn giản và dễ hiểu. Chỉ cần tạo mộtVirtualHost trong tệp cấu hình Apache và trỏ DocumentRoot đến Public thư mục của ứng dụng Zend Framework.

Một cấu hình mẫu (myapp) được đưa ra bên dưới -

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

Trước khi tiếp tục chương này, chúng ta hãy tìm hiểu sơ lược về MVC. AModel View Controllerlà một cách tiếp cận phần mềm tách logic ứng dụng khỏi bản trình bày. Trên thực tế, nó cho phép các trang web chứa tập lệnh PHP tối thiểu vì bản trình bày tách biệt với nó.

Mô tả ngắn gọn về Thành phần MVC như sau

  • Model- Mô hình biểu diễn cấu trúc của dữ liệu ứng dụng. Thông thường, các lớp mô hình chứa các hàm giúpretrieve, insertupdate business data trong cơ sở dữ liệu back-end (MySQL, PostgreSQL, v.v.).

  • View- View là lớp trình bày của Ứng dụng MVC. Nó lấy dữ liệu mô hình thông qua Bộ điều khiển và hiển thị nó khi cần thiết. Nó được kết hợp lỏng lẻo vớiControllerModel và do đó, nó có thể được thay đổi mà không ảnh hưởng đến Model và Controller.

  • Controller- Bộ điều khiển là thành phần chính của kiến ​​trúc MVC. Mọi yêu cầu đầu tiên sẽ truy cập bộ điều khiển. Nói cách khác, bộ điều khiển xử lý tất cả yêu cầu và đóng vai trò trung gian giữa Mô hình, Chế độ xem và bất kỳ tài nguyên nào khác cần thiết đểprocess the HTTP request và để tạo ra phản hồi.

Trong chương tiếp theo, chúng ta sẽ hiểu các khái niệm khác nhau của Zend Framework.

Zend Framework là tập hợp của hơn 60 thành phần. Chúng được kết nối lỏng lẻo với nhau. Chúng có thể được sử dụng như một thành phần độc lập cũng như một nhóm các thành phần hoạt động như một đơn vị duy nhất.

Zend Framework cung cấp ba thành phần quan trọng nhất, đó là:

  • zend-servicemanager
  • zend-eventmanager và
  • zend-modulemanager.

Chúng cung cấp cho các thành phần Zend khả năng tích hợp với các thành phần khác một cách hiệu quả.

  • Event Manager- Nó cung cấp khả năng tạo lập trình dựa trên sự kiện. Điều này giúp tạo, đưa và quản lý các sự kiện mới.

  • Service Manager - Nó cung cấp khả năng sử dụng bất kỳ dịch vụ nào (các lớp PHP) từ bất kỳ đâu với một chút nỗ lực.

  • Module Manager - Khả năng chuyển đổi một tập hợp các lớp PHP có chức năng tương tự thành một đơn vị duy nhất được gọi là module. Các mô-đun mới được tạo có thể được sử dụng, duy trì và cấu hình như một đơn vị duy nhất.

Chúng tôi sẽ trình bày chi tiết các khái niệm này trong các chương tiếp theo.

Zend Framework bao gồm một triển khai mẫu định vị dịch vụ mạnh mẽ được gọi là zend-servicemanager. Zend framework sử dụng rộng rãi trình quản lý dịch vụ cho tất cả các chức năng của nó. Trình quản lý dịch vụ cung cấp một bản tóm tắt cấp cao cho Zend Framework. Nó cũng tích hợp độc đáo với tất cả các thành phần khác của Zend Framework.

Cài đặt Trình quản lý Dịch vụ

Thành phần Trình quản lý dịch vụ có thể được cài đặt bằng cách sử dụng composer dụng cụ.

composer require zendframework/zend-servicemanager

Thí dụ

Đầu tiên, tất cả các dịch vụ cần được đăng ký vào trình quản lý dịch vụ. Sau khi các dịch vụ được đăng ký vào hệ thống quản lý máy chủ, nó có thể được truy cập bất kỳ lúc nào với nỗ lực tối thiểu. Người quản lý dịch vụ cung cấp rất nhiều tùy chọn để đăng ký dịch vụ. Một ví dụ đơn giản như sau:

use Zend\ServiceManager\ServiceManager; 
use Zend\ServiceManager\Factory\InvokableFactory; 
use stdClass;  
$serviceManager = new ServiceManager([ 
   'factories' => [stdClass::class => InvokableFactory::class,], 
]);

Đoạn mã trên đăng ký stdClass vào hệ thống bằng cách sử dụng FactoryLựa chọn. Bây giờ, chúng ta có thể lấy một phiên bản của stdClass bất kỳ lúc nào bằng cách sử dụngget() phương pháp của người quản lý dịch vụ như hình dưới đây.

use Zend\ServiceManager\ServiceManager;  
$object = $serviceManager->get(stdClass::class);

Phương thức get () chia sẻ đối tượng được truy xuất và do đó, đối tượng được trả về bằng cách gọi phương thức get () nhiều lần là một và cùng một thể hiện. Để có được một phiên bản khác nhau mọi lúc, trình quản lý dịch vụ cung cấp một phương pháp khác, đó làbuild() phương pháp.

use Zend\ServiceManager\ServiceManager;  
$a = $serviceManager->build(stdClass::class); $b = $serviceManager->build(stdClass::class);

Đăng ký người quản lý dịch vụ

Trình quản lý dịch vụ cung cấp một tập hợp các phương pháp để đăng ký một thành phần. Một số phương pháp quan trọng nhất được đưa ra dưới đây:

  • Phương pháp nhà máy
  • Phương pháp nhà máy trừu tượng
  • Phương pháp khởi tạo
  • Phương thức nhà máy ủy quyền

Chúng ta sẽ thảo luận chi tiết từng điều này trong các chương sắp tới.

Phương pháp nhà máy

Một nhà máy về cơ bản là bất kỳ lớp nào có thể gọi hoặc bất kỳ lớp nào triển khai FactoryInterface (Zend \ ServiceManager \ Factory \ FactoryInterface).

FactoryInterface có một phương thức duy nhất -

public function __invoke(ContainerInterface $container, $requestedName, array $options = null)

Chi tiết đối số của FactoryInterface như sau:

  • container (ContainerInterface)- Đây là giao diện cơ sở của ServiceManager. Nó cung cấp một tùy chọn để nhận các dịch vụ khác.

  • requestedName - Đó là tên dịch vụ.

  • options - Nó cung cấp các tùy chọn bổ sung cần thiết cho dịch vụ.

Hãy để chúng tôi tạo một lớp đơn giản thực hiện FactoryInterface và xem cách đăng ký lớp đó.

Kiểm tra lớp - Đối tượng được lấy

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

Các Test lớp phụ thuộc vào stdClass.

Lớp TestFactory - Lớp để khởi tạo đối tượng thử nghiệm

class TestFactory implements FactoryInterface { 
   public function __invoke(ContainerInterface $container, $requestedName, 
      array $options = null) { $dep = $container->get(stdClass::class); return new Test($dep); 
   } 
}

TestFactory sử dụng một vùng chứa để lấy stdClass, tạo thể hiện của lớp Test và trả về nó.

Đăng ký và sử dụng Zend Framework

Bây giờ chúng ta hãy hiểu cách đăng ký và sử dụng Zend Framework.

serviceManager $sc = new ServiceManager([ 'factories' => [stdClass::class => InvokableFactory::class, Test::class => TestFactory::class] ]); $test = $sc->get(Test::class);

Người quản lý dịch vụ cung cấp một nhà máy đặc biệt được gọi là InvokableFactoryđể truy xuất bất kỳ lớp nào không có phụ thuộc. Ví dụ,stdClass có thể được cấu hình bằng InvokableFactory vì stdClass không phụ thuộc vào bất kỳ lớp nào khác.

serviceManager $sc = new ServiceManager([ 
   'factories' => [stdClass::class => InvokableFactory::class] 
]);  
$stdC = $sc->get(stdClass::class);

Một cách khác để truy xuất một đối tượng mà không cần triển khai FactoryInterface hoặc sử dụng InvokableFactory đang sử dụng phương pháp nội tuyến như được đưa ra bên dưới.

$serviceManager = new ServiceManager([ 'factories' => [ stdClass::class => InvokableFactory::class, Test::class => function(ContainerInterface $container, $requestedName) { $dep = $container->get(stdClass::class); return new Test($dep); 
      }, 
   ], 
]);

Phương pháp nhà máy trừu tượng

Đôi khi, chúng ta có thể cần tạo các đối tượng mà chúng ta chỉ biết đến trong thời gian chạy. Tình huống này có thể được xử lý bằng cách sử dụngAbstractFactoryInterface, có nguồn gốc từ FactoryInterface.

AbstractFactoryInterface định nghĩa một phương thức để kiểm tra xem đối tượng có thể được tạo ra ở phiên bản được yêu cầu hay không. Nếu có thể tạo đối tượng, nó sẽ tạo đối tượng bằng cách sử dụng__invokemethod của FactoryInterface và trả lại nó.

Chữ ký của AbstractFactoryInterface như sau:

public function canCreate(ContainerInterface $container, $requestedName)

Phương pháp khởi tạo

Phương thức khởi tạo là một tùy chọn đặc biệt để thêm phụ thuộc cho các dịch vụ đã được tạo. Nó thực hiệnInitializerInterface và chữ ký của phương pháp duy nhất có sẵn như sau:

public function(ContainerInterface $container, $instance)  
function(ContainerInterface $container, $instance) { 
   if (! $instance instanceof EventManagerAwareInterface) { return; } $instance->setEventManager($container->get(EventManager::class)); 
}

Trong ví dụ trên, phương thức kiểm tra xem phiên bản có thuộc kiểu EventManagerAwareInterface hay không. Nếu nó thuộc loạiEventManagerAwareInterface, nó đặt đối tượng trình quản lý sự kiện, nếu không thì không. Vì phương thức có thể có hoặc không thiết lập sự phụ thuộc, nó không đáng tin cậy và tạo ra nhiều vấn đề về thời gian chạy.

Phương pháp nhà máy ủy quyền

Zend Framework hỗ trợ mẫu người ủy quyền thông qua DelegatorFactoryInterface. Nó có thể được sử dụng để trang trí dịch vụ.

Chữ ký của hàm này như sau:

public function __invoke(ContainerInterface $container, 
   $name, callable $callback, array $options = null 
);

Đây, $callback chịu trách nhiệm trang trí phiên bản dịch vụ.

Dịch vụ lười biếng

Dịch vụ lười biếng là một trong những dịch vụ sẽ không được khởi tạo hoàn toàn tại thời điểm tạo. Chúng chỉ được tham chiếu và chỉ khởi tạo khi thực sự cần thiết. Một trong những ví dụ điển hình nhất là kết nối cơ sở dữ liệu, có thể không cần thiết ở mọi nơi. Nó là một nguồn tài nguyên đắt tiền cũng như tốn nhiều thời gian để tạo ra. Zend framework cung cấpLazyServiceFactory được chuyển hóa từ DelegatorFactoryInterface, có thể tạo ra dịch vụ lười biếng với sự trợ giúp của Delegator khái niệm và trình quản lý proxy bên thứ 3, được gọi là ocramius proxy manager.

Plugin Manager

Trình quản lý plugin mở rộng trình quản lý dịch vụ và cung cấp chức năng bổ sung như xác thực phiên bản. Zend Framework sử dụng rộng rãi trình quản lý plugin.

Ví dụ: tất cả các dịch vụ xác thực đều thuộc ValidationPluginManager.

Tùy chọn cấu hình

Trình quản lý dịch vụ cung cấp một số tùy chọn để mở rộng tính năng của trình quản lý dịch vụ. họ đangshared, shared_by_defaultaliases. Như chúng ta đã thảo luận trước đó, các đối tượng đã truy xuất được chia sẻ giữa các đối tượng được yêu cầu theo mặc định và chúng ta có thể sử dụngbuild()phương pháp để có được một đối tượng riêng biệt. Chúng tôi cũng có thể sử dụngsharedtùy chọn để chỉ định dịch vụ nào sẽ được chia sẻ. Cácshared_by_default giống như shared , ngoại trừ việc nó áp dụng cho tất cả các dịch vụ.

$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 
]);

Các aliasestùy chọn có thể được sử dụng để cung cấp một tên thay thế cho các dịch vụ đã đăng ký. Điều này có cả lợi thế và bất lợi. Về mặt tích cực, chúng tôi có thể cung cấp các tên viết tắt thay thế cho một dịch vụ. Tuy nhiên, đồng thời, tên có thể trở nên sai ngữ cảnh và gây ra lỗi.

aliases' => ['std' => stdClass::class, 'standard' => 'std']

Tất cả các ứng dụng hiện đại cần các thành phần sự kiện chắc chắn và linh hoạt. Zend Framework cung cấp một thành phần như vậy,zend-eventmanager. Zend-eventmanager giúp thiết kế kiến ​​trúc cấp cao và hỗ trợ mô hình chủ thể / người quan sát và lập trình hướng khía cạnh.

Cài đặt Trình quản lý sự kiện

Trình quản lý sự kiện có thể được cài đặt bằng cách sử dụng Composer như được chỉ định bên dưới -

composer require zendframework/zend-eventmanager

Các khái niệm về Trình quản lý sự kiện

Các khái niệm cốt lõi của người quản lý sự kiện như sau:

  • Event - Sự kiện là hành động được đặt tên tùy ý, nói greet.

  • Listener- Bất kỳ lệnh gọi lại PHP nào. Chúng được đính kèm với các sự kiện và được gọi khi sự kiện được kích hoạt. Chữ ký mặc định của Listener là -

function(EventInterface $e)
  • EventInterface Class- Được sử dụng để chỉ định chính sự kiện. Nó có các phương thức để thiết lập và lấy thông tin sự kiện như tên (set / getName), target (get / setTarget) và tham số (get / setParams).

  • EventManager class- Phiên bản của EventManager theo dõi tất cả các sự kiện được xác định trong một ứng dụng và các trình nghe tương ứng của nó. EventManager cung cấp một phương thức,attach để đính kèm người nghe vào một sự kiện và nó cung cấp một phương pháp, triggerđể kích hoạt bất kỳ sự kiện nào được xác định trước. Sau khi kích hoạt được gọi, EventManager sẽ gọi trình nghe gắn liền với nó.

  • EventManagerAwareInterface- Đối với một lớp hỗ trợ lập trình dựa trên sự kiện, nó cần triển khai EventManagerAwareInterface. Nó cung cấp hai phương pháp,setEventManagergetEventManager để lấy và đặt trình quản lý sự kiện.

Thí dụ

Hãy để chúng tôi viết một ứng dụng bảng điều khiển PHP đơn giản để hiểu khái niệm trình quản lý sự kiện. Làm theo các bước dưới đây.

  • Tạo một thư mục "eventapp".

  • Tải về zend-eventmanager sử dụng trình soạn nhạc.

  • Tạo một tệp PHP Greeter.php bên trong thư mục "eventapp".

  • Tạo lớp học Greeter và thực hiện EventManagerAwareInterface.

require __DIR__ . '/vendor/autoload.php'; 
class Greeter implements EventManagerAwareInterface { 
   // code 
}

Đây, require được sử dụng để tự động tải tất cả các thành phần đã cài đặt của trình soạn nhạc.

Viết setEventManager phương pháp trong lớp Greeter như hình dưới đây -

public function setEventManager(EventManagerInterface $events) { $events->setIdentifiers([ __CLASS__, get_called_class(),]); 
   $this->events = $events; 
   return $this; 
}

Phương thức này đặt lớp hiện tại thành trình quản lý sự kiện đã cho (đối số $ sự kiện) và sau đó đặt trình quản lý sự kiện trong biến cục bộ $events.

Bước tiếp theo là viết getEventManager phương pháp trong lớp Greeter như hình dưới đây -

public function getEventManager() { 
   if (null === $this->events) { 
      $this->setEventManager(new EventManager()); } return $this->events; 
}

Phương thức này lấy trình quản lý sự kiện từ một biến cục bộ. nếu nó không có sẵn, thì nó sẽ tạo một thể hiện của trình quản lý sự kiện và trả về nó.

Viết một phương thức, greet, Trong lớp Greeter.

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

Phương thức này nhận trình quản lý sự kiện và kích hoạt / kích hoạt các sự kiện gắn liền với nó.

Bước tiếp theo là tạo một phiên bản của Greeter và đính kèm một trình lắng nghe vào phương thức của nó, 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); 
});

Người nghe gọi lại chỉ in tên của sự kiện, mục tiêu và các tham số được cung cấp.

Danh sách đầy đủ của Greeter.php như sau -

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

Bây giờ, chạy ứng dụng trong dấu nhắc lệnh php Greeter.php và kết quả sẽ như sau:

"Hello" from class 
"Hello" from class 
"greet" event of class "Greeter" is called. The parameter supplied is ["Hello"]

Ứng dụng mẫu ở trên chỉ giải thích những điều cơ bản của người quản lý sự kiện. Trình quản lý sự kiện cung cấp nhiều tùy chọn nâng cao hơn nhưListener Priority, Custom Callback Prototype / Signature, Short Circuiting, v.v ... Trình quản lý sự kiện được sử dụng rộng rãi trong khuôn khổ Zend MVC.

Zend Framework cung cấp một hệ thống mô-đun mạnh mẽ. Hệ thống mô-đun có ba thành phần. Chúng như sau:

  • Module Autoloader- Trình tự động tải mô-đun chịu trách nhiệm định vị và tải mô-đun từ nhiều nguồn khác nhau. Nó có thể tải các mô-đun được đóng gói dưới dạngPhar archivescũng. Việc triển khai Trình tự động tải mô-đun được đặt tại myapp / nhà cung cấp / zendframework / zend-loader / src / ModuleAutoloader.php.

  • Module Manager- Khi Trình tự động tải mô-đun định vị các mô-đun, trình quản lý mô-đun sẽ kích hoạt một chuỗi sự kiện cho mỗi mô-đun. Việc triển khai Trình quản lý mô-đun được đặt tại myapp / nhà cung cấp / zendframework / zendmodulemanager / src / ModuleManager.php.

  • Module Manager Listeners- Chúng có thể được đính kèm với các sự kiện do Trình quản lý mô-đun kích hoạt. Bằng cách gắn vào các sự kiện của trình quản lý mô-đun, họ có thể làm mọi thứ từ giải quyết và tải mô-đun đến thực hiện công việc phức tạp cho từng mô-đun.

Hệ thống mô-đun web MVC

Ứng dụng Web MVC trong Zend Framework thường được viết dưới dạng Mô-đun. Một trang web có thể chứa một hoặc nhiều mô-đun được nhóm theo chức năng. Cấu trúc được khuyến nghị cho mô-đun hướng MVC như sau:

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>

Cấu trúc tương tự như đã thảo luận trong chương trước, nhưng ở đây nó là chung chung. Cácautoload_ files có thể được sử dụng làm cơ chế mặc định để tự động tải các lớp có sẵn trong mô-đun mà không cần sử dụng nâng cao Module Manager có sẵn trong zend-modulemanager.

  • autoload_classmap.php - Trả về một mảng tên lớp và tên tệp tương ứng của nó.

  • autoload_function.php- Trả về một lệnh gọi lại PHP. Điều này có thể sử dụng các lớp được trả về bởi autoload_classmap.php.

  • autoload_register.php - Đăng ký lệnh gọi lại PHP được trả về bởi autoload_ Chức năng.php.

Các tệp tự động tải này không bắt buộc nhưng được khuyến nghị. Trong ứng dụng khung xương, chúng tôi đã không sử dụngautoload_ files.

Lớp mô-đun

Lớp Mô-đun phải được đặt tên Module và không gian tên của lớp mô-đun phải là Module name. Điều này sẽ giúp Zend Framework giải quyết và tải mô-đun dễ dàng. CácApplication mã mô-đun trong ứng dụng khung xương (myapp), myapp / module / Application / src / Module.php như sau:

namespace Application; 
class Module { 
   const VERSION = '3.0.2dev'; 
   public function getConfig() { 
      return include __DIR__ . '/../config/module.config.php'; 
   } 
}

Trình quản lý mô-đun Zend Framework sẽ gọi getConfig() hoạt động tự động và sẽ thực hiện các bước cần thiết.

Trong chương này, chúng ta hãy hiểu cấu trúc của ứng dụng Zend Framework. Cấu trúc củamyapp ứng dụng như sau -

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

Ứng dụng Zend Framework bao gồm các thư mục khác nhau. Chúng như sau:

  • Application- Thư mục này chứa ứng dụng của bạn. Nó sẽ chứa hệ thống MVC, cũng như các cấu hình, dịch vụ được sử dụng và tệp bootstrap của bạn.

  • Config - Thư mục này chứa các tệp cấu hình của một ứng dụng.

  • Data - Thư mục này cung cấp một nơi lưu trữ dữ liệu ứng dụng dễ bay hơi và có thể là tạm thời.

  • Module - Mô-đun cho phép một nhà phát triển nhóm một tập hợp các bộ điều khiển liên quan thành một nhóm được tổ chức hợp lý.

  • Public- Đây là gốc tài liệu của ứng dụng. Nó khởi động ứng dụng Zend. Nó cũng chứa các tài sản của ứng dụng như JavaScript, CSS, Hình ảnh, v.v.

  • Vendor - Thư mục này chứa các phụ thuộc của nhà soạn nhạc.

Cấu trúc của các mô-đun ứng dụng

Đây là thư mục chính của ứng dụng của bạn. Zend Framework 2 giới thiệu một hệ thống mô-đun mạnh mẽ và linh hoạt để tổ chức ứng dụng một cách hiệu quả. CácApplicationmô-đun của ứng dụng khung (myapp) cung cấp cấu hình khởi động, lỗi và định tuyến cho toàn bộ ứng dụng. Cấu trúc củaApplication mô-đun như hình dưới đây -

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

Hãy để chúng tôi trình bày chi tiết từng thư mục mô-đun này -

  • Application- Đây là thư mục gốc của module. Tên của thư mục sẽ khớp với tên của mô-đun và tên cũng được sử dụng làm không gian tên PHP của tất cả các lớp được định nghĩa bên trong mô-đun. Nó sẽ chứa hệ thống MVC, cũng như các cấu hình, dịch vụ được sử dụng và tệp bootstrap của bạn.

  • Config - Cấu hình độc lập của mô-đun.

  • Src - Logic nghiệp vụ chính của ứng dụng.

  • View- Chứa các tập tin thiết kế / trình bày (HTML). Ví dụ: index.phtml.

  • src/Module.php- Nó là trái tim của mô-đun. Nó hoạt động như một “bộ điều khiển phía trước” cho mô-đun. Quy trình Zendsrc/Module.php trước khi xử lý bất kỳ Lớp PHP nào trong mô-đun này.

  • Application/config/module.config.php - Nó được thực hiện cho cấu hình bộ định tuyến và tự động tải tệp.

  • Application/view/layout- Bố cục thể hiện các phần chung của nhiều khung nhìn. Ví dụ, đầu trang và chân trang của trang. Theo mặc định, bố cục sẽ được lưu trữ trongviews/layoutsfolder.

Tất cả các mô-đun có chung cấu trúc hoặc cấu trúc tương tự như cấu trúc của mô-đun Ứng dụng ở trên .

Trong chương này, chúng ta sẽ học cách tạo một mô-đun dựa trên MVC trong Zend Framework. Hãy để chúng tôi tạo một mô-đun có tên làTutorial để hiểu quy trình tạo mô-đun.

  • Tạo một lớp PHP mới có tên Module bên trong thư mục –myapp / module / Tutorial / src / và triển khai ConfigProviderInterface.

  • Bộ Tutorial làm không gian tên cho Module lớp học.

  • Viết một hàm công khai getConfig bên trong Module lớp và trả về tệp cấu hình cho Tutorial Mô-đun.

Mã hoàn chỉnh cho Module lớp như sau -

<?php  
namespace Tutorial; 
use Zend\ModuleManager\Feature\ConfigProviderInterface;
class Module implements ConfigProviderInterface { 
   public function getConfig() {    
      return include __DIR__ . '/../config/module.config.php'; 
   }    
}

Định cấu hình Tutorial mô-đun trong composer.json phía dưới cái autoload bằng cách sử dụng mã sau.

"autoload": { 
   "psr-4": { 
      "Application\\": "module/Application/src/", 
      "Tutorial\\": "module/Tutorial/src/" 
   } 
}

Cập nhật ứng dụng bằng trình soạn nhạc update lệnh như hình dưới đây.

composer update

Các composer lệnh sẽ thực hiện thay đổi cần thiết đối với ứng dụng và hiển thị nhật ký trong dấu nhắc lệnh như hình dưới đây:

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

Tạo tệp cấu hình mô-đun, “module.config.php” tại /config/ với mã sau -

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

Tệp cấu hình có ba phần và chúng như sau:

  • Controller configuration - Chỉ định các bộ điều khiển có sẵn bên trong Mô-đun.

  • Routing configuration - Chỉ định cách giải quyết các bộ điều khiển trong mô-đun thành URL.

  • View configuration - Chỉ định cấu hình liên quan đến chế độ xem như vị trí của các chế độ xem, v.v.

Định cấu hình Tutorial mô-đun trong tệp cấu hình mức ứng dụng - myapp / config / modules.config.php.

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

Chạy ứng dụng bằng cách thực thi composer serve ở thư mục gốc của thư mục ứng dụng.

Chúng tôi đã thêm thành công một mô-đun mới, nhưng chúng tôi vẫn cần thêm Controller, RoutingViews để chạy thành công Tutorial mô-đun.

Như đã thảo luận trước đó, controllerđóng một vai trò quan trọng trong Zend MVC Framework. Tất cả các trang web trong ứng dụng cần được bộ điều khiển xử lý.

Trong Zend MVC Framework, bộ điều khiển là các đối tượng triển khai - Zend / Stdlib / DispatchableInterface. CácDispatchableInterface có một phương pháp duy nhất, dispatch, mà có được Request đối tượng làm đầu vào, thực hiện một số logic và trả về Response một đối tượng làm đầu ra.

dispatch(Request $request, Response $response = null)

Một ví dụ đơn giản về đối tượng Controller để trả về “Hello World” như sau:

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!"); 
   } 
}

Các DispatchableInterfacelà cơ bản và nó cần nhiều giao diện khác để viết các bộ điều khiển cấp cao. Một số giao diện như sau:

  • InjectApplicationEventInterface - Được sử dụng để chèn sự kiện (Zend EventManager)

  • ServiceLocatorAwareInterface - Được sử dụng để định vị Dịch vụ (Zend ServiceManager)

  • EventManagerAwareInterface - Dùng để quản lý các sự kiện (Zend EventManager)

Hãy ghi nhớ những điều này, Zend Framework cung cấp rất nhiều bộ điều khiển chế tạo sẵn để triển khai các giao diện này. Các bộ điều khiển quan trọng nhất như được giải thích bên dưới.

AbstractActionController

AbstractActionController (Zend / Mvc / Controller / AbstractActionController) là bộ điều khiển được sử dụng nhiều nhất trong Zend MVC Framework. Nó có tất cả các tính năng cần thiết để viết một trang web điển hình. Nó cho phép các tuyến đường (Định tuyến là đối sánh url yêu cầu với bộ điều khiển và một trong các phương thức của nó) để khớp vớiaction. Khi khớp, một phương thức được đặt tên theo hành động sẽ được bộ điều khiển gọi.

Ví dụ, nếu một tuyến đường test phù hợp và tuyến đường, test trả lại hello cho hành động, sau đó helloAction phương thức sẽ được gọi.

Hãy để chúng tôi viết TutorialController sử dụng AbstractActionController.

  • Tạo một lớp PHP mới được gọi là TutorialController bằng cách mở rộng AbstractActionController và đặt nó trong module/Tutorial/src/Controller/ danh mục.

  • Đặt Tutorial\Controller như không gian tên.

  • Viết một indexAction phương pháp.

  • Trả lại ViewModel đối tượng từ indexActionphương pháp. CácViewModel đối tượng được sử dụng để gửi dữ liệu từ bộ điều khiển đến bộ máy xem, chúng ta sẽ thấy trong các chương tiếp theo.

Danh sách mã hoàn chỉnh như sau:

?php  
namespace Tutorial\Controller;  
use Zend\Mvc\Controller\AbstractActionController; 
use Zend\View\Model\ViewModel;  
class TutorialController extends AbstractActionController { 
   public function indexAction() { 
      return new ViewModel(); 
   } 
}

Chúng tôi đã thêm mới thành công TutorialController.

AbstractRestfulController

AbstractRestfulController (Zend \ Mvc \ Controller \ AbstractRestfulController) kiểm tra HTTP method của yêu cầu đến và khớp với hành động (phương thức) bằng cách xem xét các phương thức HTTP

Ví dụ: yêu cầu với phương thức GET HTTP phù hợp với getList() phương pháp hoặc get() phương pháp, nếu id tham số được tìm thấy trong yêu cầu.

AbstractConsoleController

AbstractConsoleController (Zend \ Mvc \ Controller \ AbstractConsoleController) giống như AbstractActionController ngoại trừ việc nó chỉ chạy trong môi trường console thay vì trình duyệt.

Bản đồ định tuyến Request URIđến phương pháp của bộ điều khiển cụ thể. Trong chương này, chúng ta sẽ xem cách triển khai các tuyến trong Zend Framework.

Nói chung, bất kỳ URI nào cũng có ba phần:

  • Phân đoạn tên máy chủ,
  • Phân đoạn đường dẫn và
  • Phân đoạn truy vấn.

Ví dụ: trong URI / URL - http://www.example.com/index?q=data, www.example.com là Phân đoạn tên máy chủ, index là Phân đoạn Đường dẫn và q=datalà Phân đoạn truy vấn. Nói chung, định tuyến kiểm traPage segmentchống lại một tập hợp các ràng buộc. Nếu bất kỳ ràng buộc nào phù hợp, thì nó trả về một tập hợp các giá trị. Một trong những giá trị chính là bộ điều khiển.

Định tuyến cũng kiểm tra phân đoạn máy chủ lưu trữ, phân đoạn truy vấn, yêu cầu phương thức HTTP, yêu cầu tiêu đề HTTP, v.v., trong một tình huống nhất định.

Route & RouteStack

Tuyến là đối tượng chính trong định tuyến. Zend Framework có một giao diện đặc biệt cho đối tượng định tuyến,RouteInterface. Tất cả đối tượng định tuyến cần triển khai RouteInterface. Danh sách đầy đủ của RouteInterface như sau:

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

Phương pháp chính là match. Phương thức đối sánh này kiểm tra yêu cầu đã cho dựa trên ràng buộc được xác định trong đó. Nếu tìm thấy bất kỳ kết quả phù hợp nào, nó sẽ trả vềRouteMatchvật. Đối tượng RouteMatch này cung cấp các chi tiết của yêu cầu đã so khớp dưới dạng các tham số. Các tham số này có thể được trích xuất từRouteObject sử dụng getParams phương pháp.

Danh sách đầy đủ của RouteObject như sau:

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

Nói chung, một ứng dụng MVC điển hình có nhiều tuyến đường. Mỗi tuyến đường này sẽ được xử lý theo thứ tự LIFO và một tuyến đường duy nhất sẽ được khớp và trả về. Nếu không có tuyến nào được khớp / trả về, thì ứng dụng sẽ trả về lỗi “Không tìm thấy trang”. Zend Framework cung cấp một giao diện để xử lý các tuyến đường,RouteStackInterface. RouteStackInterface này có tùy chọn thêm / bớt các tuyến đường.

Danh sách đầy đủ của RouteStackInterface như sau:

namespace Zend\Mvc\Router;  
interface RouteStackInterface extends RouteInterface { 
   public function addRoute($name, $route, $priority = null); public function addRoutes(array $routes); 
   public function removeRoute($name); public function setRoutes(array $routes); 
}

Zend framework cung cấp hai cách triển khai RouteStack giao diện và chúng như sau:

  • SimpleRouteStack
  • TreeRouteStack

Loại tuyến đường

Khung công tác Zend cung cấp rất nhiều đối tượng định tuyến được tạo sẵn cho tất cả các tình huống trong không gian tên "Zend \ Mvc \ Router \ Http". Chỉ cần chọn và sử dụng đối tượng định tuyến thích hợp cho tình huống nhất định là đủ.

Các tuyến đường có sẵn như sau:

  • Hostname - Được sử dụng để khớp với phần máy chủ của URI.

  • Literal - Được sử dụng để đối sánh URI chính xác.

  • Method - Được sử dụng để khớp với phương thức HTTP của yêu cầu gửi đến.

  • Part - Được sử dụng để khớp một phần của đoạn đường dẫn URI bằng cách sử dụng logic tùy chỉnh.

  • Regex - Được sử dụng để khớp với phân đoạn đường dẫn URI bởi Regex Pattern.

  • Schema - Được sử dụng để khớp với Lược đồ URI như http, https, v.v.

  • Segment - Được sử dụng để khớp với đường dẫn URI bằng cách chia nó thành nhiều đoạn.

Hãy để chúng tôi xem cách viết Route theo nghĩa đen và đoạn được sử dụng phổ biến nhất. Các tuyến thường được chỉ định trong tệp cấu hình của mỗi mô-đun -module.config.php.

Tuyến đường theo nghĩa đen

Thông thường, các tuyến được truy vấn theo thứ tự LIFO. Lộ trình Literal là để thực hiện đối sánh chính xác đường dẫn URI.

Nó được định nghĩa như hình dưới đây -

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

Tuyến đường trên phù hợp với /path trong url yêu cầu và trả về index như là actionIndexController với tư cách là người điều khiển.

Tuyến đường phân đoạn

Một tuyến đường được phân đoạn được sử dụng cho bất cứ khi nào url của bạn được cho là chứa các tham số biến đổi.

Nó được mô tả như dưới đây:

$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',), 
));

Ở đây, Phân đoạn được biểu thị bằng dấu hai chấm và theo sau là các ký tự chữ và số. Nếu bạn giữ một đoạn là tùy chọn thì nó được bao bởi dấu ngoặc. Mỗi phân đoạn có thể có các ràng buộc liên quan đến nó. Mỗi ràng buộc là một biểu thức chính quy.

Định cấu hình tuyến đường trong mô-đun hướng dẫn

Hãy để chúng tôi thêm một tuyến đường phân đoạn trong mô-đun Hướng dẫn của chúng tôi. Cập nhật tệp cấu hình mô-đun hướng dẫn -module.config.php có sẵn tại 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',], 
   ], 
];

Chúng tôi đã thêm thành công định tuyến cho Tutorialmô-đun. Chúng tôi chỉ chậm một bước trong việc hoàn thành mô-đun Hướng dẫn của chúng tôi. Chúng tôi cần thêmView cho mô-đun của chúng ta, mà chúng ta sẽ tìm hiểu trong chương tiếp theo.

Lớp View là lớp trình bày của ứng dụng MVC. Nó tách logic ứng dụng khỏi logic trình bày. Trong một ứng dụng web PHP điển hình, tất cả logic nghiệp vụ và thiết kế được trộn lẫn với nhau. Trộn lẫn cho phép phát triển nhanh hơn trong một dự án nhỏ. Nhưng, nó thất bại thảm hại trong một dự án lớn, nơi có nhiều kiến ​​trúc cấp cao tham gia. Để thay đổi thiết kế của ứng dụng web, một nhà phát triển cũng cần phải làm việc trên logic nghiệp vụ. Điều này có thể là thảm họa dẫn đến phá vỡ logic kinh doanh.

Zend Framework cung cấp một lớp View tốt, sạch sẽ, linh hoạt và có thể mở rộng. Lớp View có sẵn dưới dạng một mô-đun riêng biệt,Zend/View và tích hợp tốt với Zend/Mvcmô-đun. Lớp Zend View được tách thành nhiều thành phần tương tác độc đáo với nhau.

Các thành phần khác nhau của nó như sau:

  • Variables Containers - Lưu trữ dữ liệu của lớp xem.

  • View Models - Giữ các Container có thể thay đổi và mẫu thiết kế.

  • Renderers - Xử lý dữ liệu và mẫu từ View Model và xuất ra biểu diễn thiết kế, có thể là đầu ra html cuối cùng.

  • Resolvers - Giải quyết mẫu có sẵn trong View Model theo cách mà Trình kết xuất có thể sử dụng.

  • View (Zend\View\View) - Bản đồ yêu cầu trình kết xuất và sau đó trình kết xuất phản hồi.

  • Rendering Strategies - Được sử dụng bởi View để ánh xạ yêu cầu đến trình kết xuất.

  • Response Strategies - Được sử dụng bởi View để trình kết xuất bản đồ phản hồi.

Lớp xem, View xử lý ViewModel, giải quyết mẫu bằng cách sử dụng Resolver, kết xuất nó bằng cách sử dụng Rendering Strategy và cuối cùng xuất ra nó bằng cách sử dụng Response Renderer.

Xem cấu hình lớp

Giống như bộ điều khiển, một lớp Xem có thể được định cấu hình trong tệp cấu hình của mô-đun được gọi là - module.config.php. Cấu hình chính là chỉ định nơi các mẫu sẽ được đặt. Điều này có thể được thực hiện bằng cách thêm cấu hình sau vào “module.config.php”.

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

Theo mặc định, lớp View có một hành vi mặc định cho tất cả các thành phần của nó. Ví dụ, mộtViewModelgiải quyết tên mẫu của hành động của bộ điều khiển bên trong gốc mẫu theo quy tắc “lowercase-module-name / lowercase-controller-name / lowercase-action-name”. Tuy nhiên, điều này có thể bị ghi đè bởisetTemplate() của ViewModel.

Bộ điều khiển và Lớp xem

Theo mặc định, bộ điều khiển không cần gửi bất kỳ dữ liệu nào đến lớp xem. Chỉ cần viết mẫu ở vị trí thích hợp là đủ.

Ví dụ, trong ví dụ của chúng tôi, TutorialController, mẫu cần được đặt tại myapp/module/Tutorial/view/tutorial/tutorial/index.phtml. Cácindex.phtmlđề cập đến mẫu dựa trên PHP và nó sẽ được PHPRenderer kết xuất. Có các trình kết xuất khác nhưJsonRenderer cho json đầu ra và FeedRenderer cho rssatom đầu ra.

Danh sách đầy đủ như sau:

<?php  
namespace Tutorial\Controller;  
use Zend\Mvc\Controller\AbstractActionController; 
use Zend\View\Model\ViewModel;  
class TutorialController extends AbstractActionController { 
   public function indexAction() { 
   } 
}

Mẫu ứng dụng Zend

<div class = "row content"> 
   <h3>This is my first Zend application</h3> 
</div>

Cuối cùng, chúng tôi đã hoàn thành thành công Tutorial và chúng tôi có thể truy cập nó bằng cách sử dụng url - http://localhost:8080/tutorial.

Chuyển dữ liệu đến lớp xem

Cách đơn giản nhất để gửi dữ liệu đến lớp xem là sử dụng ViewModeltranh luận. Sự thay đổiindexAction phương pháp như sau:

public function indexAction() { 
   $view = new ViewModel([ 'message' => 'Hello, Tutorial' ]); return $view; 
}

Bây giờ, hãy thay đổi index.phtml tập tin như sau -

<div class = "row content"> 
   <h3>This is my first Zend application</h3> 
   <h4><?php echo $this->message?></h4> 
</div>

Xem người trợ giúp

Một Trình trợ giúp Chế độ xem được sử dụng để viết các hàm nhỏ, nguyên tử được sử dụng trong các mẫu. Zend framework cung cấp một giao diện, Zend \ View \ Helper \ HelperInterface để viết các trình trợ giúp chế độ xem chuẩn.

Một HelperInterface chỉ có hai phương thức,

  • setView() - Phương thức này chấp nhận một phiên bản / triển khai Zend \ View \ Renderer \ RendererInterface.

  • getView() - Nó được sử dụng để truy xuất thể hiện đó.

Danh sách mã hoàn chỉnh của HelperInterface như sau -

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

Để sử dụng một trình trợ giúp trong tập lệnh xem của bạn, hãy truy cập nó bằng $this->helperName().

Người trợ giúp tích hợp

Zend Framework cung cấp rất nhiều chức năng trợ giúp có sẵn cho các mục đích khác nhau. Một số Trình trợ giúp Chế độ xem có sẵn trongzend-mvc như sau -

URL

Trình trợ giúp URL được sử dụng để tạo các URL khớp với các tuyến được xác định trong ứng dụng.

Định nghĩa của trình trợ giúp URL là -

$this->url($name, $params, $options, $reuseMatchedParameters)

Ví dụ: trong mô-đun hướng dẫn, tuyến đường được đặt tên là tutorial và nó có hai tham số actionid. Chúng tôi có thể sử dụng trình trợ giúp URL để tạo hai URL khác nhau như được hiển thị bên dưới -

<a href = "<? = $this->url('tutorial'); ?>">Tutorial Index</a>  
<a href = "<? = $this->url('tutorial', ['action' => 'show', 'id' =>10]); ?>"> 
   Details of Tutorial #10 
</a>

Kết quả sẽ như sau:

<a href = "/tutorial">Tutorial Index</a>  
<a href = "/tutorial/show/10"> Details of Tutorial #10</a>

Trình giữ chỗ

Trình trợ giúp giữ chỗ được sử dụng để duy trì nội dung giữa các tập lệnh xem và các phiên bản xem. Nó cung cấp tùy chọn để thiết lập dữ liệu ban đầu và sau đó sử dụng nó trong các giai đoạn sau.

Ví dụ, chúng ta có thể đặt, nói company name và sau đó sử dụng nó ở tất cả các nơi khác.

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

Trình giữ chỗ cung cấp một số tùy chọn nâng cao để tạo nội dung phức tạp từ mảng và đối tượng PHP. Nó cũng có tùy chọn để nắm bắt phần nhất định của chính mẫu.

Ví dụ: đoạn mã sau ghi lại kết quả mẫu ở giữa và lưu trữ nó trong productlist trình giữ chỗ.

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

Trình trợ giúp Doctype được sử dụng để tạo các loại tài liệu html khác nhau. Đó là việc thực hiện cụ thểPlaceholderngười giúp đỡ. Loại tài liệu có thể được đặt trong tệp bootstrap và tệp cấu hình.

Cách sử dụng cơ bản được hiển thị bên dưới -

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

Trình trợ giúp HeadTitle được sử dụng để tạo phần tử tiêu đề html. Đó là việc thực hiện cụ thểPlaceholderngười giúp đỡ. Zend cung cấp một tùy chọn để đặt tiêu đề trong tệp cấu hình mô-đun và nó có thể được đặt ở bất kỳ cấp nào như trang web, mô-đun, bộ điều khiển, hành động, v.v. Một phần mã cho HeadTitle như sau:

Module

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

Template

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

Result

action - controller - module - Zend Framework

HeadMeta

Trình trợ giúp HeadMeta được sử dụng để tạo các thẻ meta html. Đó là một triển khai cụ thể của Trình trợ giúp Trình giữ chỗ.

Template -

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

Result

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

HeadLink

Trình trợ giúp HeadLink được sử dụng để tạo các liên kết html để bao gồm các tài nguyên bên ngoài. Đó là triển khai cụ thể của Trình trợ giúp Trình giữ chỗ.

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

Trình trợ giúp HeadStyle được sử dụng để tạo các kiểu CSS nội tuyến. Đó là triển khai cụ thể của Trình trợ giúp Trình giữ chỗ.

Template

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

HeadScript

HeadScript được sử dụng để tạo tập lệnh nội tuyến hoặc bao gồm các tập lệnh bên ngoài. Đó là triển khai cụ thể của Trình trợ giúp Trình giữ chỗ.

Template

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

InlineScript

InlineScript được sử dụng để tạo tập lệnh trong cả phần đầu và phần nội dung của mẫu html. Nó có nguồn gốc từ HeadScript.

HTMLList

HTMLList được sử dụng để tạo danh sách có thứ tự và không có thứ tự. Định nghĩa của HTMLList như sau:

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>

Đi xe đạp

Chu trình được sử dụng để tạo ra các lựa chọn thay thế trong môi trường vòng lặp. Nó có chức năng gán, tiếp theo và trước.

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>

Một số trợ giúp quan trọng khác được tích hợp sẵn như sau:

  • BasePath - BasePath được sử dụng để tạo đường dẫn của thư mục chung của thư mục gốc của ứng dụng.

  • Partial - Một phần được sử dụng để kết xuất một mẫu cụ thể trong phạm vi biến của riêng nó.

  • PartialLoop - PartialLoop giống như Partial, nhưng được sử dụng trong môi trường lặp.

  • Identity - Danh tính được sử dụng để truy xuất danh tính của người dùng đã đăng nhập từ Dịch vụ xác thực.

  • JSON- JSON được sử dụng trong môi trường yên tĩnh, nơi đầu ra có định dạng JSON. Nó phát ra tiêu đề HTTP thích hợp và vô hiệu hóa khái niệm bố cục.

Vẫn còn rất nhiều trợ giúp có sẵn trong Zend Framework chẳng hạn như i18n helper, form helpers, pagination helpers, navigation helpers, Vân vân.

Tạo View Helpers

Zend Framework cung cấp một AbstractHelper thực thi HelperInterface để viết trợ giúp xem.

Các bước liên quan đến việc viết một trình trợ giúp mới như sau:

  • Step 1 - Mở rộng lớp Zend \ View \ Helper \ AbstractHelper.

  • Step 2 - Ghi đè __invoke() chức năng.

  • Step 3 - Đặt cấu hình trong module.config.php file.

  • Step 4 - Sử dụng trình trợ giúp chế độ xem trong các tập lệnh xem.

Bây giờ chúng ta hãy tạo một TestHelper

Tạo thư mục Người trợ giúp tại myapp/module/Tutorial/src/View directory. ViếtTestHelper bên trong thư mục Người trợ giúp, TestHelper.php.

Danh sách đầy đủ như sau:

<?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'); 
   } 
}

Đặt cấu hình trong module.config.php.

'view_helpers' => [ 
   'aliases' => [ 
      'testHelper' => View\Helper\TestHelper::class, 
   ], 
   'factories' => [ 
      View\Helper\TestHelper::class => InvokableFactory::class, 
   ],
],

Sử dụng cái mới được tạo TestHelper bên trong about xem kịch bản.

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

Bố cục đại diện cho các phần chung của nhiều dạng xem, ví dụ, đầu trang và chân trang của trang. Theo mặc định, bố cục sẽ được lưu trữ trongview/layout thư mục.

Cấu hình Bố cục được xác định trong view_manager trong module.config.php.

Cấu hình mặc định của ứng dụng khung như sau:

'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', 
),

Đây, template_mapđược sử dụng để chỉ định bố cục. Nếu không tìm thấy bố cục thì nó sẽ trả về lỗi. Hãy để chúng tôi xem bố cục chính của ứng dụng khung xương.

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>

Khi bạn phân tích bố cục, nó chủ yếu sử dụng trình trợ giúp chế độ xem, mà chúng ta đã thảo luận trong chương trước. Khi chúng ta xem xét kỹ hơn, bố cục sử dụng một biến đặc biệt,$this->content. Biến này rất quan trọng vì nó sẽ được thay thế bằng tập lệnh xem (mẫu) của trang được yêu cầu thực tế.

Tạo bố cục mới

Hãy để chúng tôi tạo một bố cục mới cho mô-đun Hướng dẫn của chúng tôi.

Để bắt đầu, hãy để chúng tôi tạo tutorial.css file trong thư mục “public / css”.

body { 
   background-color: lightblue; 
} 
h1 { 
   color: white; 
   text-align: center; 
}

Tạo một tệp bố cục mới newlayout.phtmltại / myapp / module / Tutorial / view / layout / và sao chép nội dung từ bố cục hiện có. Sau đó, thêmtutorial.css bảng định kiểu bằng cách sử dụng HeadLink lớp trợ giúp bên trong phần đầu bố cục.

<?php echo $this->headLink()->appendStylesheet('/css/tutorial.css');?>

Thêm mới about liên kết trong phần điều hướng bằng cách sử dụng URL người giúp đỡ.

<li><a href = "<?= $this->url('tutorial', ['action' => 'about']) ?>">About</a></li>

Trang bố cục này là chung cho ứng dụng mô-đun hướng dẫn. Cập nhậtview_manager của tệp cấu hình mô-đun hướng dẫn.

'view_manager' => array( 
   'template_map' => array( 
      'layout/layout' => __DIR__ . '/../view/layout/newlayout.phtml'), 
   'template_path_stack' => array('tutorial' => __DIR__ . '/../view',), 
)

Thêm aboutAction chức năng trong TutorialController.

public function aboutAction() { 
}

Thêm about.phtml tại myapp / module / Tutorial / view / tutorial / tutorial / với nội dung sau.

<h2>About page</h2>

Bây giờ, bạn đã sẵn sàng để chạy ứng dụng cuối cùng - http://localhost:8080/tutorial/about.

Trong chương này, chúng ta sẽ thảo luận về các mô hình khác nhau và cơ sở dữ liệu của Zend Framework.

Mô hình trong Zend Framework

Mô hình xác định biểu diễn dữ liệu lôgic của ứng dụng. Ví dụ, trong ứng dụng giỏ hàng - Sản phẩm, Khách hàng, Giỏ hàng và Đơn đặt hàng là các mô hình. Chúng xác định các thuộc tính của thực thể mà nó nắm giữ. Một số khái niệm về mô hình như sau:

  • Bộ điều khiển giao tiếp với các mô hình và yêu cầu họ truy xuất thông tin họ cần. Thông tin được truy xuất này sau đó được bộ điều khiển chuyển đến Chế độ xem. Cuối cùng, View sẽ hiển thị mô hình dưới dạng dữ liệu trình bày có thể sử dụng được của người dùng.

  • Rất hiếm khi mô hình tương tác trực tiếp với một khung nhìn, nhưng đôi khi nó có thể xảy ra.

  • Người mẫu có thể nói chuyện với nhau và không khép kín. Họ có quan hệ với nhau. Các mối quan hệ này giúp bộ điều khiển lấy thông tin dễ dàng và nhanh chóng hơn, vì nó không phải tương tác với các mô hình khác nhau; các mô hình có thể tự làm điều đó.

Hãy để chúng tôi xem xét một mô hình đơn giản - MyModel

<?php  
namespace Tutorial\Model;  
class Book { 
   public $id; public $author; 
   public $title; 
}

Cơ sở dữ liệu trong Zend Framework

Zend framework cung cấp một lớp đơn giản và giàu tính năng, Zend \ Db \ TableGateway \ TableGateway để tìm, chèn, cập nhật và xóa dữ liệu khỏi bảng cơ sở dữ liệu.

Hãy để chúng tôi xem cách kết nối MySqlservice thông qua trình điều khiển PDO của PHP trong khung công tác Zend thông qua các bước sau.

Bước 1: Tạo cơ sở dữ liệu trong MySQL

Tạo nên cơ sở dữ liệu tutorialstrong máy chủ MySQL cục bộ. Chúng ta có thể sử dụngphpmyadminhoặc bất kỳ công cụ MySQL GUI nào khác cho mục đích này. Hãy để chúng tôi sử dụngMySQL clienttrong dấu nhắc lệnh. Kết nối với máy chủ mysql và chạy lệnh sau để tạotutorial cơ sở dữ liệu.

create database tutorials

Bước 2: Tạo bảng trong db hướng dẫn

Bây giờ chúng ta hãy tạo một cơ sở dữ liệu book bên trong tutorials db bằng cách sử dụng lệnh SQL sau.

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

Bước 3: Nhập dữ liệu vào bảng sách

Điền vào bookbảng với dữ liệu mẫu. Sử dụng lệnh SQL sau.

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');

Bước 4: Cập nhật kết nối cơ sở dữ liệu

Cập nhật tệp cấu hình chung, là - myapp / config / autoload / global.php với thông tin ổ đĩa cơ sở dữ liệu cần thiết.

<?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', 
      ), 
   ), 
);

Bước 5: Cập nhật thông tin đăng nhập cơ sở dữ liệu

Cập nhật thông tin đăng nhập cơ sở dữ liệu trong tệp cấu hình cục bộ, đó là - myapp / config / autoload / local.php. Bằng cách này, chúng ta có thể phân tách thông tin xác thực kết nối cơ sở dữ liệu cục bộ và cơ sở dữ liệu trực tiếp.

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

Bước 6: Tạo mô hình cho sách

Hãy để chúng tôi tạo một Mô hình, Book trong mô-đun của chúng tôi srcdanh mục. Nói chung, các mô hình được nhóm trong thư mục Model - /myapp/module/Tutorial/src/Model/Book.php.

<?php  
namespace Tutorial\Model;  
class Book { 
   public $id; 
   public $author; public $title; 
}

Bước 7: Triển khai ExchangeArray trong mô hình sách

Các TableGateway tương tác với một mô hình thông qua exchangeArraychức năng. Đối số tiêu chuẩn của hàm exchangeArray là tập kết quả cơ sở dữ liệu được lưu trữ dưới dạng mảng PHP. Sử dụngexchangeArrayfunction, thuộc tính của một mô hình có thể được đồng bộ hóa dễ dàng với bảng cơ sở dữ liệu tương ứng.

Cập nhật mô hình, Book như hình dưới đây -

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

Bước 8: Sử dụng TableGateway để tìm nạp sách

Tạo một lớp học, BookTableđể lấy thông tin sách từ cơ sở dữ liệu. Tạo lớp học, BookTable trongModel thư mục chính nó.

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

Chúng tôi vừa dùng select()phương thức của lớp TableGateway để lấy thông tin sách từ cơ sở dữ liệu. Nhưng, chúng tôi chưa sử dụng bất kỳ tham chiếu nào đến bảng -booktrong mã. TableGateway về bản chất là chung và nó có thể tìm nạp dữ liệu từ bất kỳ bảng nào bằng cách sử dụng cấu hình nhất định. Thông thường, các cấu hình này được thực hiện trongmodule.config.php mà chúng ta sẽ thảo luận trong các bước tiếp theo.

Bước 9: Định cấu hình lớp BookTable

Cập nhật mô-đun hướng dẫn, Module.php với getServiceConfig() phương pháp.

<?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);
            },
         ],
      ];
   }
}

Ở đây, chúng tôi đã đăng ký BookTablelớp sử dụng trình quản lý dịch vụ. Lớp BookTable được sử dụng để lấy thông tin sách và bằng cách đăng ký, chúng ta có thể truy cập bất cứ khi nào cần. Do đó, các dịch vụ đã đăng ký được chia sẻ, chúng làm tăng hiệu suất, giảm mức tiêu thụ bộ nhớ, v.v.

Một mục khác, lớp Model \ BookTableGateway :: là đối tượng TableGateway chuyên dụng cho Book mô hình và là sự phụ thuộc của BookTable.

Bước 10: Cập nhật cấu hình TutorialController

Chúng tôi cần BookTabledịch vụ trong bộ điều khiển hướng dẫn để tìm nạp thông tin sách. Để có được dịch vụ BookTable, hãy đăng ký nó dưới dạng phụ thuộc hàm tạo trong TutorialController.

Sự phụ thuộc của Constructor này giúp nhận được dịch vụ BookTable trong khi bản thân bộ điều khiển đang ở giai đoạn khởi tạo. Cập nhật phần bộ điều khiển của cấu hình mô-đun hướng dẫn,module.config.php như hình bên dưới.

'controllers' => [ 
   'factories' => [ 
      Controller\TutorialController::class => function($container) { 
         return new Controller\TutorialController( 
            $container->get(Model\BookTable::class) 
         ); 
      }, 
   ], 
],

Bước 11: Cập nhật bộ điều khiển hướng dẫn

Điều này được thực hiện bằng cách tuân thủ ba bước sau.

  • Thêm hàm tạo với BookTable làm đối số.
private $table;
public function __construct(BookTable $table) { $this->table = $table; 
}
  • Tìm nạp thông tin sách bằng cách sử dụng BookTable's fetchAll() và đăng ký nó vào chế độ xem.

public function indexAction() { 
   $view = new ViewModel([ 
      'data' => $this->table->fetchAll(), ]); return $view; 
}
  • Hiển thị thông tin sách trong tập lệnh xem.

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

Bước 12: Chạy ứng dụng

Kiểm tra ứng dụng bằng cách chạy - http://localhost:8080/tutorial.

Như đã thảo luận trong chương trước, khung công tác Zend cung cấp một cách chung để truy cập cơ sở dữ liệu bằng cách sử dụng Database DriverÝ tưởng. Làm việc với cơ sở dữ liệu chỉ phụ thuộc vào thông tin trình điều khiển và do đó, kết nối với cơ sở dữ liệu khác nhau chỉ liên quan đến việc thay đổi thông tin trình điều khiển.

Bây giờ hãy để chúng tôi thay đổi book ví dụ để kết nối với postgresql cơ sở dữ liệu với các bước sau.

Step 1 - Tạo cơ sở dữ liệu, hướng dẫn trong cơ sở dữ liệu postgresql cục bộ bằng lệnh sau:

CREATE DATABASE tutorials

Step 2 - Thêm bookbàn. Di chuyển đến cơ sở dữ liệu mới và thực thi tập lệnh tạo bảng.

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

Step 3 - Thêm thông tin sách mẫu bằng cách sử dụng tập lệnh sau -

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 - Thay đổi thông tin trình điều khiển trong global.config file.

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

Step 5 - Thay đổi thông tin đăng nhập cơ sở dữ liệu trong local.config tập tin.

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

Step 6 - Cuối cùng, chạy ứng dụng http://localhost:8080/tutorial. Kết quả giống như ứng dụng MySQL.

Zend Framework cung cấp một thành phần riêng biệt, zend-formđể đẩy nhanh quá trình tạo và xác nhận biểu mẫu. Nó kết nối mô hình và lớp xem. Nó cung cấp một tập hợp các phần tử biểu mẫu để tạo biểu mẫu html chính thức từ các mô hình được xác định trước,InputFilter lớp để xác thực mô hình so với biểu mẫu và các tùy chọn để ràng buộc dữ liệu từ biểu mẫu với mô hình và ngược lại.

Cài đặt thành phần biểu mẫu

Thành phần biểu mẫu Zend có thể được cài đặt bằng cách sử dụng Composer lệnh như được chỉ định bên dưới -

composer require zendframework/zend-form

Khung biểu mẫu Zend có ba thành phần con để quản lý các biểu mẫu. Chúng được giải thích chi tiết bên dưới -

  • Elements - Được sử dụng để xác định một điều khiển đầu vào html duy nhất được ánh xạ tới một thuộc tính trong mô hình.

  • Fieldset - Được sử dụng để nhóm các phần tử và các fieldset theo cách lồng nhau.

  • Form - Được sử dụng để tạo một biểu mẫu html và bao gồm các phần tử và tập trường.

Biểu mẫu Zend thường được tạo theo module//src/Form danh mục.

Thí dụ

Bây giờ chúng ta hãy tạo một biểu mẫu đơn giản để thêm bookvào cơ sở dữ liệu. Để làm điều này, chúng ta nên tuân thủ các bước sau:

Bước 1: Tạo BookForm

Tạo “BookForm.php” trong thư mục * myapp / module / Tutorial / src / Form ”. Thêm các thay đổi sau vào tệp -

<?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', 
         ), 
      )); 
   } 
}

Các Form lớp học cung cấp một add methodđể lập bản đồ mô hình và các chi tiết hình thức tương ứng của nó. chúng tôi đã tạo raBookForm bằng cách mở rộng Form lớp và thêm chi tiết biểu mẫu cho Book mô hình.

Bước 2: Cập nhật mô hình sách, Book.php

Cập nhật mô hình, ‘Book’ với bộ lọc và xác thực như được chỉ định bên dưới -

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

Mỗi mô hình nên triển khai InputFilterAwareInterface. InputFilterAwareInterface cung cấp hai phương thức,setInputFilter()getInputFilter().

GetInputFilter được sử dụng để lấy các chi tiết xác thực của mô hình. Zend framework cung cấp một bộ lọc và trình xác thực phong phú để xác thực biểu mẫu. Một số bộ lọc và trình xác thực được sử dụng trong mô hình sách như sau:

  • StripTags - Loại bỏ HTML không mong muốn.

  • StringTrim - Loại bỏ khoảng trắng không cần thiết.

  • StringLength validator - Đảm bảo rằng người dùng không nhập nhiều ký tự hơn giới hạn đã chỉ định.

Bước 3: Cập nhật lớp BookTable

Bao gồm cái saveBook phương pháp thêm sách vào cơ sở dữ liệu.

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

Bước 4: Cập nhật lớp TutorialController

Thêm một addAction hành động mới trong bộ điều khiển hướng dẫn - 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); 
}

Các addAction phương pháp thực hiện các quá trình sau:

  • Nhận đối tượng yêu cầu.

  • Kiểm tra xem phương thức http của yêu cầu có phải là post phương pháp.

  • Nếu phương thức http của yêu cầu không phải là post, nó chỉ hiển thị mẫu, add.phtml

  • Nếu phương thức http của yêu cầu không phải là post, sau đó nó đặt inputfilter, lấy dữ liệu yêu cầu và đặt nó vào inputfiler.

  • Kiểm tra xem biểu mẫu có hợp lệ hay không bằng cách sử dụng isValid() phương thức của lớp Form.

  • Nếu biểu mẫu không hợp lệ, nó lại hiển thị mẫu, add.phtml

  • Nếu biểu mẫu hợp lệ, nó sẽ lưu sách vào cơ sở dữ liệu và chuyển hướng đến trang chủ.

Bước 5: Thêm mẫu add.phtml

Tạo một mẫu - add.phtml trong 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(); 
}

Ở đây, chúng tôi đang kết xuất biểu mẫu sách bằng cách sử dụng Form ví dụ, $form.

Bước 6: Chạy ứng dụng

Bây giờ, chúng ta có thể chạy ứng dụng - http://localhost:8080/tutorial/add.

Form Page

Validate Error Page

Tải lên tệp là một trong những khái niệm chính trong lập trình biểu mẫu. Zend framework cung cấp tất cả các mục cần thiết để tải tệp lên thông quazend-formzend-inputfilter thành phần.

Lớp FileInput

Thành phần zend-inputfilter cung cấp lớp Zend \ InputFilter \ FileInput để xử lý phần tử đầu vào tệp html - <input type = 'file' />. CácFileInputgiống như các bộ lọc đầu vào khác với một vài ngoại lệ. Chúng như sau:

  • Vì PHP lưu chi tiết tệp được tải lên trong $_FILES mảng toàn cầu, FileInput chỉ thu thập thông tin tệp đã tải lên thông qua $ _FILES.

  • Việc xác thực cần được thực hiện trước khi lớp FileInput xử lý dữ liệu. Đây là hành vi ngược lại với các bộ lọc đầu vào khác.

  • Zend \ Validator \ File \ UploadFile là trình xác thực mặc định được sử dụng. CácUploadFile xác thực chi tiết đầu vào của tệp.

Để thêm loại tải lên tệp trong biểu mẫu, chúng ta cần sử dụng loại đầu vào File. Mã một phần như sau:

$form->add(array( 
   'name' => 'imagepath', 
   'type' => 'File', 
   'options' => array('label' => 'Picture',), 
));

Một lớp khác được sử dụng trong quá trình tải lên tệp là Zend \ Filter \ File \ RenameUpload. CácRenameUploadđược sử dụng để di chuyển tệp đã tải lên đến vị trí mong muốn của chúng tôi. Lớp một phần để sử dụng bộ lọc tệp như sau:

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

Tại đây, các tùy chọn của RenameUpload như sau -

  • target - Đường dẫn đích của tệp được tải lên.

  • randomize - Thêm một chuỗi ngẫu nhiên để tránh trùng lặp tệp đã tải lên.

  • use_upload_extension - Nối phần mở rộng tệp vào tệp đã tải lên đến đích.

Tải lên tệp - Ví dụ làm việc

Hãy để chúng tôi sửa đổi mô-đun hướng dẫn và bao gồm tính năng tải ảnh lên.

Sửa đổi bảng cơ sở dữ liệu

Hãy để chúng tôi thêm imagepath cột vào bảng sách bằng cách thực hiện lệnh SQL sau:

ALTER TABLE `book` ADD `imagepath` VARCHAR(255) NOT NULL AFTER 'imagepath';

Cập nhật BookForm.php

Thêm phần tử đầu vào tệp để tải ảnh lên ở dạng sách - myapp / module / Tutorial / src / Model / BookForm.php.

Bao gồm mã sau trong __constructmethod của lớp BookForm.

$this->add(array( 
   'name' => 'imagepath', 
   'type' => 'File', 
   'options' => array ('label' => 'Picture',), 
));

Cập nhật Book.php

Thực hiện các thay đổi sau trong lớp Sách - myapp / module / Tutorial / src / Model / Book.php.

  • Thêm một thuộc tính mới imagepath cho bức tranh.

public $imagepath;
  • Cập nhật getInputFilter như hình dưới đây -

    • Thêm FileInput bộ lọc cho phần tử đầu vào tệp.

    • Đặt UploadFile xác thực để xác thực phần tử đầu vào tệp.

    • Định cấu hình RenameUpload để di chuyển tệp đã tải lên đến đích thích hợp.

Danh sách một phần mã như sau:

$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);
  • Cập nhật exchangeArray phương pháp bao gồm imagepathbất động sản. Đường dẫn hình ảnh có thể đến từ một biểu mẫu hoặc một cơ sở dữ liệu. Nếu đường dẫn hình ảnh đến từ một biểu mẫu, định dạng sẽ là một mảng với đặc điểm kỹ thuật sau:

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> 
   } 
}
  • Nếu đường dẫn hình ảnh đến từ cơ sở dữ liệu, nó sẽ là một chuỗi đơn giản. Danh sách mã một phần để phân tích cú pháp một đường dẫn hình ảnh như sau:

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

Danh sách đầy đủ của Book mô hình như sau -

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

Cập nhật BookTable.php

Chúng tôi đã cập nhật BookFormBook model. Bây giờ, chúng tôi cập nhậtBookTable và sửa đổi saveBookphương pháp. Điều này là đủ để bao gồm mục nhập đường dẫn hình ảnh trong mảng dữ liệu,$data.

Danh sách một phần mã như sau:

$data = array('author' => $book->author, 'title' => $book->title, 
   'imagepath' => $book->imagepath 
);

Danh sách mã hoàn chỉnh của BookTable lớp như sau -

<?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: Thông tin tải lên tệp sẽ có sẵn trong $_FILES mảng toàn cầu và nó có thể được truy cập bằng cách sử dụng Request's getFiles()phương pháp. Vì vậy, hãy hợp nhất cả dữ liệu đã đăng và thông tin tải lên tệp như hình dưới đây.

$post = array_merge_recursive( 
   $request->getPost()->toArray(), $request->getFiles()->toArray() 
);

Danh sách đầy đủ của addAction() phương pháp như sau:

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

Cập nhật Chế độ xem của add.phtml

Cuối cùng, thay đổi “add.phtml” và bao gồm phần tử đầu vào tệp imagepath như hình dưới đây:

echo $this->formRow($form->get('imagepath'))."<br>";

Danh sách đầy đủ như sau:

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

Chạy ứng dụng

Cuối cùng, chạy ứng dụng tại http://localhost:8080/tutorial/add và thêm các bản ghi mới.

Kết quả sẽ được hiển thị trong ảnh chụp màn hình sau:

Form Page

Index Page

AJAX là một công nghệ hiện đại trong lập trình web. Nó cung cấp các tùy chọn để gửi và nhận dữ liệu trong trang web một cách không đồng bộ mà không cần làm mới trang. Zend framework cung cấp một tùy chọn để làm việc vớijson mô hình thông qua zend-viewzend-jsonthành phần. Chúng ta hãy tìm hiểu lập trình Zend AJAX trong chương này.

Cài đặt thành phần json

Thành phần Zend json có thể được cài đặt bằng cách sử dụng Composer lệnh như được chỉ định bên dưới -

composer require zendframework/zend-json

Ý tưởng

Zend framework cung cấp hai phương pháp để dễ dàng viết một ứng dụng web hỗ trợ AJAX. Chúng như sau:

  • Các isXmlHttpRequest() phương pháp trong Requestđối tượng - Nếu một yêu cầu AJAX được thực hiện, phương thức isXmlHttpRequest () của đối tượng yêu cầu trả về true, ngược lại là false. Phương pháp này được sử dụng để xử lý một yêu cầu AJAX đúng cách ở phía máy chủ.

if ($request->isXmlHttpRequest()) { 
   // Ajax request 
} else { 
   // Normal request 
}
  • Zend / View / Model / JsonModel - The JsonModel là một sự thay thế cho ViewModelđược sử dụng riêng cho các kịch bản AJAX và REST API. JsonModel cùng vớiJsonStrategy (được định cấu hình trong khối trình quản lý chế độ xem của mô-đun) mã hóa dữ liệu mô hình thành Json và trả về nó dưới dạng phản hồi thay vì lượt xem (phtml).

AJAX - Ví dụ làm việc

Hãy để chúng tôi thêm một trang ajax mới, ajaxtrong mô-đun hướng dẫn và tìm nạp thông tin sách một cách không đồng bộ. Để làm được điều này, chúng ta nên tuân thủ các bước sau.

Bước 1: Thêm JsonStrategy trong cấu hình mô-đun

Cập nhật khối trình quản lý chế độ xem trong tệp cấu hình mô-đun hướng dẫn - myapp / module / Tutorial / config / module.config.php. Sau đó,JsonStrategy sẽ làm việc với JsonModel để mã hóa và gửi dữ liệu json.

'view_manager' => [ 
   'template_map' => array
      ('layout/layout' => __DIR__ . '/../view/layout/newlayout.phtml'), 
   'template_path_stack' => [ 
      'tutorial' => __DIR__ . '/../view', 
   ], 
   'strategies' => array('ViewJsonStrategy',), 
],

Bước 2: Thêm phương thức ajaxAction trong TutorialController.php

Thêm phương thức ajaxAction trong TutorialController.php với đoạn mã sau:

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

Tại đây, ajaxAction sẽ kiểm tra xem yêu cầu gửi đến có phải là AJAX hay không. Nếu yêu cầu đến là AJAX, thìJsonModelsẽ được tạo ra. Nếu không, một bình thườngViewModel sẽ được tạo ra.

Trong cả hai trường hợp, thông tin sách sẽ được tìm nạp từ cơ sở dữ liệu và được điền vào mô hình. Nếu mô hình là JsonModel, thìJsonStrategy sẽ được gọi và nó sẽ mã hóa dữ liệu dưới dạng json và trả về dưới dạng phản hồi.

Các $query->get('showJson') == 1được sử dụng cho mục đích gỡ lỗi. Chỉ cần thêmshowJson=1 trong url và trang sẽ hiển thị dữ liệu json.

Bước 3: Thêm ajax.phtml

Bây giờ, hãy thêm tập lệnh xem ajax.phtmlcho phương thức ajaxAction. Trang này sẽ có một liên kết với nhãn -Load book information.

Nhấp vào liên kết đó sẽ thực hiện yêu cầu AJAX, yêu cầu này sẽ tìm nạp thông tin sách dưới dạng dữ liệu Json và hiển thị thông tin sách dưới dạng bảng được định dạng. Quá trình AJAX được thực hiện bằng cách sử dụngJQuery.

Danh sách mã hoàn chỉnh như sau:

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

Bước 4: Chạy ứng dụng

Cuối cùng, chạy ứng dụng - http://localhost:8080/tutorial/ajax và nhấp vào liên kết Nạp thông tin sách.

Kết quả sẽ như hình dưới đây -

Ajax Page -

Ajax Page with Book Information

Ajax page with debugging information

Cookie là một khái niệm rất quan trọng trong một ứng dụng web. Nó cung cấp tùy chọn để duy trì dữ liệu của người dùng, thường là một phần thông tin nhỏ trong chính trình duyệt trong một khoảng thời gian giới hạn.

Cookie được sử dụng để duy trì trạng thái của ứng dụng web. Zend framework cung cấp một mô-đun cookie bên trongzend-httpthành phần. Zend-http này cung cấp sự trừu tượng hóa HTTP và việc triển khai nó.

Cài đặt thành phần HTTP

Thành phần HTTP có thể được cài đặt dễ dàng bằng cách sử dụng Composer như được chỉ định trong mã bên dưới.

composer require zendframework/zend-http

Ý tưởng

Zend-http cung cấp Zend\Http\Cookieslớp để quản lý cookie. Nó được sử dụng cùng vớiZend\Http\Client, được sử dụng để gửi yêu cầu đến máy chủ web. Cookie có thể được khởi tạo như thể hiện trong đoạn mã bên dưới -

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

Khi máy khách HTTP (Zend \ Http \ Client) lần đầu tiên gửi yêu cầu URI đến máy chủ web, nó không có bất kỳ cookie nào. Sau khi máy chủ web nhận được yêu cầu, nó sẽ bao gồm cookie trong đối tượng phản hồi của nó dưới dạngHTTP Header, Set-Cookievà gửi nó đến máy khách HTTP. Máy khách HTTP sẽ trích xuất cookie từ phản hồi http và gửi lại nó dưới dạng Tiêu đề HTTP tương tự trong yêu cầu tiếp theo. Nói chung, mỗi cookie sẽ được ánh xạ tới một miền và một đường dẫn của miền.

Các phương pháp có sẵn trong Cookies lớp như sau -

  • addCookie(uri) - Nó được sử dụng để thêm cookie vào đối tượng yêu cầu của URI đã cho.

  • getCookie(cookieName, $cookieForm) - Nó được sử dụng để lấy cookie, $ cookieName có sẵn trong URI đã cho, $uri. Đối số thứ ba là cách cookie sẽ được trả lại, chuỗi hoặc mảng.

  • fromResponse(uri) - Nó được sử dụng để trích xuất cookie từ đối tượng phản hồi của URI đã cho.

  • addCookiesFromResponse - Nó giống như fromResponse, nhưng nó trích xuất và thêm lại nó vào đối tượng yêu cầu của URI đã cho.

  • isEmpty() - Nó được sử dụng để tìm liệu Cookie đối tượng có bất kỳ cookie nào hay không.

  • reset() - Nó được sử dụng để xóa tất cả các cookie trong URI đã cho.

Trong chương tiếp theo, chúng ta sẽ thảo luận về quản lý phiên trong Zend Framework.

Phiên là một khái niệm rất quan trọng trong một ứng dụng web. Nó cung cấp tùy chọn để duy trì dữ liệu của người dùng trong máy chủ web trong một khoảng thời gian giới hạn. Zend framework cung cấp một thành phần riêng biệt,zend-session để xử lý thông tin phiên.

Cài đặt một thành phần phiên

Thành phần phiên có thể được cài đặt bằng cách sử dụng Composer như được chỉ định bên dưới -

composer require zendframework/zend-session

Thành phần phiên

Zend framework cung cấp sáu thành phần để xử lý việc quản lý phiên. Tất cả các thành phần này đã được giải thích bên dưới -

  • Zend\Session\Container - API chính để đọc và ghi thông tin phiên.

  • Zend\Session\SessionManager - Nó được sử dụng để quản lý toàn bộ vòng đời của một phiên.

  • Zend\Session\Storage - Điều này được sử dụng để chỉ định cách dữ liệu phiên sẽ được lưu trữ trong bộ nhớ.

  • Zend\Session\SaveHandler - Nó được sử dụng để lưu trữ và truy xuất dữ liệu phiên vào một vị trí thực như RDBMS, Redis, MangoDB, v.v.

  • Zend\Session\Validator - Điều này được sử dụng để bảo vệ phiên khỏi bị tấn công bằng cách kiểm tra chéo địa chỉ và tác nhân người dùng từ xa của yêu cầu ban đầu và sau đó.

  • Zend\Session\Config\SessionConfig - Nó được sử dụng để cấu hình cách phiên hoạt động.

Cấu hình mặc định đủ để hoạt động với một phiên. Sử dụng các thành phần trên, tất cả các khía cạnh của một phiên có thể được xử lý dễ dàng.

Ví dụ về thành phần phiên

Chúng ta hãy tuân thủ các điểm sau để tạo một trang mới để hiểu một phiên trong khung công tác Zend. Theo mặc định, nó đủ để tạo một phiên bản củaContainer lớp để quản lý các phiên.

  • Tạo một hành động mới, sessionAction trong TutorialController.

  • Khởi tạo một Container vật.

$c = new Container();
  • Kiểm tra xem một khóa tùy ý counttồn tại. Nếu khóa không có sẵn, hãy khởi tạocount với giá trị 1. Nếu có, hãy tăng giá trị như thể hiện trong đoạn mã sau.

if (!isset($c->count)) { $c->count = 0; 
} else { 
   $c->count++; 
}
  • Đăng ký số lượng trong ViewModel.

  • Tạo tệp mẫu cho - sessionAction, session.phtml trong myapp / module / Tutorial / view / tutorial / tutorial / session.phtml và sau đó hiển thị count giá trị.

  • Làm mới trang sẽ tăng giá trị của counttrong phiên. Danh sách đầy đủ như sau:

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

Xác thực là một trong những tính năng quan trọng nhất và phải có trong bất kỳ ứng dụng web nào. Zend Framework cung cấp một thành phần riêng biệt để xử lý xác thực, được gọi làzend-authentication.

Cài đặt một thành phần xác thực

Thành phần xác thực có thể được cài đặt bằng cách sử dụng sau Composer chỉ huy.

composer require zendframework/zend-authentication

Ý tưởng

Thông thường, một nhà phát triển viết một hàm php để xác thực chi tiết người dùng dựa trên một nguồn dữ liệu. Sau khi xác thực xong, các chi tiết xác thực vẫn tồn tại cho các yêu cầu tiếp theo. Zend Framework tổng quát hóa khái niệm này và cung cấp hai lớp, được giải thích bên dưới:

Class 1 Zend \ Authentication \ Adapter \ AdaptorInterface

Lớp này cung cấp một phương thức duy nhất, authenticateđể viết logic xác thực. Phương thức xác thực trả về một phiên bản củaZend\Authentication\Result lớp học.

Điều này Resultđối tượng giữ trạng thái xác thực; nhận dạng nếu xác thực thành công và thông báo lỗi nếu xác thực không thành công. Chữ ký của giao diện xác thực và lớp kết quả như sau:

AdaptorInterface

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

Result class

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

Zend Framework cung cấp một triển khai mặc định để xác thực dựa trên cơ sở dữ liệu, ldap, http cơ bản và thông tin đăng nhập. AnAdaptor xác thực nhưng không lưu giữ các chi tiết cho bất kỳ yêu cầu nào trong tương lai.

Lớp 2 Zend \ Authentication \ AuthenticationService

AuthenticationService là thành phần chính, sử dụng bộ điều hợp đã được định cấu hình cho mục đích xác thực. Sau khi xác thực xong, nó sẽ lưu giữ các chi tiết xác thực và cung cấp các phương pháp,hasIdentity() để kiểm tra xem có danh tính hay không, getIdentity() để lấy chi tiết xác thực và clearIdentity() để xóa các chi tiết xác thực.

Danh sách một phần mã để sử dụng AuthenticationService này như sau:

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

Những thứ liên quan đến ủy quyền được đóng gói dưới dạng hai mô-đun riêng biệt, đó là: zend-permissions-aclzend-permissions-rbac. Zend-permissions-acl dựa trên danh sách Access control và zend-permissions-rbac dựa trên danh sách điều khiển truy cập dựa trên vai trò. Chúng cung cấp khái niệm ACL & RBAC trừu tượng ở mức độ cao và hỗ trợ viết đơn đăng ký cấp doanh nghiệp.

Zend Framework cung cấp một thành phần riêng biệt được gọi là zend-mailđể gửi tin nhắn email. Thành phần zend-mail cũng cung cấp một tùy chọn để đọc và viết thư email có tệp đính kèm ở cả định dạng văn bản và html. Gửi email trong Zend dễ dàng hơn và cấu hình đơn giản hơn nhiều.

Chúng ta hãy xem qua các khái niệm email, cài đặt cơ bản, cài đặt nâng cao như truyền tải SMTP, v.v., trong chương này.

Cài đặt cấu phần thư

Thành phần thư có thể được cài đặt bằng lệnh Trình soạn thảo sau.

composer require zendframework/zend-mail

Cấu hình Email Cơ bản

Một email cơ bản bao gồm một hoặc nhiều người nhận, một chủ đề, một nội dung và một người gửi. Zend cung cấpZend\Mail\Messagelớp để tạo một thư email mới. Để gửi một email bằng cách sử dụngzend-mail, bạn phải chỉ định ít nhất một người nhận cũng như nội dung thư.

Mã một phần để tạo một thư mới như sau:

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 cung cấp lớp Zend \ Mail \ Sendmail để gửi thư. Sendmail sử dụng chức năng thư gốc php, mail để gửi thư và chúng ta có thể cấu hình lớp truyền tải bằng cách sử dụng tệp cấu hình php.

Mã hóa một phần bằng Sendmail như sau:

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

Các zend-mail cung cấp nhiều lớp truyền tải và mỗi lớp có thể yêu cầu nhiều tham số bổ sung như tên người dùng, mật khẩu, v.v.

Phương pháp quản lý email

Một số phương pháp quản lý email đáng chú ý như sau:

  • isValid - Thư không có địa chỉ 'Từ' là không hợp lệ.

isValid() : bool
  • setEncoding - Đặt mã hóa tin nhắn.

setEncoding(string $encoding) : void
  • getEncoding - Nhận mã hóa tin nhắn.

getEncoding() : string
  • setHeaders - Soạn các tiêu đề.

setHeaders(Zend\Mail\Headers $headers) : void
  • getHeaders - Truy cập bộ sưu tập tiêu đề.

getHeaders() : Zend\Mail\Headers
  • setFrom- Đặt (ghi đè) Từ địa chỉ. Nó chứa một cặp khóa / giá trị trong đó khóa là tên có thể đọc được của con người và giá trị là địa chỉ email.

setFrom( 
   string|AddressInterface|array|AddressList|Traversable $emailOrAddressList, string|null $name 
) : void
  • addFrom - Thêm địa chỉ 'Từ'.

addFrom( 
   string|AddressInterface|array|AddressList|Traversable $emailOrAddressOrList, string|null $name 
) : void
  • getFrom - Truy xuất danh sách người gửi 'Từ'.

getFrom() : AddressList 
setTo - Overwrite the address list in the To recipients. 
setTo( 
   string|AddressInterface|array|AddressList|Traversable $emailOrAddressList, null|string $name 
) : void
  • setSubject - Đặt giá trị tiêu đề chủ đề thư.

setSubject(string $subject) :void
  • setBody - Đặt nội dung thư.

setBody(null|string|Zend\Mime\Message|object $body) : void

Lớp truyền tải SMTP

Các zend-mail cung cấp các tùy chọn để gửi email bằng máy chủ SMTP thông qua Zend\Mail\Transport\Smtpclass. Nó giống nhưSendmail ngoại trừ việc nó có một số tùy chọn bổ sung để định cấu hình máy chủ lưu trữ SMTP, cổng, tên người dùng, mật khẩu, v.v.

Mã một phần như sau:

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

Đây,

  • name - Tên của máy chủ lưu trữ SMTP.

  • host - Tên máy chủ hoặc địa chỉ IP từ xa.

  • port - Cổng mà máy chủ từ xa đang nghe.

Khái niệm Thư - Ví dụ

Chúng ta hãy làm theo các điểm sau đây để viết một ứng dụng bàn điều khiển php đơn giản để hiểu khái niệm thư.

  • Tạo một thư mục “mailapp”.

  • Tải về zend-mail sử dụng công cụ soạn nhạc.

  • Tạo một tệp php Mail.php bên trong thư mục "mailapp".

  • Tạo tin nhắn bằng cách sử dụng Zend\Mail\Message.

$message = new Message(); $message->addTo('[email protected]'); 
$message->addFrom('[email protected]'); $message->setSubject('Hello!'); 
$message->setBody("My first Zend-mail application!");
  • Tạo lớp truyền tải SMTP và thêm cấu hình cần thiết.

// 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);
  • Gửi email bằng cách sử dụng send phương pháp.

$transport->send($message);

Danh sách đầy đủ, Mail.php như sau:

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

Bây giờ, hãy chạy ứng dụng trong dấu nhắc lệnh php Mail.php. Thao tác này sẽ gửi thư như được định cấu hình trong ứng dụng.

Nói chung, chúng ta có thể gỡ lỗi một ứng dụng PHP bằng cách sử dụng advanced debugger tool hoặc bằng cách sử dụng các lệnh đơn giản như echodie. Trong một kịch bản web, chúng ta cần kiểm tra lôgic nghiệp vụ cũng như lớp trình bày. Các biểu mẫu trong ứng dụng web có thể được kiểm tra bằng cách nhập dữ liệu kiểm tra liên quan để đảm bảo rằng các biểu mẫu đang hoạt động như mong đợi.

Thiết kế của một trang web có thể được kiểm tra thủ công bằng cách sử dụng trình duyệt. Loại quy trình kiểm tra này có thể được tự động hóa bằng cách sử dụng kiểm thử đơn vị. Một bài kiểm tra đơn vị là điều cần thiết trong các dự án lớn. Các bài kiểm tra đơn vị này sẽ giúp tự động hóa quá trình kiểm tra và cảnh báo cho nhà phát triển khi có sự cố.

Thiết lập PHPUnit

Khung công tác Zend tích hợp với khung thử nghiệm đơn vị PHPUnit. Để viết một bài kiểm tra đơn vị cho khung công tác Zend, chúng ta cần thiết lập PHPUnit, có thể dễ dàng thực hiện bằng cách sử dụng lệnh Composer sau đây.

$ composer require --dev phpunit/phpunit

Sau khi thực hiện lệnh trên, bạn sẽ nhận được phản hồi như trong khối mã sau.

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

Bây giờ, khi bạn mở tệp “composer.json”, bạn sẽ thấy những thay đổi sau:

"require-dev": { 
   "phpunit/phpunit": "^5.7" 
}

TestCase và Assertions

Khung công tác Zend cung cấp các lớp trợ giúp để đơn vị kiểm tra bộ điều khiển. CácTestCase là thành phần chính trong một PHPUnit khung để viết các trường hợp kiểm thử và Zend Framework cung cấp một triển khai trừu tượng của TestCase được gọi là AbstractHttpControllerTestCase.

AbstractHttpControllerTestCase này cung cấp nhiều Assertvà có thể nhóm theo chức năng. Chúng như sau:

  • Request Assertions- Được sử dụng để xác nhận yêu cầu http. Ví dụ, khẳng địnhControllerName.

  • CSS Select Assertions - Được sử dụng để kiểm tra HTML phản hồi bằng mô hình HTML DOM.

  • XPath Assertions - Một thay thế cho các xác nhận lựa chọn CSS dựa trên XPath.

  • Redirect Assertions - Dùng để kiểm tra chuyển hướng trang.

  • Response Header Assertions - Được sử dụng để kiểm tra tiêu đề phản hồi như mã trạng thái (khẳng địnhResponseStatusCode)

Tạo thư mục thử nghiệm

Một bài kiểm tra đơn vị có thể được viết riêng cho từng mô-đun. Tất cả mã hóa liên quan đến thử nghiệm cần được tạo bên trongtest thư mục trong thư mục gốc của mô-đun.

Ví dụ: để viết một bài kiểm tra cho TutorialController có sẵn trong mô-đun Tutorial, lớp kiểm tra cần được đặt trong thư mục myapp / module / Tutorial / test / Controller /.

Thí dụ

Hãy để chúng tôi viết một lớp thử nghiệm để kiểm tra đơn vị TutorialController.

Để bắt đầu, chúng ta nên viết một lớp có tên là TutorialControllerTest và mở rộng nó thành AbstractHttpControllerTestCase.

Bước tiếp theo là viết một Setupphương pháp thiết lập môi trường thử nghiệm. Điều này có thể được thực hiện bằng cách gọisetApplicationConfig phương pháp và chuyển tệp cấu hình ứng dụng chính của chúng tôi myapp / config / application.config.php

public function setUp() { 
   $configOverrides = [];  
   $this->setApplicationConfig(ArrayUtils::merge( include __DIR__ . '/../../../../config/application.config.php', $configOverrides 
   )); 
   parent::setUp(); 
}

Viết một hoặc nhiều phương thức và gọi các phương thức xác nhận khác nhau tùy thuộc vào yêu cầu.

$this->assertMatchedRouteName('tutorial');

Chúng tôi đã viết lớp thử nghiệm và danh sách đầy đủ như sau:

<?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'); 
   } 
}

Bây giờ, mở dấu nhắc lệnh, chuyển đến thư mục gốc của ứng dụng và thực thi phpunit có thể thực thi bên trong vendor thư mục.

cd /path/to/app  
./vendor/bin/phpunit ./vendor/bin/phpunit module/
   Tutorial/test/Controller/TutorialControllerTest.php

Kết quả sẽ được hiển thị trong khối mã sau:

PHPUnit 5.7.5 by Sebastian Bergmann and contributors.  
.1 / 1 (100%)  
Time: 96 ms, Memory: 8.00MB  
OK (1 test, 5 assertions)

Sự cố của hệ thống cần được xử lý hiệu quả để hệ thống hoạt động trơn tru. Zend Framework đi kèm với mộtdefault error trappingin và ghi lại lỗi khi chúng xảy ra. Trình xử lý lỗi tương tự này được sử dụng để bắtExceptions.

Trình xử lý lỗi hiển thị lỗi khi gỡ lỗi là đúng và ghi lại lỗi khi gỡ lỗi là sai. Zend Framework có một số lớp ngoại lệ và việc xử lý ngoại lệ được tích hợp sẵn sẽ nắm bắt mọi ngoại lệ chưa được ghi nhận và hiển thị một trang hữu ích.

Xử lý lỗi mặc định

Chúng ta có thể cấu hình cài đặt lỗi mặc định trong tệp cấu hình ứng dụng, myapp / module / Application / config / module.config.php.

Mẫu mã một phần như sau:

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

Ở đây, display_exception, not_found_template, exception_template, error / 404 và error / index là các mục cấu hình liên quan đến lỗi và có thể tự giải thích.

Mục quan trọng nhất trong số này là error/index. Đây là mẫu được hiển thị khi một ngoại lệ xảy ra trong hệ thống. Chúng ta có thể sửa đổi mẫu này, myapp / module / Application / view / error / index.phtml để kiểm soát lượng lỗi được hiển thị.

Trong chương này, chúng ta sẽ học cách tạo một Đơn xin việc hoàn chỉnh dựa trên MVC trong Zend Framework. Làm theo các bước dưới đây.

Bước 1: Module.php

Đầu tiên, chúng ta nên tạo một mô-đun Nhân viên bên trong thư mục - myapp / module / Employee / src / và sau đó triển khai giao diện ConfigProviderInterface.

Mã hoàn chỉnh cho lớp Mô-đun như sau:

<?php  
namespace Employee;  
use Zend\ModuleManager\Feature\ConfigProviderInterface;  
class Module implements ConfigProviderInterface { 
   public function getConfig() {    
      return include __DIR__ . '/../config/module.config.php'; 
   }    
}

Bước 2: composer.json

Định cấu hình Tutorial mô-đun trong composer.json trong phần tự động tải bằng cách sử dụng mã sau.

"autoload": { 
   "psr-4": { 
      "Application\\": "module/Application/src/", 
      "Tutorial\\": "module/Tutorial/src/", 
      "Employee\\": "module/Employee/src/" 
   } 
}

Bây giờ, hãy cập nhật ứng dụng bằng lệnh cập nhật trình soạn nhạc.

composer update

Lệnh Composer sẽ thực hiện các thay đổi cần thiết đối với ứng dụng và hiển thị các bản ghi như được hiển thị trong dấu nhắc lệnh bên dưới.

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

Bước 3: module.config.php cho Mô-đun nhân viên

Tạo tệp cấu hình mô-đun, “module.config.php” trong myapp / module / Employee / config với mã sau.

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

Bây giờ, hãy cấu hình mô-đun Nhân viên trong tệp cấu hình cấp ứng dụng - myapp / config / modules.config.php.

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

Bước 4: EmployeeController

Tạo một lớp PHP mới, EmployeeController bằng cách mở rộng AbstractActionController và đặt nó tại thư mục myapp / module / Employee / src / Controller.

Danh sách mã hoàn chỉnh như sau:

<?php  
namespace Employee\Controller;  
use Zend\Mvc\Controller\AbstractActionController; 
use Zend\View\Model\ViewModel;  
class EmployeeController extends AbstractActionController { 
   public function indexAction() { 
      return new ViewModel(); 
   } 
}

Bước 5: Cấu hình bộ định tuyến

Hãy để chúng tôi thêm một tuyến đường phân đoạn trong mô-đun Nhân viên của chúng tôi. Cập nhật tệp cấu hình mô-đun nhân viên, module.config.php có sẵn tại 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', 
      ], 
   ], 
];

Chúng tôi đã thêm thành công định tuyến cho mô-đun Nhân viên của chúng tôi. Bước tiếp theo là tạo một kịch bản xem cho ứng dụng Nhân viên.

Bước 6: Tạo ViewModel

Tạo một tệp có tên là “index.phtml” trong thư mục myapp / module / Employee / view / worker / worker.

Thêm các thay đổi sau vào tệp -

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

Cuối cùng, chúng ta đã hoàn thành thành công phân hệ Nhân viên. chúng tôi có thể truy cập nó bằng cách sử dụng url sau:http://localhost:8080/employee.

Kết quả

Trong bước tiếp theo, chúng tôi sẽ thực hiện add, editdeletehoạt động dữ liệu trong ứng dụng nhân viên. Để thực hiện các thao tác này, trước tiên chúng ta nên tạo một mô hình cơ sở dữ liệu. Nó được mô tả trong bước tiếp theo.

Bước 7: Tạo mô hình

Hãy để chúng tôi tạo một mô hình, Nhân viên trong mô-đun của chúng tôi src directory. Nói chung, các mô hình được nhóm trong thư mục Model (myapp / module / Employee / src / Model / Employee.php)

<?php  
namespace Employee\Model;  
class Employee { 
   public $id; public $emp_name; 
   public $emp_job; 
}

Bước 8: Bảng MySQL

Tạo cơ sở dữ liệu có tên là tutorials trong máy chủ MYSQL cục bộ bằng cách sử dụng lệnh sau:

create database tutorials;

Hãy để chúng tôi tạo một bảng có tên là employee trong cơ sở dữ liệu bằng cách sử dụng lệnh SQL sau:

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

Chèn dữ liệu vào employee bảng sử dụng truy vấn sau:

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');

Bước 9: Cập nhật cấu hình cơ sở dữ liệu

Cập nhật tệp Cấu hình toàn cầu, myapp / config / autoload / global.php với thông tin ổ đĩa cơ sở dữ liệu cần thiết.

return [
   'db' => [
      'driver' => 'Pdo',
      'dsn' => 'mysql:dbname = tutorials;host=localhost',
      'driver_options' => [PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''],
   ],
];

Bây giờ, Cập nhật thông tin đăng nhập cơ sở dữ liệu trong tệp cấu hình cục bộ - myapp / config / autoload / local.php. Bằng cách này, chúng ta có thể phân tách thông tin xác thực kết nối cơ sở dữ liệu cục bộ và cơ sở dữ liệu trực tiếp.

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

Bước 10: Triển khai ExchangeArray

Thực hiện chức năng ExchangeArray trong mô hình Nhân viên.

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

Bước 11: Sử dụng TableGateway để tìm nạp Dữ liệu nhân viên

Tạo lớp, EmployeeTable trong chính thư mục Model. Nó được định nghĩa trong khối mã sau.

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

Bước 12: Định cấu hình lớp EmployeeTable

Cập nhật dịch vụ nhân viên trong Module.php bằng phương thức 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);
            },
         ],
      ];
   }
}

Bước 13: Thêm Dịch vụ Nhân viên trong Bộ điều khiển

Cập nhật phần điều khiển của Cấu hình mô-đun nhân viên trong - myapp / module / config / module.config.php như hình dưới đây.

'controllers' => [
   'factories' => [
      Controller\EmployeeController::class => function($container) { return new Controller\EmployeeController( $container->get(Model\EmployeeTable::class)
         ); 
      }, 
   ], 
]

Bước 14: Thêm hàm tạo cho EmployeeController

Thêm hàm tạo với EmployeeTable làm đối số và chỉnh sửa các thay đổi sau.

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

Bước 15: Hiển thị Thông tin nhân viên trong tập lệnh xem “index.phtml”

Di chuyển đến tệp - index.phtml và thực hiện các thay đổi sau -

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

Bây giờ chúng ta đã tạo thành công một mô hình cơ sở dữ liệu và có thể tìm nạp các bản ghi trong ứng dụng.

Yêu cầu ứng dụng bằng url - http://localhost:8080/employee.

Kết quả

Bước tiếp theo giải thích về insert, editdelete các thao tác dữ liệu trong phân hệ nhân viên.

Bước 16: Tạo biểu mẫu nhân viên

Tạo một tệp có tên EmployeeForm.phptrong thư mục myapp / module / Employee / src / Form. Nó được mô tả trong khối mã bên dưới.

<?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', 
         ), 
      )); 
   } 
}

Bước 17: Cập nhật mô hình nhân viên

Cập nhật mô hình nhân viên và triển khai InputFilterAwareInterface. Di chuyển đến thư mục myapp / module / Employee / src / Employee / Model và thêm các thay đổi sau vàoEmployee.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; 
   } 
}

Bước 18: Thêm addAction trong Bộ điều khiển nhân viên

Thêm các thay đổi sau trong EmployeeController lớp học.

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

Bước 19: Thêm chức năng lưu trong lớp EmployeeTable

Thêm hai hàm sau trong lớp 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'); 
      } 
   } 
}

Bước 20: Tạo View script cho phương thức AddAction, Add.phtml

Thêm các thay đổi sau vào tệp “Add.phtml” trong - 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

Kết quả

Khi dữ liệu đã được thêm vào, nó sẽ chuyển hướng đến trang chủ.

Bước 21: Chỉnh sửa hồ sơ nhân viên

Hãy để chúng tôi thực hiện các thao tác chỉnh sửa dữ liệu trong mô-đun Nhân viên. Cập nhật những thay đổi sau trongEmployeecontroller.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,); 
}

Ở đây, chúng tôi tìm kiếm id, nằm trong lộ trình phù hợp và sau đó tải chi tiết nhân viên cho thao tác chỉnh sửa.

Bước 22: Employee.php

Bây giờ, hãy thêm các thay đổi sau vào tệp “Employee.php”, nằm trong thư mục - myapp / module / Employee / src / Employee / Model /.

public function getArrayCopy() { 
   return get_object_vars($this); 
}

Ở đây, Zend \ Stdlib \ Hydrator \ ArraySerializable hy vọng sẽ tìm thấy hai phương thức trong mô hình: getArrayCopy()exchangeArray().

Trong đó, ExchangeArray () được sử dụng để lặp lại. Hàm này được sử dụng để liên kết dữ liệu từ bảng nhân viên.

Bây giờ, chúng ta cần tạo một tập lệnh xem cho editAction().

Bước 23: Tạo Edit.phtml

Tạo một tệp kịch bản chế độ xem trong mô-đun / Nhân viên / xem / nhân viên / nhân viên / 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();

Chỉnh sửa chi tiết nhân viên được hiển thị trong ảnh chụp màn hình sau.

Khi dữ liệu đã được chỉnh sửa, nó sẽ chuyển hướng đến trang chủ.

Bước 24: Thêm phương thức xóa

Thêm phương thức deleteE Jobee trong lớp EmployeeTable - myapp / module / Employee / src / Model / EmployeeTable.php

public function deleteEmployee($id) { $this->tableGateway->delete(['id' => (int) $id]); 
}

Bước 25: Xóa hồ sơ nhân viên

Bây giờ chúng ta hãy thực hiện các thao tác xóa dữ liệu trong mô-đun Nhân viên. Thêm phương thức sau,deleteAction trong lớp 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) 
   ); 
}

Tại đây, phương thức deleteEaffee () xóa nhân viên theo id và chuyển hướng đến trang danh sách nhân viên (trang chủ).

Bây giờ chúng ta hãy tạo một tập lệnh dạng xem tương ứng cho phương thức deleteAction ().

Bước 26: Tạo tập lệnh xem

Tạo một tệp có tên delete.phtml trong - myapp / module / Employee / view / worker / worker / delete.phtml và thêm mã sau vào đó.

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

Bây giờ, xóa bất kỳ nhân viên nào sử dụng edit trong trang chủ và kết quả sẽ như trong ảnh chụp màn hình sau.

Kết quả

Chúng tôi đã hoàn thành thành công mô-đun Nhân viên bằng cách triển khai tất cả các tính năng cần thiết.

Phần kết luận

Trong môi trường cạnh tranh hiện nay, Zend framework được nhà phát triển đặt lên vị trí hàng đầu. Nó cung cấp các thông tin trừu tượng cho bất kỳ chương trình nào hoặc bất kỳ loại ứng dụng nào bằng ngôn ngữ PHP. Nó là một khung hoàn thiện và hỗ trợ các tính năng ngôn ngữ PHP hiện đại. Nó là thú vị, chuyên nghiệp, phát triển và bắt kịp với công nghệ hiện tại.