Zend Framework - คู่มือฉบับย่อ

PHP Web Framework คือชุดของคลาสที่ช่วยในการพัฒนาเว็บแอปพลิเคชัน Zend เป็นหนึ่งในกรอบ PHP ที่ได้รับความนิยมมากที่สุด มันคือopen-source MVC frameworkสำหรับเว็บแอปพลิเคชันที่พัฒนาอย่างรวดเร็วและทันสมัย Zend Framework มีส่วนประกอบที่เชื่อมโยงกันอย่างหลวม ๆ ดังนั้นจึงเรียกว่า“ Component Library” Zend Framework ให้สแต็ก PHP และเซิร์ฟเวอร์ Zend เพื่อเรียกใช้แอปพลิเคชัน Zend framework

Zend Studio เป็น IDE ที่มีคุณสมบัติในการทำงานร่วมกับ Zend Framework ให้มุมมอง MVC และการสร้างรหัส Zend framework 3.0 ปัจจุบันมีส่วนประกอบใหม่ ๆ เช่นเซิร์ฟเวอร์ JSON RPC ตัวแปลง XML เป็น JSON ฟังก์ชัน PSR-7 และความเข้ากันได้กับ PHP 7

Zend Framework 2 เป็นเฟรมเวิร์กโอเพ่นซอร์สสำหรับการพัฒนาเว็บแอปพลิเคชันและบริการโดยใช้ PHP 5.3+ Zend Framework 2 ใช้โค้ดเชิงวัตถุ 100% และใช้คุณสมบัติใหม่ส่วนใหญ่ของ PHP 5.3 นั่นคือNamespaces, Lambda Functions และ Closures.

Zend Framework 2 พัฒนามาจาก Zend Framework 1 ซึ่งเป็นเฟรมเวิร์ก PHP ที่ประสบความสำเร็จด้วยการดาวน์โหลดมากกว่า 15 ล้านครั้ง Zend Server มีเวอร์ชันชุมชนฟรีและเวอร์ชันเชิงพาณิชย์

คุณสมบัติ Zend Framework

คุณสมบัติเด่นบางประการของ Zend Framework มีดังต่อไปนี้ -

  • เฟรมเวิร์กแอ็พพลิเคชันเว็บเชิงวัตถุบริสุทธิ์
  • การใช้ MVC ขั้นสูง
  • รองรับหลายฐานข้อมูลรวมถึง PostgreSQL, SQLite เป็นต้น
  • Simple cloud API
  • การจัดการเซสชัน
  • การเข้ารหัสข้อมูล
  • การกำหนดเส้นทาง URI ที่ยืดหยุ่น
  • Zend ให้การสนับสนุนการพัฒนา RESTful API
  • โค้ดใช้ซ้ำได้และดูแลรักษาง่ายกว่า

ทำไมต้อง Zend Framework

สิ่งที่ทำให้ Zend Framework เป็นหนึ่งในเฟรมเวิร์กชั้นนำที่นักพัฒนา PHP ใช้คือ - ให้โค้ดที่สะอาดและเสถียรพร้อมสิทธิ์ในทรัพย์สินทางปัญญา นอกจากนี้ยังช่วยให้การเขียนโปรแกรมง่ายขึ้น เป็นกรอบที่รวดเร็วเรียนรู้ง่ายและสะดวก Zend สนับสนุนเครื่องมือการเข้ารหัสที่แข็งแกร่งและเทคนิคการแฮชรหัสผ่าน

Zend เป้าหมาย

ต่อไปนี้เป็นเป้าหมายของ Zend Framework

  • Flexibility
  • เรียบง่ายและมีประสิทธิผล
  • Compatibility
  • Extensibility - โปรแกรมเมอร์สามารถขยายคลาสของเฟรมเวิร์กทั้งหมดได้อย่างง่ายดาย
  • การพกพา - รองรับหลายสภาพแวดล้อม

Zend Applications

ผลิตภัณฑ์ยอดนิยมต่อไปนี้ได้รับการพัฒนาโดยใช้ Zend Framework

  • เว็บไซต์ McAfee Company
  • เว็บไซต์ IBM Company
  • Magento - หนึ่งในเว็บไซต์ตะกร้าสินค้ายอดนิยม

ข้อดีของ Zend Framework

ข้อดีบางประการของ Zend Framework มีดังต่อไปนี้

  • Loosely Coupled - Zend มีตัวเลือกในการลบโมดูลหรือส่วนประกอบที่เราไม่ต้องการในแอปพลิเคชัน

  • Performance- Zend Framework ได้รับการปรับให้เหมาะสมที่สุดสำหรับประสิทธิภาพ Zend Framework 3 เร็วกว่ารุ่นก่อนหน้าถึง 4 เท่า

  • Security - Framework รองรับการเข้ารหัสมาตรฐานอุตสาหกรรม

  • Testing - PHPUnit ถูกรวมเข้ากับ Zend เพื่อให้คุณสามารถทดสอบกรอบงานได้อย่างง่ายดาย

ในบทถัดไปเราจะเรียนรู้วิธีการติดตั้ง Zend Framework

ในการติดตั้ง Zend Framework ก่อนอื่นเราต้องติดตั้ง Composer และ PHP เวอร์ชันล่าสุดดังแสดงในขั้นตอนต่อไปนี้

  • Install Composer- Zend ใช้ Composer ในการจัดการการอ้างอิงดังนั้นตรวจสอบให้แน่ใจว่าคุณได้ติดตั้ง Composer ไว้ในเครื่องของคุณ หากไม่ได้ติดตั้ง Composer ให้ไปที่เว็บไซต์อย่างเป็นทางการของComposerและติดตั้ง

  • Install the latest version of PHP- เพื่อให้ได้ประโยชน์สูงสุดจาก Zend Framework ให้ติดตั้ง PHP เวอร์ชันล่าสุด เวอร์ชันขั้นต่ำที่จำเป็นสำหรับ Zend Framework 3 คือ PHP 5.6 หรือใหม่กว่า

ติดตั้ง Zend Framework

Zend Framework สามารถติดตั้งได้สองวิธี มีดังนี้ -

  • การติดตั้งด้วยตนเอง
  • การติดตั้งตามนักแต่งเพลง

ให้เราหารือเกี่ยวกับการติดตั้งทั้งสองนี้โดยละเอียด

การติดตั้งด้วยตนเอง

ดาวน์โหลด Zend Framework เวอร์ชันล่าสุดโดยไปที่ลิงค์ต่อไปนี้ - https://framework.zend.com/downloads/archives

แตกเนื้อหาของไฟล์เก็บถาวรที่ดาวน์โหลดไปยังโฟลเดอร์ที่คุณต้องการเก็บไว้ เมื่อคุณมีสำเนาของ Zend Framework ในเครื่องของคุณแล้วเว็บแอปพลิเคชันที่ใช้ Zend Framework ของคุณจะสามารถเข้าถึงคลาสของเฟรมเวิร์กได้ แม้ว่าจะมีหลายวิธีในการบรรลุเป้าหมายนี้ แต่ PHP ของคุณinclude_pathจำเป็นต้องมีพา ธ ไปยังคลาส Zend Framework ภายใต้ไดเร็กทอรี / library ในการแจกจ่าย วิธีนี้ใช้ได้กับ Zend Framework เวอร์ชัน 2.4 และรุ่นก่อนหน้าเท่านั้น

การติดตั้งตาม Composer

หากต้องการติดตั้ง Zend Framework อย่างง่ายดายให้ใช้เครื่องมือ Composer นี่เป็นวิธีที่แนะนำในการติดตั้ง Zend Framework เวอร์ชันล่าสุด ในการติดตั้งส่วนประกอบทั้งหมดของ Zend Framework ให้ใช้คำสั่ง Composer ต่อไปนี้ -

$ composer require zendframework/zendframework

แต่ละโมดูล / ส่วนประกอบ Zend Framework สามารถติดตั้งแยกกันได้เช่นกัน ตัวอย่างเช่นในการติดตั้งไฟล์MVC component ของ Zend Framework ให้ใช้สิ่งต่อไปนี้ composer คำสั่ง -

$ composer require zendframework/zend-mvc

ให้เราสร้างแอปพลิเคชันโครงกระดูกโดยใช้เลเยอร์ Zend Framework MVC และระบบโมดูล

การติดตั้งโดยใช้ Composer

วิธีที่ง่ายที่สุดในการสร้างโปรเจ็กต์ Zend Framework ใหม่คือการใช้ Composer มีกำหนดดังต่อไปนี้ -

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

คุณจะเห็นผลลัพธ์ต่อไปนี้บนหน้าจอของคุณ -

Installing zendframework/skeleton-application (dev-master 
   941da45b407e4f09e264f000fb537928badb96ed)
   - Installing zendframework/skeleton-application (dev-master master)
   Cloning master

Created project in myapp
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
   - Installing zendframework/zend-component-installer (0.3.0)
   Loading from cache
  
   - Installing zendframework/zend-stdlib (3.0.1)
   Loading from cache
   
   - Installing zendframework/zend-config (2.6.0)
   Loading from cache
   
   - Installing zendframework/zend-loader (2.5.1)
   Loading from cache
   
   - Installing zendframework/zend-eventmanager (3.0.1)
   Loading from cache
   
   - Installing zendframework/zend-view (2.8.0)
   Loading from cache
   
   - Installing container-interop/container-interop (1.1.0)
   Loading from cache
   
   - Installing zendframework/zend-servicemanager (3.1.0)
   Loading from cache
   
   - Installing zendframework/zend-validator (2.8.1)
   Loading from cache
   
   - Installing zendframework/zend-escaper (2.5.1)
   Loading from cache
   
   - Installing zendframework/zend-uri (2.5.2)
   Loading from cache
   
   - Installing zendframework/zend-http (2.5.4)
   Loading from cache
   
   - Installing zendframework/zend-router (3.0.2)
   Loading from cache
   
   - Installing zendframework/zend-modulemanager (2.7.2)
   Loading from cache

   - Installing zendframework/zend-mvc (3.0.1)
   Loading from cache
   
   - Installing zendframework/zend-skeleton-installer (0.1.3)
   Loading from cache
   
   - Installing zfcampus/zf-development-mode (3.0.0)
   Loading from cache
zendframework/zend-config suggests installing zendframework/zend-filter
   (Zend\Filter component)
zendframework/zend-config suggests installing zendframework/zend-i18n
   (Zend\I18n component)
zendframework/zend-config suggests installing zendframework/zend-json
   (Zend\Json to use the Json reader or writer classes)
zendframework/zend-view suggests installing zendframework/zend-authentication
   (Zend\Authentication component)
zendframework/zend-view suggests installing zendframework/zend-feed
   (Zend\Feed component)
zendframework/zend-view suggests installing zendframework/zend-filter
   (Zend\Filter component)
zendframework/zend-view suggests installing zendframework/zend-i18n
   (Zend\I18n component)
zendframework/zend-view suggests installing zendframework/zend-json
   (Zend\Json component)
zendframework/zend-view suggests installing zendframework/zend-navigation
   (Zend\Navigation component)
zendframework/zend-view suggests installing zendframework/zend-paginator
   (Zend\Paginator component)
zendframework/zend-view suggests installing zendframework/zend-permissions-acl
   (Zend\Permissions\Acl component)
zendframework/zend-servicemanager suggests installing ocramius/proxy-manager
   (ProxyManager 1.* to handle lazy initialization of services)
zendframework/zend-validator suggests installing zendframework/zend-db
   (Zend\Db component)
zendframework/zend-validator suggests installing zendframework/zend-filter
   (Zend\Filter component, required by the Digits validator)
zendframework/zend-validator suggests installing zendframework/zend-i18n
   (Zend\I18n component to allow translation of validation error messages as well as
   to use the various Date validators)
zendframework/zend-validator suggests installing zendframework/zend-i18nresources
   (Translations of validator messages)
zendframework/zend-validator suggests installing zendframework/zend-math
   (Zend\Math component)
zendframework/zend-validator suggests installing zendframework/zend-session
   (Zend\Session component)
zendframework/zend-router suggests installing zendframework/zend-i18n
   (^2.6, if defining translatable HTTP path segments)

zendframework/zend-modulemanager suggests installing zendframework/zend-console
   (Zend\Console component)
zendframework/zend-mvc suggests installing zendframework/zend-json ((^2.6.1 ||
   ^3.0) To auto-deserialize JSON body content in AbstractRestfulController
   extensions, when json_decode is unavailable)
zendframework/zend-mvc suggests installing zendframework/zend-mvc-console
   (zend-mvc-console provides the ability to expose zend-mvc as a console application)
zendframework/zend-mvc suggests installing zendframework/zend-mvc-i18n
   (zendmvc-i18n provides integration with zend-i18n, including a translation bridge
   and translatable route segments)
zendframework/zend-mvc suggests installing zendframework/zend-mvc-pluginfileprg
   (To provide Post/Redirect/Get functionality around forms that container
   file uploads)
zendframework/zend-mvc suggests installing zendframework/zend-mvc-pluginflashmessenger
   (To provide flash messaging capabilities between requests)
zendframework/zend-mvc suggests installing zendframework/zend-mvc-pluginidentity
   (To access the authenticated identity (per zend-authentication) in controllers)
zendframework/zend-mvc suggests installing zendframework/zend-mvc-plugin-prg
   (To provide Post/Redirect/Get functionality within controllers)
zendframework/zend-mvc suggests installing zendframework/zend-psr7bridge
   ((^0.2) To consume PSR-7 middleware within the MVC workflow)
zendframework/zend-mvc suggests installing zendframework/zend-servicemanager-di
   (zend-servicemanager-di provides utilities for integrating zend-di and
   zendservicemanager in your zend-mvc application)

Generating autoload files
   Removing optional packages from composer.json
   Updating composer.json
Removing zendframework/zend-skeleton-installer...
   - Removing zendframework/zend-skeleton-installer (0.1.3)
   Removed plugin zendframework/zend-skeleton-installer.
   Removing from composer.json
   Complete!
> zf-development-mode enable
You are now in development mode.

เมื่อติดตั้งแอปพลิเคชันแล้วคุณสามารถทดสอบได้ทันทีโดยใช้ไฟล์ PHP's built-in web server -

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

จากนั้นคุณจะเห็นคำตอบต่อไปนี้ -

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

สิ่งนี้จะเริ่มต้นเซิร์ฟเวอร์ CLI ในตัวของ PHP บนพอร์ต 8080 เมื่อเซิร์ฟเวอร์การพัฒนาเริ่มทำงานคุณสามารถเยี่ยมชมไซต์ได้ที่ (http://localhost:8080/). เซิร์ฟเวอร์ CLI ในตัวใช้สำหรับการพัฒนาเท่านั้น

การทดสอบหน่วย

ในการรันการทดสอบยูนิตโครงกระดูกพิมพ์คำสั่งต่อไปนี้ในเทอร์มินัลของคุณ

$ composer require --dev zendframework/zend-test

มันจะตอบสนองต่อไปนี้ -

Using version ^3.0 for zendframework/zend-test 
   ./composer.json has been updated 
Loading composer repositories with package information 
Updating dependencies (including require-dev) 
   - Installing zendframework/zend-dom (2.6.0) 
   Loading from cache  
   
   - Installing zendframework/zend-console (2.6.0) 
   Loading from cache  
   
   - Installing sebastian/version (2.0.1) 
   Loading from cache 
   
   - Installing symfony/yaml (v3.2.1)
   Downloading: 100%           
   
   - Installing sebastian/resource-operations (1.0.0) 
   Loading from cache  
   
   - Installing sebastian/recursion-context (2.0.0) 
   Loading from cache  
   
   - Installing sebastian/object-enumerator (2.0.0) 
   Loading from cache  
   
   - Installing sebastian/global-state (1.1.1) 
   Loading from cache  
   
   - Installing sebastian/exporter (2.0.0) 
   Loading from cache  
   
   - Installing sebastian/environment (2.0.0) 
   Loading from cache  
   
   - Installing sebastian/diff (1.4.1) 
   Loading from cache  
   
   - Installing sebastian/comparator (1.2.2) 
   Loading from cache  
   
   - Installing phpunit/php-text-template (1.2.1) 
   Loading from cache  
   
   - Installing doctrine/instantiator (1.0.5) 
   Loading from cache  
   
   - Installing phpunit/phpunit-mock-objects (3.4.3) 
   Downloading: 100%          
   
   - Installing phpunit/php-timer (1.0.8)
   Loading from cache  
   
   - Installing phpunit/php-file-iterator (1.4.2) 
   Loading from cache  
   
   - Installing sebastian/code-unit-reverse-lookup (1.0.0) 
   Loading from cache  
   
   - Installing phpunit/php-token-stream (1.4.9) 
   Loading from cache  
   
   - Installing phpunit/php-code-coverage (4.0.4) 
   Downloading: 100%           
   
   - Installing webmozart/assert (1.2.0) 
   Loading from cache  
   
   - Installing phpdocumentor/reflection-common (1.0) 
   Loading from cache  
   
   - Installing phpdocumentor/type-resolver (0.2.1) 
   Loading from cache  
   
   - Installing phpdocumentor/reflection-docblock (3.1.1) 
   Loading from cache  
   
   - Installing phpspec/prophecy (v1.6.2) 
   Loading from cache  
   
   - Installing myclabs/deep-copy (1.5.5) 
   Loading from cache  
   
   - Installing phpunit/phpunit (5.7.4) 
   Downloading: 100%          
   
   - Installing zendframework/zend-test (3.0.2) 
   Loading from cache

zendframework/zend-console suggests installing zendframework/zend-filter 
   (To support DefaultRouteMatcher usage) 
symfony/yaml suggests installing symfony/console (For validating YAML files 
   using the lint command) 
sebastian/global-state suggests installing ext-uopz (*) 
phpunit/phpunit-mock-objects suggests installing ext-soap (*) 
phpunit/php-code-coverage suggests installing ext-xdebug (>=2.4.0) 
phpunit/phpunit suggests installing phpunit/php-invoker (~1.1) 
phpunit/phpunit suggests installing ext-xdebug (*) 
zendframework/zend-test suggests installing zendframework/zend-mvc-console 
   (^1.1.8, to test MVC <-> console integration) 
Writing lock file 
Generating autoload files

ตอนนี้การรองรับการทดสอบถูกเปิดใช้งานเพื่อให้คุณสามารถรันการทดสอบโดยใช้คำสั่งต่อไปนี้

$ ./vendor/bin/phpunit

Apache เว็บเซิร์ฟเวอร์

การโฮสต์แอปพลิเคชันที่ใช้ Zend Framework ในสภาพแวดล้อมการผลิตนั้นง่ายมากและตรงไปตรงมา เพียงแค่สร้างไฟล์VirtualHost ในไฟล์คอนฟิกูเรชัน Apache แล้วชี้ไฟล์ DocumentRoot ไปที่ Public โฟลเดอร์ของแอปพลิเคชัน Zend Framework

ตัวอย่างการกำหนดค่า (myapp) ได้รับด้านล่าง -

<VirtualHost *:80> 
   ServerName myapp.localhost 
   DocumentRoot /path/to/install/myapp/public 
   <Directory /path/to/install/myapp/public> 
      DirectoryIndex index.php 
      AllowOverride All 
      Order allow,deny 
      Allow from all 
      <IfModule mod_authz_core.c> 
         Require all granted 
      </IfModule> 
   </Directory> 
</VirtualHost>

ก่อนดำเนินการในบทนี้ขอให้เราทำความเข้าใจสั้น ๆ เกี่ยวกับ MVC กModel View Controllerเป็นแนวทางซอฟต์แวร์ที่แยกตรรกะของแอปพลิเคชันออกจากการนำเสนอ ในทางปฏิบัติจะอนุญาตให้หน้าเว็บมีการเขียนสคริปต์ PHP น้อยที่สุดเนื่องจากงานนำเสนอแยกออกจากกัน

คำอธิบายสั้น ๆ ของส่วนประกอบ MVC มีดังต่อไปนี้

  • Model- โมเดลแสดงถึงโครงสร้างของข้อมูลแอปพลิเคชัน โดยปกติคลาสโมเดลจะมีฟังก์ชันที่ช่วยในการretrieve, insert และ update business data ในฐานข้อมูลส่วนหลัง (MySQL, PostgreSQL ฯลฯ )

  • View- View เป็นเลเยอร์การนำเสนอของแอปพลิเคชัน MVC รับข้อมูลโมเดลผ่านคอนโทรลเลอร์และแสดงผลตามต้องการ มันอยู่คู่กับController และ Model ดังนั้นจึงสามารถเปลี่ยนแปลงได้โดยไม่ส่งผลกระทบต่อโมเดลและคอนโทรลเลอร์

  • Controller- คอนโทรลเลอร์เป็นส่วนประกอบหลักของสถาปัตยกรรม MVC ทุกคำขอแรกจะกระทบตัวควบคุม กล่าวอีกนัยหนึ่งคอนโทรลเลอร์จะประมวลผลคำขอทั้งหมดและทำหน้าที่เป็นตัวกลางระหว่าง Model, View และทรัพยากรอื่น ๆ ที่จำเป็นในการprocess the HTTP request และเพื่อสร้างการตอบสนอง

ในบทถัดไปเราจะทำความเข้าใจแนวคิดต่างๆของ Zend Framework

Zend Framework คือชุดส่วนประกอบมากกว่า 60+ รายการ พวกเขาเชื่อมต่อกันอย่างหลวม ๆ สามารถใช้เป็นทั้งส่วนประกอบแบบสแตนด์อะโลนและกลุ่มของส่วนประกอบที่ทำงานเป็นหน่วยเดียว

Zend Framework มีองค์ประกอบที่สำคัญที่สุดสามประการ ได้แก่ -

  • zend-servicemanager
  • zend-eventmanager และ
  • zend-modulemanager.

ทำให้ส่วนประกอบของ Zend สามารถรวมเข้ากับส่วนประกอบอื่น ๆ ได้อย่างมีประสิทธิภาพ

  • Event Manager- ให้ความสามารถในการสร้างโปรแกรมตามเหตุการณ์ ซึ่งจะช่วยในการสร้างฉีดและจัดการกิจกรรมใหม่

  • Service Manager - ช่วยให้สามารถใช้บริการใด ๆ (คลาส PHP) ได้จากทุกที่ด้วยความพยายามเพียงเล็กน้อย

  • Module Manager - ความสามารถในการแปลงคอลเลกชันของคลาส PHP ที่มีฟังก์ชันการทำงานคล้ายกันเป็นหน่วยเดียวที่เรียกว่า module. โมดูลที่สร้างขึ้นใหม่สามารถใช้ดูแลรักษาและกำหนดค่าเป็นหน่วยเดียวได้

เราจะกล่าวถึงแนวคิดเหล่านี้โดยละเอียดในบทต่อ ๆ ไป

Zend Framework ประกอบด้วยการใช้งานรูปแบบตัวระบุตำแหน่งบริการที่มีประสิทธิภาพที่เรียกว่า zend-servicemanager. Zend framework ใช้ตัวจัดการบริการอย่างกว้างขวางสำหรับฟังก์ชันการทำงานทั้งหมด ผู้จัดการฝ่ายบริการจัดเตรียมสิ่งที่เป็นนามธรรมระดับสูงสำหรับ Zend Framework นอกจากนี้ยังรวมเข้ากับส่วนประกอบอื่น ๆ ทั้งหมดของ Zend Framework ได้เป็นอย่างดี

ติดตั้งตัวจัดการบริการ

คอมโพเนนต์ตัวจัดการบริการสามารถติดตั้งได้โดยใช้ composer เครื่องมือ.

composer require zendframework/zend-servicemanager

ตัวอย่าง

ขั้นแรกบริการทั้งหมดต้องลงทะเบียนในตัวจัดการบริการ เมื่อลงทะเบียนบริการลงในระบบจัดการเซิร์ฟเวอร์แล้วจะสามารถเข้าถึงได้ตลอดเวลาโดยใช้ความพยายามเพียงเล็กน้อย ผู้จัดการบริการมีตัวเลือกมากมายในการลงทะเบียนบริการ ตัวอย่างง่ายๆมีดังนี้ -

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

รหัสด้านบนลงทะเบียนไฟล์ stdClass เข้าสู่ระบบโดยใช้ไฟล์ Factoryตัวเลือก ตอนนี้เราสามารถรับอินสแตนซ์ของ stdClass ได้ตลอดเวลาโดยใช้ไฟล์get() วิธีการของผู้จัดการบริการดังที่แสดงด้านล่าง

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

เมธอด get () แชร์อ็อบเจ็กต์ที่ดึงมาดังนั้นอ็อบเจ็กต์ที่ส่งคืนโดยการเรียกใช้เมธอด get () หลาย ๆ ครั้งเป็นอินสแตนซ์เดียว ในการรับอินสแตนซ์ที่แตกต่างกันทุกครั้งตัวจัดการบริการมีวิธีการอื่นซึ่งก็คือไฟล์build() วิธี.

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

การลงทะเบียนผู้จัดการบริการ

ตัวจัดการบริการจัดเตรียมชุดวิธีการในการลงทะเบียนส่วนประกอบ วิธีการที่สำคัญที่สุดมีดังต่อไปนี้ -

  • วิธีการโรงงาน
  • วิธีโรงงานนามธรรม
  • วิธีการเริ่มต้น
  • วิธีการของ Delegator Factory

เราจะพูดถึงสิ่งเหล่านี้โดยละเอียดในบทต่อ ๆ ไป

วิธีการโรงงาน

โดยพื้นฐานแล้วโรงงานนั้นสามารถเรียกได้หรือคลาสใด ๆ ที่ใช้ FactoryInterface (Zend \ ServiceManager \ Factory \ FactoryInterface)

FactoryInterface มีวิธีการเดียว -

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

รายละเอียดอาร์กิวเมนต์ของ FactoryInterface มีดังต่อไปนี้ -

  • container (ContainerInterface)- เป็นอินเทอร์เฟซพื้นฐานของ ServiceManager มีตัวเลือกในการรับบริการอื่น ๆ

  • requestedName - เป็นชื่อบริการ

  • options - ให้ตัวเลือกเพิ่มเติมที่จำเป็นสำหรับบริการ

ให้เราสร้างคลาสง่ายๆโดยใช้ FactoryInterface และดูวิธีการลงทะเบียนคลาส

การทดสอบคลาส - วัตถุที่จะเรียกคืน

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

Test คลาสขึ้นอยู่กับ stdClass

Class TestFactory - คลาสเพื่อเริ่มต้นวัตถุทดสอบ

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

TestFactory ใช้คอนเทนเนอร์เพื่อดึงข้อมูล stdClass สร้างอินสแตนซ์ของคลาสทดสอบและส่งคืน

การลงทะเบียนและการใช้งาน Zend Framework

ตอนนี้ให้เราเข้าใจวิธีการลงทะเบียนและใช้ Zend Framework

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

ผู้จัดการฝ่ายบริการจัดหาโรงงานพิเศษที่เรียกว่า InvokableFactoryเพื่อดึงคลาสใด ๆ ที่ไม่มีการพึ่งพา ตัวอย่างเช่นไฟล์stdClass สามารถกำหนดค่าโดยใช้ InvokableFactory เนื่องจาก stdClass ไม่ขึ้นอยู่กับคลาสอื่น ๆ

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

อีกวิธีหนึ่งในการดึงวัตถุโดยไม่ต้องใช้ FactoryInterface หรือใช้ไฟล์ InvokableFactory กำลังใช้วิธีการอินไลน์ตามที่ระบุด้านล่าง

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

วิธีโรงงานนามธรรม

บางครั้งเราอาจต้องสร้างอ็อบเจกต์ซึ่งเราจะรู้เฉพาะตอนรันไทม์เท่านั้น สถานการณ์นี้สามารถจัดการได้โดยใช้AbstractFactoryInterfaceซึ่งได้มาจาก FactoryInterface

AbstractFactoryInterface กำหนดวิธีการตรวจสอบว่าสามารถสร้างวัตถุที่อินสแตนซ์ที่ร้องขอได้หรือไม่ หากสามารถสร้างวัตถุได้ก็จะสร้างวัตถุโดยใช้ไฟล์__invokemethod ของ FactoryInterface และส่งคืน

ลายเซ็นของ AbstractFactoryInterface มีดังนี้ -

public function canCreate(ContainerInterface $container, $requestedName)

วิธีการเริ่มต้น

Initializer Method เป็นตัวเลือกพิเศษในการแทรกการอ้างอิงเพิ่มเติมสำหรับบริการที่สร้างไว้แล้ว มันใช้InitializerInterface และลายเซ็นของวิธีการเดียวที่ใช้ได้มีดังนี้ -

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

ในตัวอย่างข้างต้นวิธีการตรวจสอบว่าอินสแตนซ์เป็นประเภท EventManagerAwareInterface หรือไม่ ถ้าเป็นประเภทEventManagerAwareInterfaceมันตั้งค่าออบเจ็กต์ตัวจัดการเหตุการณ์มิฉะนั้นจะไม่ เนื่องจากวิธีนี้อาจตั้งค่าการอ้างอิงหรือไม่ก็ได้จึงไม่น่าเชื่อถือและก่อให้เกิดปัญหารันไทม์มากมาย

วิธีการของ Delegator Factory

Zend Framework รองรับรูปแบบตัวแทนผ่าน DelegatorFactoryInterface. สามารถใช้ในการตกแต่งบริการ

ลายเซ็นของฟังก์ชันนี้มีดังต่อไปนี้ -

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

ที่นี่ $callback รับผิดชอบในการตกแต่งอินสแตนซ์บริการ

บริการขี้เกียจ

บริการ Lazy เป็นหนึ่งในบริการที่จะไม่เริ่มต้นอย่างสมบูรณ์ในขณะที่สร้าง พวกเขาเป็นเพียงการอ้างอิงและเริ่มต้นเมื่อจำเป็นจริงๆเท่านั้น หนึ่งในตัวอย่างที่ดีที่สุดคือการเชื่อมต่อฐานข้อมูลซึ่งอาจไม่จำเป็นในทุกที่ เป็นทรัพยากรที่มีราคาแพงและมีกระบวนการที่ใช้เวลานานในการสร้าง Zend framework ให้LazyServiceFactory มาจากไฟล์ DelegatorFactoryInterfaceซึ่งสามารถผลิตบริการขี้เกียจด้วยความช่วยเหลือของ Delegator แนวคิดและตัวจัดการพร็อกซีบุคคลที่สามซึ่งเรียกว่า ocramius proxy manager.

ตัวจัดการปลั๊กอิน

Plugin Manager ขยายตัวจัดการบริการและมีฟังก์ชันเพิ่มเติมเช่นการตรวจสอบอินสแตนซ์ Zend Framework ใช้ตัวจัดการปลั๊กอินอย่างกว้างขวาง

ตัวอย่างเช่นบริการตรวจสอบความถูกต้องทั้งหมดอยู่ภายใต้ไฟล์ ValidationPluginManager.

ตัวเลือกการกำหนดค่า

ตัวจัดการบริการมีตัวเลือกบางอย่างเพื่อขยายคุณลักษณะของตัวจัดการบริการ พวกเขาเป็นshared, shared_by_default และ aliases. ดังที่เราได้กล่าวไว้ก่อนหน้านี้อ็อบเจ็กต์ที่ดึงมาจะถูกแชร์ระหว่างอ็อบเจ็กต์ที่ร้องขอตามค่าเริ่มต้นและเราสามารถใช้build()วิธีการรับวัตถุที่แตกต่างกัน เรายังสามารถใช้ไฟล์sharedตัวเลือกเพื่อระบุบริการที่จะแชร์ shared_by_default เหมือนกับไฟล์ shared คุณสมบัติยกเว้นว่าจะใช้กับบริการทั้งหมด

$serviceManager = new ServiceManager([ 
   'factories' => [ 
      stdClass::class => InvokableFactory::class 
   ], 
   'shared' => [ 
      stdClass::class => false // will not be shared 
   ], 
   'shared_by_default' => false, // will not be shared and applies to all service 
]);

aliasesสามารถใช้ตัวเลือกเพื่อระบุชื่ออื่นให้กับบริการที่ลงทะเบียน สิ่งนี้มีทั้งข้อดีและข้อเสีย ในด้านบวกเราสามารถระบุชื่อย่อทางเลือกสำหรับบริการได้ แต่ในขณะเดียวกันชื่ออาจไม่อยู่ในบริบทและทำให้เกิดข้อบกพร่อง

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

แอพพลิเคชั่นที่ทันสมัยทั้งหมดต้องการส่วนประกอบเหตุการณ์ที่มั่นคงและยืดหยุ่น Zend Framework มีองค์ประกอบดังกล่าวzend-eventmanager. zend-eventmanager ช่วยในการออกแบบสถาปัตยกรรมระดับสูงและสนับสนุนรูปแบบหัวเรื่อง / ผู้สังเกตการณ์และการเขียนโปรแกรมเชิงแง่มุม

ติดตั้ง Event Manager

ตัวจัดการเหตุการณ์สามารถติดตั้งได้โดยใช้ไฟล์ Composer ตามที่ระบุด้านล่าง -

composer require zendframework/zend-eventmanager

แนวคิดของผู้จัดการกิจกรรม

แนวคิดหลักของผู้จัดการเหตุการณ์มีดังนี้ -

  • Event - เหตุการณ์เป็นชื่อการกระทำโดยพลการพูด greet.

  • Listener- การโทรกลับ PHP ใด ๆ พวกเขาจะแนบกับเหตุการณ์และถูกเรียกเมื่อเหตุการณ์ถูกกระตุ้น ลายเซ็นเริ่มต้นของ Listener คือ -

function(EventInterface $e)
  • EventInterface Class- ใช้เพื่อระบุเหตุการณ์นั้นเอง มีวิธีการตั้งค่าและรับข้อมูลเหตุการณ์เช่น name (set / getName), target (get / setTarget) และ parameter (get / setParams)

  • EventManager class- อินสแตนซ์ของ EventManager ติดตามเหตุการณ์ที่กำหนดทั้งหมดในแอปพลิเคชันและผู้ฟังที่เกี่ยวข้อง EventManager มีวิธีการattach เพื่อแนบผู้ฟังเข้ากับเหตุการณ์และมีวิธีการ triggerเพื่อทริกเกอร์เหตุการณ์ที่กำหนดไว้ล่วงหน้า เมื่อเรียกทริกเกอร์แล้ว EventManager จะเรียกฟังที่แนบมา

  • EventManagerAwareInterface- สำหรับคลาสเพื่อรองรับการเขียนโปรแกรมตามเหตุการณ์จำเป็นต้องใช้ EventManagerAwareInterface มีสองวิธีsetEventManager และ getEventManager เพื่อรับและตั้งค่าตัวจัดการเหตุการณ์

ตัวอย่าง

ให้เราเขียนแอปพลิเคชันคอนโซล PHP ง่ายๆเพื่อทำความเข้าใจแนวคิดตัวจัดการเหตุการณ์ ทำตามขั้นตอนที่ระบุด้านล่าง

  • สร้างโฟลเดอร์“ eventapp”

  • ติดตั้ง zend-eventmanager โดยใช้นักแต่งเพลง

  • สร้างไฟล์ PHP Greeter.php ภายในโฟลเดอร์“ eventapp”

  • สร้างชั้นเรียน Greeter และใช้ EventManagerAwareInterface.

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

ที่นี่ require ใช้ในการโหลดคอมโพเนนต์ทั้งหมดที่ติดตั้งโดยอัตโนมัติ

เขียน setEventManager วิธีการในชั้นเรียน Greeter ดังแสดงด้านล่าง -

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

วิธีนี้ตั้งค่าคลาสปัจจุบันเป็นตัวจัดการเหตุการณ์ที่กำหนด (อาร์กิวเมนต์ $ events) จากนั้นตั้งค่าตัวจัดการเหตุการณ์ในตัวแปรภายใน $events.

ขั้นตอนต่อไปคือการเขียนไฟล์ getEventManager วิธีการในชั้นเรียน Greeter ดังแสดงด้านล่าง -

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

เมธอดรับตัวจัดการเหตุการณ์จากตัวแปรโลคัล หากไม่พร้อมใช้งานระบบจะสร้างอินสแตนซ์ของตัวจัดการเหตุการณ์และส่งคืน

เขียนวิธีการ greet, ในชั้นเรียน Greeter.

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

วิธีนี้ได้รับตัวจัดการเหตุการณ์และเริ่ม / ทริกเกอร์เหตุการณ์ที่แนบมา

ขั้นตอนต่อไปคือการสร้างอินสแตนซ์ของไฟล์ Greeter เรียนและแนบผู้ฟังเข้ากับวิธีการ greet.

$greeter = new Greeter();  
$greeter->getEventManager()->attach('greet', function($e) { 
   $event_name = $e->getName(); 
   $target_name = get_class($e->getTarget()); 
   $params_json = json_encode($e->getParams());  
   printf("\"%s\" event of class \"%s\" is called." . 
      " The parameter supplied is %s\n",  
      $event_name, $target_name,  
      $params_json); 
});

การโทรกลับของผู้ฟังเพียงแค่พิมพ์ชื่อของเหตุการณ์เป้าหมายและพารามิเตอร์ที่ให้มา

รายชื่อทั้งหมดของไฟล์ Greeter.php มีดังนี้ -

<?php  
require __DIR__ . '/vendor/autoload.php';  

use Zend\EventManager\EventManagerInterface; 
use Zend\EventManager\EventManager; 
use Zend\EventManager\EventManagerAwareInterface; 

class Greeter implements EventManagerAwareInterface { 
   protected $events;
   public function setEventManager(EventManagerInterface $events) { $events->setIdentifiers([__CLASS__, get_called_class(), ]); 
      $this->events = $events; 
      return $this; } public function getEventManager() { if (null === $this->events) { 
         $this->setEventManager(new EventManager()); } return $this->events; 
   } 
   public function greet($message) { printf("\"%s\" from class\n", $message); 
      $this->getEventManager()->trigger(__FUNCTION__, $this, [$message ]); } } $greeter = new Greeter(); 
$greeter->greet("Hello"); $greeter->getEventManager()->attach('greet', function($e) { $event_name = $e->getName(); $target_name = get_class($e->getTarget()); $params_json = json_encode($e->getParams()); printf("\"%s\" event of class \"%s\" is called." . " The parameter supplied is %s\n", $event_name,
      $target_name, $params_json); 
});  
$greeter->greet("Hello");

ตอนนี้เรียกใช้แอปพลิเคชันในพรอมต์คำสั่ง php Greeter.php และผลลัพธ์จะเป็นดังนี้ -

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

แอปพลิเคชันตัวอย่างข้างต้นอธิบายเฉพาะพื้นฐานของตัวจัดการเหตุการณ์ ผู้จัดการกิจกรรมมีตัวเลือกขั้นสูงอื่น ๆ อีกมากมายเช่นListener Priority, Custom Callback Prototype / Signature, Short Circuiting, ฯลฯ ตัวจัดการเหตุการณ์ถูกใช้อย่างกว้างขวางในกรอบงาน Zend MVC

Zend Framework มีระบบโมดูลที่มีประสิทธิภาพ ระบบโมดูลมีส่วนประกอบสามส่วน มีดังนี้ -

  • Module Autoloader- โมดูล Autoloader มีหน้าที่ในการค้นหาและโหลดโมดูลจากแหล่งต่างๆ สามารถโหลดโมดูลที่บรรจุเป็นไฟล์Phar archivesเช่นกัน. การใช้งาน Module Autoloader อยู่ที่ myapp / vendor / zendframework / zend-loader / src / ModuleAutoloader.php

  • Module Manager- เมื่อโมดูล Autoloader ค้นหาโมดูลแล้วตัวจัดการโมดูลจะยิงลำดับเหตุการณ์สำหรับแต่ละโมดูล การใช้งานตัวจัดการโมดูลจะอยู่ที่ myapp / vendor / zendframework / zendmodulemanager / src / ModuleManager.php

  • Module Manager Listeners- สามารถแนบกับเหตุการณ์ที่เรียกใช้โดยตัวจัดการโมดูล เมื่อเชื่อมต่อกับเหตุการณ์ของตัวจัดการโมดูลพวกเขาสามารถทำทุกอย่างได้ตั้งแต่การแก้ไขและโหลดโมดูลไปจนถึงการทำงานที่ซับซ้อนสำหรับแต่ละโมดูล

ระบบโมดูลเว็บ MVC

MVC Web Application ใน Zend Framework มักจะเขียนเป็นโมดูล เว็บไซต์เดียวสามารถมีโมดูลอย่างน้อยหนึ่งโมดูลที่จัดกลุ่มตามฟังก์ชันการทำงาน โครงสร้างที่แนะนำสำหรับโมดูลเชิง MVC มีดังต่อไปนี้ -

module_root/ 
   Module.php 
   autoload_classmap.php 
   autoload_function.php 
   autoload_register.php 
   config/ 
      module.config.php 
   public/ 
      images/ 
      css/ 
      js/ 
   src/ 
      <module_namespace>/ 
      <code files> 
   test/ 
      phpunit.xml
      bootstrap.php 
      <module_namespace>/ 
         <test code files> 
   view/ 
      <dir-named-after-module-namespace>/ 
         <dir-named-after-a-controller>/ 
            <.phtml files>

โครงสร้างจะเหมือนกับที่กล่าวไว้ในบทที่แล้ว แต่ในที่นี้เป็นแบบทั่วไป autoload_ files สามารถใช้เป็นกลไกเริ่มต้นสำหรับการโหลดคลาสที่มีอยู่ในโมดูลโดยอัตโนมัติโดยไม่ต้องใช้ขั้นสูง Module Manager มีอยู่ในไฟล์ zend-modulemanager.

  • autoload_classmap.php - ส่งคืนอาร์เรย์ของชื่อคลาสและชื่อไฟล์ที่เกี่ยวข้อง

  • autoload_function.php- ส่งคืนการเรียกกลับ PHP สิ่งนี้สามารถใช้ประโยชน์จากคลาสที่ส่งคืนโดย autoload_classmap.php

  • autoload_register.php - ลงทะเบียนการเรียกกลับ PHP ที่ส่งคืนโดย autoload_function.php

ไฟล์เหล่านี้ไม่จำเป็นต้องโหลดอัตโนมัติ แต่แนะนำ ในแอปพลิเคชัน skeleton เราไม่ได้ใช้ไฟล์autoload_ files.

คลาสโมดูล

ควรตั้งชื่อคลาสโมดูล Module และเนมสเปซของคลาสโมดูลควรเป็น Module name. สิ่งนี้จะช่วยให้ Zend Framework แก้ไขและโหลดโมดูลได้อย่างง่ายดาย Application รหัสโมดูลในแอปพลิเคชันโครงกระดูก (myapp), myapp / module / Application / src / Module.php มีดังนี้ -

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

ตัวจัดการโมดูล Zend Framework จะเรียกไฟล์ getConfig() ทำงานโดยอัตโนมัติและจะทำตามขั้นตอนที่จำเป็น

ในบทนี้ให้เราเข้าใจโครงสร้างของแอปพลิเคชัน Zend Framework โครงสร้างของmyapp ใบสมัครมีดังนี้ -

├── composer.json 
├── composer.lock 
├── CONDUCT.md 
├── config 
│   ├── application.config.php 
│   ├── autoload 
│   │   ├── development.local.php 
│   │   ├── development.local.php.dist 
│   │   ├── global.php 
│   │   ├── local.php.dist 
│   │   ├── README.md 
│   │   └── zend-developer-tools.local-development.php 
│   ├── development.config.php 
│   ├── development.config.php.dist 
│   └── modules.config.php 
├── CONTRIBUTING.md 
├── data 
│   └── cache 
│       └── module-classmap-cache.application.module.cache.php ├── docker-compose.yml 
├── Dockerfile 
├── LICENSE.md 
├── module 
│   └── Application 
│       ├── config 
│       ├── src 
│       ├── test 
│       └── view 
├── phpcs.xml 
├── phpunit.xml.dist 
├── public
│   ├── css 
│   │   ├── bootstrap.css 
│   │   ├── bootstrap.css.map 
│   │   ├── bootstrap.min.css 
│   │   ├── bootstrap.min.css.map 
│   │   ├── bootstrap-theme.css 
│   │   ├── bootstrap-theme.css.map 
│   │   ├── bootstrap-theme.min.css 
│   │   ├── bootstrap-theme.min.css.map 
│   │   └── style.css 
│   ├── fonts 
│   │   ├── glyphicons-halflings-regular.eot 
│   │   ├── glyphicons-halflings-regular.svg 
│   │   ├── glyphicons-halflings-regular.ttf 
│   │   ├── glyphicons-halflings-regular.woff 
│   │   └── glyphicons-halflings-regular.woff2 
│   ├── img 
│   │   ├── favicon.ico 
│   │   └── zf-logo-mark.svg 
│   ├── index.php 
│   ├── js 
│   │   ├── bootstrap.js 
│   │   ├── bootstrap.min.js 
│   │   └── jquery-3.1.0.min.js 
│   └── web.config 
├── README.md 
├── TODO.md 
├── Vagrantfile 
└── vendor     
├── autoload.php     
├── bin     
│   ├── phpunit -> ../phpunit/phpunit/phpunit     
│   ├── templatemap_generator.php -> ../zendframework/zend-
view/bin/templatemap_generator.php
│   └── zf-development-mode -> ../zfcampus/zf-development-mode/bin/zf-
development-mode 
├── composer     
│   ├── autoload_classmap.php     
│   ├── autoload_namespaces.php     
│   ├── autoload_psr4.php     
│   ├── autoload_real.php     
│   ├── ClassLoader.php     
│   ├── installed.json 
│   └── LICENSE     
├── container-interop 
│   └── container-interop     
├── doctrine 
│   └── instantiator     
├── myclabs 
│   └── deep-copy     
├── phpdocumentor     
│   ├── reflection-common     
│   ├── reflection-docblock 
│   └── type-resolver     
├── phpspec 
│   └── prophecy     
├── phpunit     
│   ├── php-code-coverage     
│   ├── php-file-iterator     
│   ├── php-text-template     
│   ├── php-timer     
│   ├── php-token-stream     
│   ├── phpunit 
│   └── phpunit-mock-objects     
├── sebastian     
│   ├── code-unit-reverse-lookup     
│   ├── comparator     
│   ├── diff     
│   ├── environment     
│   ├── exporter     
│   ├── global-state     
│   ├── object-enumerator
│   ├── recursion-context     
│   ├── resource-operations 
│   └── version     
├── symfony 
│   └── yaml     
├── webmozart 
│   └── assert     
├── zendframework     
│   ├── zend-component-installer     
│   ├── zend-config     
│   ├── zend-console     
│   ├── zend-dom     
│   ├── zend-escaper     
│   ├── zend-eventmanager     
│   ├── zend-http     
│   ├── zend-loader     
│   ├── zend-modulemanager     
│   ├── zend-mvc     
│   ├── zend-router     
│   ├── zend-servicemanager     
│   ├── zend-stdlib     
│   ├── zend-test     
│   ├── zend-uri     
│   ├── zend-validator 
│   └── zend-view 
└── zfcampus 
└── zf-development-mode  

73 directories, 55 files

แอปพลิเคชัน Zend Framework ประกอบด้วยโฟลเดอร์ต่างๆ มีดังนี้ -

  • Application- ไดเร็กทอรีนี้มีแอปพลิเคชันของคุณ มันจะเป็นที่ตั้งของระบบ MVC ตลอดจนการกำหนดค่าบริการที่ใช้และไฟล์ bootstrap ของคุณ

  • Config - ไดเร็กทอรีนี้มีไฟล์การกำหนดค่าของแอปพลิเคชัน

  • Data - ไดเร็กทอรีนี้เป็นที่สำหรับจัดเก็บข้อมูลแอปพลิเคชันที่มีความผันผวนและอาจเกิดขึ้นชั่วคราว

  • Module - โมดูลช่วยให้นักพัฒนาสามารถจัดกลุ่มชุดของตัวควบคุมที่เกี่ยวข้องเป็นกลุ่มที่จัดอย่างมีเหตุผล

  • Public- นี่คือรูทเอกสารของแอปพลิเคชัน มันเริ่มแอปพลิเคชัน Zend นอกจากนี้ยังมีเนื้อหาของแอปพลิเคชันเช่น JavaScript, CSS, รูปภาพและอื่น ๆ

  • Vendor - ไดเร็กทอรีนี้มีการอ้างอิงของผู้แต่ง

โครงสร้างของโมดูลแอปพลิเคชัน

นี่คือไดเร็กทอรีหลักของแอปพลิเคชันของคุณ Zend Framework 2 แนะนำระบบโมดูลที่มีประสิทธิภาพและยืดหยุ่นเพื่อจัดระเบียบแอปพลิเคชันอย่างมีประสิทธิภาพ Applicationโมดูลของแอปพลิเคชันโครงกระดูก(myapp)ให้การกำหนดค่าการบูตข้อผิดพลาดและการกำหนดเส้นทางไปยังแอปพลิเคชันทั้งหมด โครงสร้างของApplication โมดูลดังแสดงด้านล่าง -

├── module 
│   └── Application 
│       ├── config 
│       │   └── module.config.php 
│       ├── src 
│       │   ├── Controller 
│       │   │   └── IndexController.php 
│       │   └── Module.php 
│       ├── test 
│       │   └── Controller 
│       │       └── IndexControllerTest.php 
│       └── view 
│           ├── application 
│           │   └── index 
│           │       └── index.phtml 
│           ├── error 
│           │   ├── 404.phtml 
│           │   └── index.phtml 
│           └── layout 
│               └── layout.phtml

ให้เราอธิบายรายละเอียดเกี่ยวกับไดเร็กทอรีโมดูลเหล่านี้ -

  • Application- นี่คือไดเรกทอรีรากของโมดูล ชื่อของโฟลเดอร์จะตรงกับชื่อของโมดูลและชื่อนี้ยังใช้เป็นเนมสเปซ PHP ของคลาสทั้งหมดที่กำหนดไว้ภายในโมดูล จะเป็นที่ตั้งของระบบ MVC ตลอดจนการกำหนดค่าบริการที่ใช้และไฟล์ bootstrap ของคุณ

  • Config - การกำหนดค่าโมดูลอิสระ

  • Src - ตรรกะทางธุรกิจหลักของแอปพลิเคชัน

  • View- มีไฟล์การออกแบบ / การนำเสนอ (HTML) ตัวอย่างเช่น index.phtml

  • src/Module.php- เป็นหัวใจหลักของโมดูล ทำงานเป็น "ตัวควบคุมด้านหน้า" สำหรับโมดูล กระบวนการ Zendsrc/Module.php ก่อนประมวลผลคลาส PHP ใด ๆ ในโมดูลนี้

  • Application/config/module.config.php - ใช้สำหรับการกำหนดค่าเราเตอร์และไฟล์โหลดอัตโนมัติ

  • Application/view/layout- เลย์เอาต์แสดงถึงส่วนทั่วไปของหลายมุมมอง ตัวอย่างเช่นส่วนหัวและส่วนท้ายของหน้า โดยค่าเริ่มต้นเค้าโครงควรเก็บไว้ในไฟล์views/layoutsfolder.

โมดูลทั้งหมดมีโครงสร้างเดียวกันหรือคล้ายกันกับโมดูลแอปพลิเคชันข้างต้น

ในบทนี้เราจะเรียนรู้วิธีสร้างโมดูลที่ใช้ MVC ใน Zend Framework ให้เราสร้างโมดูลที่เรียกว่า asTutorial เพื่อทำความเข้าใจกระบวนการสร้างโมดูล

  • สร้างคลาส PHP ใหม่ชื่อ Module ภายในไดเร็กทอรี –myapp / module / Tutorial / src / และใช้ ConfigProviderInterface

  • ชุด Tutorial เป็นเนมสเปซสำหรับ Module ชั้นเรียน.

  • เขียนฟังก์ชันสาธารณะ getConfig ใน Module คลาสและส่งคืนไฟล์คอนฟิกูเรชันสำหรับ Tutorial โมดูล.

รหัสที่สมบูรณ์สำหรับ Module คลาสมีดังนี้ -

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

กำหนดค่า Tutorial โมดูลใน composer.json ภายใต้ autoload โดยใช้รหัสต่อไปนี้

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

อัปเดตแอปพลิเคชันโดยใช้โปรแกรมแต่งเพลง update คำสั่งดังที่แสดงด้านล่าง

composer update

composer คำสั่งจะทำการเปลี่ยนแปลงที่จำเป็นในแอปพลิเคชันและแสดงบันทึกในพรอมต์คำสั่งดังที่แสดงด้านล่าง -

Loading composer repositories with package information 
Updating dependencies (including require-dev) 
   - Removing zendframework/zend-component-installer (0.3.0) 
   - Installing zendframework/zend-component-installer (0.3.1) 
   Downloading: 100%           
   
   - Removing zendframework/zend-stdlib (3.0.1) 
   - Installing zendframework/zend-stdlib (3.1.0) 
   Loading from cache  
   
   - Removing zendframework/zend-eventmanager (3.0.1) 
   - Installing zendframework/zend-eventmanager (3.1.0) 
   Downloading: 100%           
   
   - Removing zendframework/zend-view (2.8.0) 
   - Installing zendframework/zend-view (2.8.1) 
   Loading from cache  
   
   - Removing zendframework/zend-servicemanager (3.1.0) 
   - Installing zendframework/zend-servicemanager (3.2.0) 
   Downloading: 100%           
   
   - Removing zendframework/zend-escaper (2.5.1) 
   - Installing zendframework/zend-escaper (2.5.2) 
   Loading from cache  
   
   - Removing zendframework/zend-http (2.5.4) 
   - Installing zendframework/zend-http (2.5.5) 
   Loading from cache  
   
   - Removing zendframework/zend-mvc (3.0.1) 
   - Installing zendframework/zend-mvc (3.0.4) 
   Downloading: 100%          
   
   - Removing phpunit/phpunit (5.7.4) 
   - Installing phpunit/phpunit (5.7.5) 
   Downloading: 100%           

Writing lock file 
Generating autoload files

สร้างไฟล์คอนฟิกูเรชันโมดูล“ module.config.php” ที่ /config/ ด้วยรหัสต่อไปนี้ -

<?php  
namespace Tutorial;  
   
use Zend\ServiceManager\Factory\InvokableFactory; 
use Zend\Router\Http\Segment;  
return [ 
   'controllers' => [ 
      'factories' => [Controller\TutorialController::class => InvokableFactory::class,], 
   ],
   'view_manager' => [ 
      'template_path_stack' => ['tutorial' => __DIR__ . '/../view',], 
   ], 
];

ไฟล์คอนฟิกูเรชันมีสามส่วนดังนี้ -

  • Controller configuration - ระบุตัวควบคุมที่มีอยู่ภายในโมดูล

  • Routing configuration - ระบุวิธีการแก้ไขคอนโทรลเลอร์ในโมดูลให้เป็น URL

  • View configuration - ระบุการกำหนดค่าที่เกี่ยวข้องกับการดูเครื่องยนต์เช่นตำแหน่งของมุมมองเป็นต้น

กำหนดค่า Tutorial โมดูลในไฟล์คอนฟิกูเรชันระดับแอ็พพลิเคชัน - myapp / config / module.config.php

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

เรียกใช้แอปพลิเคชันโดยเรียกใช้ไฟล์ composer serve ที่รากของโฟลเดอร์แอปพลิเคชัน

เราได้เพิ่มโมดูลใหม่เรียบร้อยแล้ว แต่เรายังต้องเพิ่มไฟล์ Controller, Routing และ Views เพื่อรันไฟล์ Tutorial โมดูล.

ตามที่กล่าวไว้ก่อนหน้านี้ controllerมีบทบาทสำคัญใน Zend MVC Framework หน้าเว็บทั้งหมดในแอปพลิเคชันต้องได้รับการจัดการโดยคอนโทรลเลอร์

ใน Zend MVC Framework คอนโทรลเลอร์คืออ็อบเจ็กต์ที่ใช้ - Zend / Stdlib / DispatchableInterface DispatchableInterface มีวิธีการเดียว dispatchซึ่งได้รับไฟล์ Request วัตถุเป็นอินพุตทำตรรกะและส่งคืน Response วัตถุเป็นผลลัพธ์

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

ตัวอย่างง่ายๆของวัตถุ Controller ที่ส่งคืน“ Hello World” มีดังต่อไปนี้ -

use Zend\Stdlib\DispatchableInterface; 
use Zend\Stdlib\RequestInterface as Request; 
use Zend\Stdlib\ResponseInterface as Response;  
class HelloWorld implements DispatchableInterface { 
   public function dispatch(Request $request, Response $response = null) { $response->setContent("Hello World!"); 
   } 
}

DispatchableInterfaceเป็นพื้นฐานและต้องการอินเทอร์เฟซอื่น ๆ มากมายเพื่อเขียนคอนโทรลเลอร์ระดับสูง บางส่วนของอินเทอร์เฟซดังต่อไปนี้ -

  • InjectApplicationEventInterface - ใช้ในการฉีดเหตุการณ์ (Zend EventManager)

  • ServiceLocatorAwareInterface - ใช้เพื่อค้นหาบริการ (Zend ServiceManager)

  • EventManagerAwareInterface - ใช้ในการจัดการเหตุการณ์ (Zend EventManager)

คำนึงถึงสิ่งเหล่านี้ Zend Framework มีตัวควบคุมสำเร็จรูปจำนวนมากที่ใช้อินเทอร์เฟซเหล่านี้ ตัวควบคุมที่สำคัญที่สุดมีคำอธิบายด้านล่าง

AbstractActionController

AbstractActionController (Zend / Mvc / Controller / AbstractActionController) เป็นคอนโทรลเลอร์ที่ใช้มากที่สุดใน Zend MVC Framework มีคุณสมบัติที่จำเป็นทั้งหมดในการเขียนเว็บเพจทั่วไป อนุญาตให้ใช้เส้นทาง (การกำหนดเส้นทางคือการจับคู่ URL คำขอกับคอนโทรลเลอร์และหนึ่งในวิธีการ) เพื่อจับคู่ไฟล์action. เมื่อจับคู่เมธอดที่ตั้งชื่อตามการกระทำจะถูกเรียกโดยคอนโทรลเลอร์

ตัวอย่างเช่นถ้าเส้นทาง test ถูกจับคู่และเส้นทาง test ผลตอบแทน hello สำหรับการดำเนินการแล้วไฟล์ helloAction วิธีการจะถูกเรียกใช้

ให้เราเขียน TutorialController ใช้ AbstractActionController.

  • สร้างคลาส PHP ใหม่ชื่อ TutorialController โดยการขยายไฟล์ AbstractActionController และวางไว้ในไฟล์ module/Tutorial/src/Controller/ ไดเรกทอรี

  • ตั้งค่า Tutorial\Controller เป็นเนมสเปซ

  • เขียนไฟล์ indexAction วิธี.

  • ส่งคืนไฟล์ ViewModel วัตถุจาก indexActionวิธี. ViewModel ออบเจ็กต์ใช้ในการส่งข้อมูลจากคอนโทรลเลอร์เพื่อดูเอนจินซึ่งเราจะเห็นในบทต่อ ๆ ไป

รายการรหัสที่สมบูรณ์มีดังนี้ -

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

เราได้เพิ่มไฟล์ TutorialController.

AbstractRestfulController

AbstractRestfulController (Zend \ Mvc \ Controller \ AbstractRestfulController) ตรวจสอบ HTTP method ของคำขอที่เข้ามาและตรงกับการดำเนินการ (วิธีการ) โดยพิจารณาจากวิธี HTTP

ตัวอย่างเช่นคำขอด้วยเมธอด GET HTTP ก็ตรงกับไฟล์ getList() วิธีการหรือ get() วิธีการถ้า id พบพารามิเตอร์ในคำขอ

AbstractConsoleController

AbstractConsoleController (Zend \ Mvc \ Controller \ AbstractConsoleController) เหมือนกับ AbstractActionController ยกเว้นว่าจะทำงานในสภาพแวดล้อมคอนโซลเท่านั้นแทนที่จะเป็นเบราว์เซอร์

แผนที่เส้นทาง Request URIเป็นวิธีการเฉพาะของคอนโทรลเลอร์ ในบทนี้เราจะดูวิธีการใช้งานเส้นทางใน Zend Framework

โดยทั่วไป URI ใด ๆ มีสามส่วน -

  • ส่วนชื่อโฮสต์
  • ส่วนเส้นทางและ
  • กลุ่มการค้นหา

ตัวอย่างเช่นใน URI / URL - http://www.example.com/index?q=data, www.example.com คือกลุ่มชื่อโฮสต์ index คือกลุ่มเส้นทางและ q=dataคือกลุ่มข้อความค้นหา โดยทั่วไปการกำหนดเส้นทางจะตรวจสอบไฟล์Page segmentกับชุดของข้อ จำกัด หากข้อ จำกัด ใด ๆ ตรงกันก็จะส่งกลับชุดของค่า หนึ่งในค่าหลักคือตัวควบคุม

การกำหนดเส้นทางยังตรวจสอบเซ็กเมนต์โฮสต์เซ็กเมนต์การค้นหาขอวิธี HTTP ขอส่วนหัว HTTP ฯลฯ ในบางสถานการณ์

เส้นทางและ RouteStack

เส้นทางเป็นวัตถุหลักในการกำหนดเส้นทาง Zend Framework มีอินเทอร์เฟซพิเศษสำหรับออบเจ็กต์เส้นทางRouteInterface. ออบเจ็กต์เส้นทางทั้งหมดต้องใช้ RouteInterface รายชื่อทั้งหมดของ RouteInterface มีดังต่อไปนี้ -

namespace Zend\Mvc\Router;  
use Zend\Stdlib\RequestInterface as Request;  
interface RouteInterface { 
   public static function factory(array $options = []); public function match(Request $request); 
   public function assemble(array $params = [], array $options = []); 
}

วิธีการหลักคือ match. วิธีการจับคู่นี้จะตรวจสอบคำขอที่ระบุกับข้อ จำกัด ที่กำหนดไว้ในนั้น หากพบรายการที่ตรงกันจะส่งกลับค่าRouteMatchวัตถุ. ออบเจ็กต์ RouteMatch นี้ให้รายละเอียดของคำร้องขอที่ตรงกันเป็นพารามิเตอร์ พารามิเตอร์เหล่านี้สามารถดึงออกมาได้RouteObject ใช้ getParams วิธี.

รายชื่อ RouteObject ที่สมบูรณ์มีดังนี้ -

namespace Zend\Mvc\Router;  
class RouteMatch { 
   public function __construct(array $params); public function setMatchedRouteName($name); 
   public function getMatchedRouteName(); 
   public function setParam($name, $value); 
   public function getParams(); 
   public function getParam($name, $default = null); 
}

โดยทั่วไปแอปพลิเคชัน MVC ทั่วไปมีหลายเส้นทาง แต่ละเส้นทางนี้จะได้รับการประมวลผลตามลำดับ LIFO และจะมีการจับคู่และส่งคืนเส้นทางเดียว หากไม่มีเส้นทางที่ตรงกัน / ส่งคืนแอปพลิเคชันจะแสดงข้อผิดพลาด“ ไม่พบหน้า” Zend Framework มีอินเทอร์เฟซสำหรับประมวลผลเส้นทางRouteStackInterface. RouteStackInterface นี้มีตัวเลือกในการเพิ่ม / ลบเส้นทาง

รายการทั้งหมดของ RouteStackInterface มีดังต่อไปนี้ -

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

Zend framework มีการใช้งาน RouteStack อินเทอร์เฟซและมีดังนี้ -

  • SimpleRouteStack
  • TreeRouteStack

ประเภทของเส้นทาง

Zend framework มีออบเจ็กต์เส้นทางสำเร็จรูปจำนวนมากสำหรับทุกสถานการณ์ภายใต้เนมสเปซ "Zend \ Mvc \ Router \ Http" เพียงพอที่จะเลือกและใช้ออบเจ็กต์เส้นทางที่เหมาะสมสำหรับสถานการณ์ที่กำหนด

เส้นทางที่มีดังต่อไปนี้ -

  • Hostname - ใช้เพื่อจับคู่ส่วนโฮสต์ของ URI

  • Literal - ใช้เพื่อจับคู่ URI ที่แน่นอน

  • Method - ใช้เพื่อจับคู่วิธี HTTP ของคำขอที่เข้ามา

  • Part - ใช้เพื่อจับคู่ส่วนของส่วนเส้นทาง URI โดยใช้ตรรกะที่กำหนดเอง

  • Regex - ใช้เพื่อจับคู่ส่วนเส้นทาง URI ตามรูปแบบ Regex

  • Schema - ใช้เพื่อจับคู่ URI Schema เช่น http, https เป็นต้น

  • Segment - ใช้เพื่อจับคู่เส้นทาง URI โดยแบ่งออกเป็นหลายส่วน

ให้เราดูวิธีการเขียนตัวอักษรและเส้นทางส่วนที่ใช้บ่อยที่สุด โดยปกติเส้นทางจะระบุไว้ในไฟล์คอนฟิกูเรชันของแต่ละโมดูล -module.config.php.

เส้นทางที่แท้จริง

โดยปกติเส้นทางจะถูกสอบถามตามลำดับ LIFO เส้นทาง Literal ใช้สำหรับการจับคู่เส้นทาง URI

มีการกำหนดดังที่แสดงด้านล่าง -

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

เส้นทางข้างต้นตรงกับ /path ใน url คำขอและส่งคืน index เป็น action และ IndexController เป็นตัวควบคุม

เส้นทางกลุ่ม

เส้นทางแบบแบ่งกลุ่มจะใช้เมื่อใดก็ตามที่ URL ของคุณควรมีพารามิเตอร์ตัวแปร

มีการอธิบายไว้ด้านล่าง -

$route = Segment::factory(array( 
   'route' => '/:controller[/:action]', 
   'constraints' => array( 
      'controller' => '[a-zA-Z][a-zA-Z0-9_-]+', 
      'action' => '[a-zA-Z][a-zA-Z0-9_-]+', 
   ), 
   'defaults' => array( 
      'controller' => 'Application\Controller\IndexController', 
      'action' => 'index',), 
));

ในที่นี้กลุ่มจะแสดงด้วยเครื่องหมายจุดคู่และตามด้วยอักขระที่เป็นตัวเลขและตัวอักษร หากคุณเก็บเซ็กเมนต์ไว้เป็นทางเลือกก็จะปิดด้วยวงเล็บ แต่ละส่วนอาจมีข้อ จำกัด ที่เกี่ยวข้อง ข้อ จำกัด แต่ละข้อเป็นนิพจน์ทั่วไป

การกำหนดค่าเส้นทางในโมดูลการสอน

ให้เราเพิ่มเส้นทางเซ็กเมนต์ในโมดูลการสอนของเรา อัปเดตไฟล์การกำหนดค่าโมดูลการสอน -module.config.php สามารถดูได้ที่ myapp/module/Tutorial/config.

<?php  
namespace Tutorial;  
use Zend\ServiceManager\Factory\InvokableFactory; 
use Zend\Router\Http\Segment;  
return [ 
   'controllers' => [ 
      'factories' => [ 
         Controller\TutorialController::class => InvokableFactory::class, 
      ], 
   ], 
   'router' => [ 
      'routes' => [ 
         'tutorial' => [ 
            'type'    => Segment::class, 
               'options' => [ 
                  'route' => '/tutorial[/:action[/:id]]', 
                  'constraints' => [ 
                     'action' => '[a-zA-Z][a-zA-Z0-9_-]*', 
                     'id'     => '[0-9]+', 
                  ], 
                  'defaults' => [
                     'controller' => Controller\TutorialController::class, 
                     'action'     => 'index', 
                  ], 
               ], 
            ], 
      ], 
   ], 
   'view_manager' => [ 
      'template_path_stack' => ['tutorial' => __DIR__ . '/../view',], 
   ], 
];

เราได้เพิ่มเส้นทางสำหรับไฟล์ Tutorialโมดูล. เราเป็นเพียงขั้นตอนเดียวในการจบโมดูลการสอนของเรา เราจำเป็นต้องเพิ่มView สำหรับโมดูลของเราซึ่งเราจะเรียนรู้ในบทต่อไป

View Layer คือเลเยอร์การนำเสนอของแอปพลิเคชัน MVC มันแยกตรรกะของแอปพลิเคชันออกจากตรรกะการนำเสนอ ในเว็บแอปพลิเคชัน PHP ทั่วไปตรรกะทางธุรกิจและการออกแบบทั้งหมดจะผสมผสานกัน Intermixing ช่วยให้พัฒนาได้เร็วขึ้นในโครงการขนาดเล็ก แต่มันล้มเหลวอย่างน่าอนาถในโครงการขนาดใหญ่ที่มีสถาปัตยกรรมระดับสูงเข้ามาเกี่ยวข้อง ในการเปลี่ยนการออกแบบเว็บแอปพลิเคชันนักพัฒนาจำเป็นต้องทำงานกับตรรกะทางธุรกิจด้วย ซึ่งอาจส่งผลให้เกิดความหายนะทางธุรกิจ

Zend Framework ให้เลเยอร์มุมมองที่มีความคิดดีสะอาดยืดหยุ่นและขยายได้ เลเยอร์มุมมองมีให้ใช้งานเป็นโมดูลแยกต่างหากZend/View และรวมเข้ากับ Zend/Mvcโมดูล. Zend View Layer ถูกแยกออกเป็นหลาย ๆ องค์ประกอบที่มีปฏิสัมพันธ์กันอย่างดี

ส่วนประกอบต่างๆมีดังนี้ -

  • Variables Containers - เก็บดูข้อมูลของเลเยอร์

  • View Models - เก็บคอนเทนเนอร์ตัวแปรและเทมเพลตการออกแบบ

  • Renderers - ประมวลผลข้อมูลและเทมเพลตจาก View Model และส่งออกการแสดงการออกแบบอาจเป็นเอาต์พุต html สุดท้าย

  • Resolvers - แก้ไขเทมเพลตที่มีอยู่ใน View Model ในลักษณะที่ Renderer สามารถใช้งานได้

  • View (Zend\View\View) - แผนที่ร้องขอไปยังตัวแสดงผลแล้วเรนเดอร์เพื่อตอบสนอง

  • Rendering Strategies - ใช้โดย View เพื่อขอแผนที่เพื่อ renderer

  • Response Strategies - ใช้โดย View เพื่อแสดงแผนที่เพื่อตอบสนอง

เลเยอร์มุมมอง View ประมวลผล ViewModelแก้ไขเทมเพลตโดยใช้ไฟล์ Resolverแสดงผลโดยใช้ Rendering Strategy และสุดท้ายส่งออกโดยใช้ไฟล์ Response Renderer.

ดูการกำหนดค่าเลเยอร์

เช่นเดียวกับคอนโทรลเลอร์สามารถกำหนดค่าเลเยอร์มุมมองในไฟล์คอนฟิกูเรชันของโมดูลที่เรียกว่า - module.config.php. การกำหนดค่าหลักคือการระบุตำแหน่งที่จะวางเทมเพลต ซึ่งสามารถทำได้โดยเพิ่มการกำหนดค่าต่อไปนี้ใน“ module.config.php”

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

ตามค่าเริ่มต้นเลเยอร์ View มีลักษณะการทำงานเริ่มต้นสำหรับส่วนประกอบทั้งหมด ตัวอย่างเช่นกViewModelแก้ไขชื่อเทมเพลตของการดำเนินการของคอนโทรลเลอร์ภายในรูทเทมเพลตตามกฎ "ตัวพิมพ์เล็กชื่อโมดูล / ตัวพิมพ์เล็ก - ตัวควบคุมชื่อ / ตัวพิมพ์เล็ก - ชื่อการกระทำ" อย่างไรก็ตามสิ่งนี้สามารถแทนที่ได้โดยไฟล์setTemplate() วิธีการของ ViewModel

คอนโทรลเลอร์และ View Layer

โดยค่าเริ่มต้นคอนโทรลเลอร์ไม่จำเป็นต้องส่งข้อมูลใด ๆ ไปยังเลเยอร์มุมมอง ก็เพียงพอที่จะเขียนแม่แบบในตำแหน่งที่เหมาะสม

ตัวอย่างเช่นในตัวอย่างของเรา TutorialControllerต้องวางเทมเพลตไว้ที่ myapp/module/Tutorial/view/tutorial/tutorial/index.phtml. index.phtmlหมายถึงเทมเพลตที่ใช้ PHP และ PHPRenderer จะแสดงผล มีตัวแสดงผลอื่น ๆ เช่นJsonRenderer สำหรับ json เอาต์พุตและ FeedRenderer สำหรับ rss และ atom เอาท์พุท

รายชื่อที่สมบูรณ์มีดังนี้ -

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

เทมเพลตแอปพลิเคชัน Zend

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

ในที่สุดเราก็ทำไฟล์ Tutorial โมดูลและเราสามารถเข้าถึงได้โดยใช้ url - http://localhost:8080/tutorial.

การส่งผ่านข้อมูลไปยังดูเลเยอร์

วิธีที่ง่ายที่สุดในการส่งข้อมูลไปยังเลเยอร์มุมมองคือการใช้ไฟล์ ViewModelข้อโต้แย้ง การเปลี่ยนแปลงindexAction วิธีการมีดังนี้ -

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

ตอนนี้เปลี่ยนไฟล์ index.phtml ไฟล์ดังนี้ -

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

ดูผู้ช่วยเหลือ

View Helper ใช้เพื่อเขียนฟังก์ชันอะตอมขนาดเล็กที่จะใช้ในเทมเพลต Zend framework มีอินเทอร์เฟซ Zend \ View \ Helper \ HelperInterface เพื่อเขียนตัวช่วยมุมมองมาตรฐาน

HelperInterface มีเพียงสองวิธี

  • setView() - วิธีนี้ยอมรับอินสแตนซ์ / การใช้งาน Zend \ View \ Renderer \ RendererInterface

  • getView() - ใช้เพื่อดึงข้อมูลอินสแตนซ์นั้น

รายการรหัสที่สมบูรณ์ของ HelperInterface มีดังนี้ -

namespace Zend\View\Helper;  
use Zend\View\Renderer\RendererInterface as Renderer;  
interface HelperInterface { 
   /** 
      * Set the View object 
      * 
      * @param  Renderer $view 
      * @return HelperInterface 
   */ 
   public function setView(Renderer $view);  
   /** 
      * Get the View object 
      * 
      * @return Renderer 
   */ 
   public function getView(); 
}

หากต้องการใช้ตัวช่วยในสคริปต์มุมมองของคุณให้เข้าถึงโดยใช้ $this->helperName().

ตัวช่วยในตัว

Zend Framework มีฟังก์ชั่นตัวช่วยในตัวมากมายสำหรับวัตถุประสงค์ต่างๆ View Helpers บางส่วนมีอยู่ในไฟล์zend-mvc มีดังนี้ -

URL

ตัวช่วย URL ใช้เพื่อสร้าง URL ที่ตรงกับเส้นทางที่กำหนดในแอปพลิเคชัน

คำจำกัดความของตัวช่วย URL คือ -

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

ตัวอย่างเช่นในโมดูลการสอนเส้นทางถูกตั้งชื่อเป็น tutorial และมีสองพารามิเตอร์ action และ id. เราสามารถใช้ตัวช่วย URL เพื่อสร้าง URL ที่แตกต่างกันสองรายการดังที่แสดงด้านล่าง -

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

ผลลัพธ์จะเป็นดังนี้ -

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

ตัวยึด

ตัวช่วยตัวยึดใช้เพื่อคงเนื้อหาระหว่างดูสคริปต์และดูอินสแตนซ์ มีตัวเลือกในการตั้งค่าข้อมูลในขั้นต้นแล้วใช้ในระยะต่อมา

ตัวอย่างเช่นเราสามารถตั้งค่าพูด company name แล้วใช้ในสถานที่อื่น ๆ ทั้งหมด

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

ตัวยึดตำแหน่งมีตัวเลือกขั้นสูงบางอย่างในการสร้างเนื้อหาที่ซับซ้อนจากอาร์เรย์ PHP และวัตถุ นอกจากนี้ยังมีตัวเลือกในการจับภาพบางส่วนของเทมเพลต

ตัวอย่างเช่นรหัสต่อไปนี้จะรวบรวมผลลัพธ์ของเทมเพลตระหว่างและเก็บไว้ในไฟล์ productlist ตัวยึด

Class – Product

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

Controller

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

Template

<!-- start capture --> 
<?php $this->placeholder('productlist')->captureStart(); 
   foreach ($this->products as $product): ?> 
<div> 
   <h2><?= $product->name ?></h2> <p><?= $product->description ?></p> 
</div> 
<?php endforeach; ?> 
<?php $this->placeholder('productlist')->captureEnd() ?> <!-- end capture --> <?= $this->placeholder('productlist') ?>

Result

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

Doctype

ตัวช่วย Doctype ใช้เพื่อสร้างหลักประเภท html ต่างๆ เป็นการดำเนินการอย่างเป็นรูปธรรมของไฟล์Placeholderผู้ช่วย. คุณสามารถตั้งค่าประเภทหลักในไฟล์ bootstrap และไฟล์ config

การใช้งานพื้นฐานแสดงไว้ด้านล่าง -

Application Bootstrap file

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

Module Configuration

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

Template

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

HeadTitle

ผู้ช่วย HeadTitle ใช้เพื่อสร้างองค์ประกอบหัวเรื่อง html เป็นการนำไปปฏิบัติอย่างเป็นรูปธรรมPlaceholderผู้ช่วย. Zend มีตัวเลือกในการตั้งชื่อเรื่องในไฟล์คอนฟิกูเรชันโมดูลและสามารถตั้งค่าได้ทุกระดับเช่นไซต์โมดูลคอนโทรลเลอร์แอ็คชั่น ฯลฯ โค้ดบางส่วนสำหรับ HeadTitle มีดังต่อไปนี้ -

Module

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

Template

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

Result

action - controller - module - Zend Framework

เฮดเมตา

ตัวช่วย HeadMeta ใช้เพื่อสร้างเมตาแท็ก html เป็นการนำตัวช่วย Placeholder ไปใช้อย่างเป็นรูปธรรม

Template -

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

Result

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

HeadLink

ตัวช่วย HeadLink ใช้เพื่อสร้างลิงก์ html เพื่อรวมทรัพยากรภายนอก เป็นการนำตัวช่วย Placeholder ไปใช้อย่างเป็นรูปธรรม

Template

<?php 
   // setting links in a view script: 
   $this->headLink(['rel' => 'icon', 'href' => '/img/favicon.ico'], 'PREPEND') 
      ->appendStylesheet('/styles/site.css') 
      ->prependStylesheet('/styles/mystyle.css', 'screen', true, ['id' => 'mystyle']);  
   
   // rendering the links from the layout: 
   echo $this->headLink(); 
?>

Result

<link href = "/styles/mystyle.css" media = "screen" rel = "stylesheet" 
   type = "text/css" id = "mystyle"> 
<link href = "/img/favicon.ico" rel = "icon"> 
<link href = "/styles/site.css" media = "screen" rel = "stylesheet" type = "text/css">

HeadStyle

ตัวช่วย HeadStyle ใช้เพื่อสร้างสไตล์ CSS แบบอินไลน์ เป็นการนำตัวช่วย Placeholder ไปใช้อย่างเป็นรูปธรรม

Template

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

HeadScript

HeadScript ใช้เพื่อสร้างสคริปต์แบบอินไลน์หรือเพื่อรวมสคริปต์ภายนอก เป็นการนำตัวช่วย Placeholder ไปใช้อย่างเป็นรูปธรรม

Template

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

อินไลน์สคริปต์

InlineScript ใช้เพื่อสร้างสคริปต์ทั้งในส่วนหัวและส่วนเนื้อหาของเทมเพลต html ได้มาจาก HeadScript

HTMLList

HTMLList ใช้เพื่อสร้างรายการที่เรียงลำดับและไม่เรียงลำดับ คำจำกัดความของ HTMLList มีดังนี้ -

Definition

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

Template

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

Result

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

วงจร

วงจรถูกใช้เพื่อสร้างทางเลือกอื่นในสภาพแวดล้อมแบบวนซ้ำ มีฟังก์ชันกำหนดถัดไปและก่อนหน้า

Controller

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

Template

<?php $this->cycle()->assign(['#F0F0F0', '#FFF'], 'colors'); ?> <table> <?php foreach ($this->data as $datum): ?> <tr style = "background-color: <?= $this->cycle()->setName('colors')>next() ?>">
      <td><?= $this->escapeHtml($datum) ?></td>
   </tr>
   <?php endforeach ?>
</table>

Result

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

ตัวช่วยในตัวที่สำคัญอื่น ๆ มีดังนี้ -

  • BasePath - BasePath ใช้เพื่อสร้างเส้นทางของโฟลเดอร์สาธารณะของรูทของแอปพลิเคชัน

  • Partial - บางส่วนใช้เพื่อแสดงเทมเพลตเฉพาะในขอบเขตตัวแปรของตัวเอง

  • PartialLoop - PartialLoop เป็นเหมือน Partial แต่ใช้ในสภาพแวดล้อมแบบวนซ้ำ

  • Identity - Identity ใช้เพื่อดึงข้อมูลประจำตัวของผู้ใช้ที่ล็อกอินจาก Authentication Service

  • JSON- JSON ถูกใช้ในสภาพแวดล้อมที่สงบโดยที่เอาต์พุตอยู่ในรูปแบบ JSON มันปล่อยส่วนหัว HTTP ที่เหมาะสมและปิดใช้งานแนวคิดโครงร่าง

ยังมีตัวช่วยมากมายใน Zend Framework เช่นไฟล์ i18n helper, form helpers, pagination helpers, navigation helpersฯลฯ

การสร้าง View Helpers

Zend Framework จัดเตรียมไว้ในตัว AbstractHelper การนำไปใช้ HelperInterface เพื่อเขียนผู้ช่วยดู

ขั้นตอนที่เกี่ยวข้องในการเขียนตัวช่วยใหม่มีดังต่อไปนี้ -

  • Step 1 - ขยายคลาส Zend \ View \ Helper \ AbstractHelper

  • Step 2 - แทนที่ไฟล์ __invoke() ฟังก์ชัน

  • Step 3 - ตั้งค่าการกำหนดค่าในไฟล์ module.config.php file.

  • Step 4 - ใช้ตัวช่วยดูในสคริปต์มุมมอง

ให้เราสร้างไฟล์ TestHelper

สร้างโฟลเดอร์ Helper ที่ myapp/module/Tutorial/src/View directory. เขียนTestHelper ภายในไดเรกทอรี Helper TestHelper.php.

รายชื่อที่สมบูรณ์มีดังนี้ -

<?php  
namespace Tutorial\View\Helper; 
use Zend\View\Helper\AbstractHelper; 
class TestHelper extends AbstractHelper { 
   public function __invoke() { 
      $output = "I am from test helper"; return htmlspecialchars($output, ENT_QUOTES, 'UTF-8'); 
   } 
}

ตั้งค่าการกำหนดค่าใน module.config.php.

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

ใช้ไฟล์ TestHelper ใน about ดูสคริปต์

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

เค้าโครงแสดงถึงส่วนทั่วไปของหลายมุมมองเช่นส่วนหัวและส่วนท้ายของหน้า โดยค่าเริ่มต้นเค้าโครงควรเก็บไว้ในไฟล์view/layout โฟลเดอร์

การกำหนดค่าเค้าโครงถูกกำหนดภายใต้ไฟล์ view_manager ใน module.config.php

การกำหนดค่าเริ่มต้นของแอปพลิเคชันโครงกระดูกมีดังนี้ -

'view_manager' => array( 
   'display_not_found_reason' => true, 
   'display_exceptions' => true, 
   'doctype' => 'HTML5', 
   'not_found_template' => 'error/404', 
   'exception_template' => 'error/index', 
   'template_map' => array( 
      'layout/layout' => __DIR__ . '/../view/layout/layout.phtml', 
      'application/index/index' => __DIR__ . '/../view/application/index/index.phtml', 
      'error/404' => __DIR__ . '/../view/error/404.phtml', 
      'error/index' => __DIR__ . '/../view/error/index.phtml', 
   ), 
   'template_path_stack' => array( 
   __DIR__ . '/../view', 
),

ที่นี่ template_mapใช้เพื่อระบุเค้าโครง หากไม่พบเค้าโครงจะส่งคืนข้อผิดพลาด ให้เราดูที่เค้าโครงหลักของแอปพลิเคชันโครงกระดูก

Layout.phtml

<?= $this->doctype() ?>  
<html lang = "en"> 
   <head> 
      <meta charset = "utf-8"> 
      <?= $this->headTitle('ZF Skeleton Application')->setSeparator(' - ')> setAutoEscape(false) ?> <?= $this->headMeta() 
         ->appendName('viewport', 'width = device-width, initial-scale = 1.0') 
         ->appendHttpEquiv('X-UA-Compatible', 'IE = edge') 
      ?>  
      
      <!-- Le styles --> 
      <?= $this->headLink(['rel' => 'shortcut icon', 'type' => 'image/vnd.microsoft.icon', 'href' => $this->basePath() . '/img/favicon.ico']) 
         ->prependStylesheet($this->basePath('css/style.css')) ->prependStylesheet($this->basePath('css/bootstraptheme.min.css')) 
         ->prependStylesheet($this->basePath('css/bootstrap.min.css')) ?> <!-- Scripts --> <?= $this->headScript() 
         ->prependFile($this->basePath('js/bootstrap.min.js')) ->prependFile($this->basePath('js/jquery-3.1.0.min.js')) 
      ?> 
   </head> 
   
   <body> 
      <nav class = "navbar navbar-inverse navbar-fixed-top" role = "navigation"> 
         <div class = "container"> 
            <div class = "navbar-header"> 
               <button type = "button" class = "navbar-toggle" data-
                  toggle = "collapse" data-target = ".navbar-collapse"> 
                  <span class = "icon-bar"></span> 
                  <span class = "icon-bar"></span> 
                  <span class = "icon-bar"></span> 
               </button> 
            
               <a class = "navbar-brand" href = "<?= $this->url('home') ?>"> <img src = "<?= $this->basePath('img/zf-logo-mark.svg') ?>
                     " height = "28" alt = "Zend Framework <?= \Application\Module::
                     VERSION ?>"/> Skeleton Application 
               </a> 
            </div>
         
            <div class = "collapse navbar-collapse"> 
               <ul class = "nav navbar-nav"> 
                  <li class = "active"><a href = "<?= 
                     $this->url('home') ?>">Home</a></li> </ul> </div> </div> </nav> <div class = "container"> <?= $this->content ?> 
         <hr> 
         <footer> 
            <p>© 2005 - <?= date('Y') ?> by Zend Technologies Ltd. 
               All rights reserved.</p> 
         </footer> 
      </div> 
      <?= $this->inlineScript() ?> 
   </body> 
</html>

ในขณะที่คุณวิเคราะห์เค้าโครงส่วนใหญ่จะใช้ตัวช่วยดูซึ่งเราได้พูดถึงในบทก่อนหน้า เมื่อเราดูใกล้ขึ้นเลย์เอาต์จะใช้ตัวแปรพิเศษ$this->content. ตัวแปรนี้มีความสำคัญเนื่องจากจะถูกแทนที่ด้วยสคริปต์มุมมอง (เทมเพลต) ของหน้าที่ร้องขอจริง

การสร้างเค้าโครงใหม่

ให้เราสร้างเค้าโครงใหม่สำหรับโมดูลการสอนของเรา

เริ่มต้นด้วยการสร้างไฟล์ tutorial.css file ภายใต้ไดเร็กทอรี“ public / css”

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

สร้างไฟล์เลย์เอาต์ใหม่ newlayout.phtmlที่ / myapp / module / Tutorial / view / layout / และคัดลอกเนื้อหาจากเค้าโครงที่มีอยู่ จากนั้นเพิ่มไฟล์tutorial.css สไตล์ชีตโดยใช้ HeadLink คลาสตัวช่วยภายในส่วนหัวเค้าโครง

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

เพิ่มไฟล์ about ลิงก์ในส่วนการนำทางโดยใช้ไฟล์ URL ผู้ช่วย.

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

หน้าเค้าโครงนี้เป็นเรื่องปกติสำหรับแอปพลิเคชันโมดูลการสอน อัปเดตไฟล์view_manager ส่วนของไฟล์คอนฟิกูเรชันโมดูลการสอน

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

เพิ่มไฟล์ aboutAction ฟังก์ชันใน TutorialController.

public function aboutAction() { 
}

เพิ่มไฟล์ about.phtml ที่ myapp / module / Tutorial / view / tutorial / tutorial / โดยมีเนื้อหาดังต่อไปนี้

<h2>About page</h2>

ตอนนี้คุณพร้อมที่จะเรียกใช้แอปพลิเคชันในที่สุด - http://localhost:8080/tutorial/about.

ในบทนี้เราจะพูดถึงโมเดลต่างๆและฐานข้อมูลของ Zend Framework

โมเดลใน Zend Framework

แบบจำลองกำหนดการแสดงข้อมูลเชิงตรรกะของแอ็พพลิเคชัน ตัวอย่างเช่นในแอปพลิเคชันตะกร้าสินค้า - ผลิตภัณฑ์ลูกค้ารถเข็นและคำสั่งซื้อเป็นแบบจำลอง กำหนดคุณสมบัติของเอนทิตีที่เก็บไว้ แนวคิดบางส่วนของแบบจำลองมีดังนี้ -

  • ตัวควบคุมสื่อสารกับโมเดลและขอให้ดึงข้อมูลที่ต้องการ ข้อมูลที่ดึงมานี้จะถูกส่งผ่านโดยคอนโทรลเลอร์ไปยัง View สุดท้าย View จะแสดงผลแบบจำลองเป็นข้อมูลการนำเสนอที่ผู้ใช้บริโภคได้

  • เป็นเรื่องยากมากที่โมเดลจะโต้ตอบกับมุมมองโดยตรง แต่บางครั้งก็อาจเกิดขึ้นได้

  • นางแบบสามารถพูดคุยกันได้และไม่มีตัวตน พวกเขามีความสัมพันธ์ซึ่งกันและกัน ความสัมพันธ์เหล่านี้ทำให้คอนโทรลเลอร์รับข้อมูลได้ง่ายและเร็วขึ้นเนื่องจากไม่จำเป็นต้องโต้ตอบกับโมเดลต่างๆ โมเดลสามารถทำได้ด้วยตัวเอง

ลองมาดูแบบจำลองง่ายๆ - MyModel

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

ฐานข้อมูลใน Zend Framework

Zend framework มีคลาสที่เรียบง่ายและมีฟีเจอร์มากมาย Zend \ Db \ TableGateway \ TableGateway เพื่อค้นหาแทรกอัปเดตและลบข้อมูลจากตารางฐานข้อมูล

ให้เราดูวิธีการเชื่อมต่อ MySqlservice ผ่านโปรแกรมควบคุม PDO ของ PHP ใน Zend framework ผ่านขั้นตอนต่อไปนี้

ขั้นตอนที่ 1: สร้างฐานข้อมูลใน MySQL

สร้างฐานข้อมูล tutorialsในเซิร์ฟเวอร์ MySQL ภายใน เราสามารถใช้phpmyadminหรือเครื่องมือ MySQL GUI อื่น ๆ เพื่อจุดประสงค์นี้ ให้เราใช้ไฟล์MySQL clientในพรอมต์คำสั่ง เชื่อมต่อกับเซิร์ฟเวอร์ mysql และรันคำสั่งต่อไปนี้เพื่อสร้างไฟล์tutorial ฐานข้อมูล.

create database tutorials

ขั้นตอนที่ 2: สร้างตารางในฐานข้อมูลแบบฝึกหัด

ตอนนี้ให้เราสร้างฐานข้อมูล book ใน tutorials db โดยใช้คำสั่ง SQL ต่อไปนี้

use tutorials;  
CREATE TABLE book ( 
   id int(11) NOT NULL auto_increment, 
   author varchar(100) NOT NULL, 
   title varchar(100) NOT NULL, 
   PRIMARY KEY (id) 
);

ขั้นตอนที่ 3: เติมข้อมูลในตารางหนังสือ

เติมไฟล์ bookตารางที่มีข้อมูลตัวอย่าง ใช้คำสั่ง SQL ต่อไปนี้

INSERT INTO book (author, title) VALUES ('Dennis Ritchie', 'C Programming'); 
INSERT INTO book (author, title) VALUES ('James gosling', 'Java Programming'); 
INSERT INTO book (author, title) VALUES ('Rasmus Lerdorf', 'Programming PHP');

ขั้นตอนที่ 4: อัปเดตการเชื่อมต่อฐานข้อมูล

อัพเดตไฟล์คอนฟิกูเรชันส่วนกลางซึ่งก็คือ - myapp / config / autoload / global.php ด้วยข้อมูลไดรฟ์ฐานข้อมูลที่จำเป็น

<?php 
return array( 
   'db' => array( 
      'driver' => 'Pdo', 
      'dsn' => 'mysql:dbname = tutorials;host = localhost', 
      'driver_options' => array( 
         PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\'' 
      ), 
   ), 
   'service_manager' => array( 
      'factories' => array(  
         'Zend\Db\Adapter\Adapter' => 'Zend\Db\Adapter\AdapterServiceFactory', 
      ), 
   ), 
);

ขั้นตอนที่ 5: อัปเดตข้อมูลรับรองฐานข้อมูล

อัพเดตข้อมูลรับรองฐานข้อมูลในไฟล์คอนฟิกูเรชันภายในซึ่งก็คือ - myapp / config / autoload / local.php ด้วยวิธีนี้เราสามารถแยกข้อมูลรับรองการเชื่อมต่อฐานข้อมูลแบบโลคัลและแบบสดได้

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

ขั้นตอนที่ 6: สร้างโมเดลสำหรับหนังสือ

ให้เราสร้างแบบจำลอง Book ในโมดูลของเรา srcไดเรกทอรี โดยทั่วไปโมเดลจะถูกจัดกลุ่มไว้ในโฟลเดอร์ Model - /myapp/module/Tutorial/src/Model/Book.php

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

ขั้นตอนที่ 7: ใช้ exchangeArray ในโมเดลหนังสือ

TableGateway โต้ตอบกับโมเดลผ่านไฟล์ exchangeArrayฟังก์ชัน อาร์กิวเมนต์มาตรฐานของฟังก์ชัน exchangeArray คือชุดผลลัพธ์ฐานข้อมูลที่จัดเก็บเป็นอาร์เรย์ PHP ใช้exchangeArrayfunctionคุณสมบัติของโมเดลสามารถซิงค์กับตารางฐานข้อมูลที่เกี่ยวข้องได้อย่างง่ายดาย

อัปเดตโมเดล Book ดังแสดงด้านล่าง -

<?php  
namespace Tutorial\Model;  
class Book { 
   public $id; public $author; 
   public $title; public function exchangeArray($data) { 
      $this->id = (!empty($data['id'])) ? $data['id'] : null; $this->Author = (!empty($data['author'])) ? $data['author'] : null; 
      $this->Title = (!empty($data['title'])) ? $data['title'] : null; 
   } 
}

ขั้นตอนที่ 8: ใช้ TableGateway เพื่อดึงหนังสือ

สร้างชั้นเรียน BookTableเพื่อดึงข้อมูลหนังสือจากฐานข้อมูล สร้างคลาส BookTable ในไฟล์Model โฟลเดอร์นั้นเอง

<?php  
namespace Tutorial\Model;  
use Zend\Db\TableGateway\TableGatewayInterface;  
class BookTable {
   protected $tableGateway; 
   public function __construct(TableGatewayInterface $tableGateway) { $this->tableGateway = $tableGateway; } public function fetchAll() { $resultSet = $this->tableGateway->select(); return $resultSet; 
   } 
}

เราได้ใช้ select()วิธีการของคลาส TableGateway เพื่อดึงข้อมูลหนังสือจากฐานข้อมูล แต่เราไม่ได้ใช้การอ้างอิงใด ๆ กับตาราง -bookในรหัส TableGateway มีลักษณะทั่วไปและสามารถดึงข้อมูลจากตารางใดก็ได้โดยใช้การกำหนดค่าบางอย่าง โดยปกติการกำหนดค่าเหล่านี้จะทำในไฟล์module.config.php ซึ่งเราจะพูดถึงในขั้นตอนต่อไป

ขั้นตอนที่ 9: กำหนดค่าคลาส BookTable

อัปเดตโมดูลการสอน Module.php กับ getServiceConfig() วิธี.

<?php
namespace Tutorial;
use Zend\Db\Adapter\AdapterInterface;
use Zend\Db\ResultSet\ResultSet;
use Zend\Db\TableGateway\TableGateway;
use Zend\ModuleManager\Feature\ConfigProviderInterface;

class Module implements ConfigProviderInterface {
   
   public function getConfig() {
      return include __DIR__ . '/../config/module.config.php';
   }
   public function getServiceConfig() {
      return [
         'factories' => [
            Model\BookTable::class => function ($container) { $tableGateway = $container->get(Model\BookTableGateway::class); $table = new Model\BookTable($tableGateway); return $table;
            },
            Model\BookTableGateway::class => function ($container) { $dbAdapter = $container->get(AdapterInterface::class); $resultSetPrototype = new ResultSet();
               $resultSetPrototype->setArrayObjectPrototype(new Model\Book()); return new TableGateway('book', $dbAdapter, null, $resultSetPrototype);
            },
         ],
      ];
   }
}

ที่นี่เราได้ลงทะเบียนไฟล์ BookTableคลาสโดยใช้ตัวจัดการบริการ ชั้น BookTable ใช้เพื่อดึงข้อมูลหนังสือและโดยการลงทะเบียนเราสามารถเข้าถึงได้ทุกที่ที่ต้องการ เนื่องจากมีการแชร์บริการที่ลงทะเบียนไว้ซึ่งจะเพิ่มประสิทธิภาพลดการใช้หน่วยความจำ ฯลฯ

รายการอื่น Model \ BookTableGateway :: class คือวัตถุ TableGateway เฉพาะสำหรับ Book แบบจำลองและเป็นการพึ่งพาของ BookTable.

ขั้นตอนที่ 10: อัปเดตการกำหนดค่าตัวควบคุมการสอน

เราต้องการไฟล์ BookTableบริการในตัวควบคุมการสอนเพื่อดึงข้อมูลหนังสือ ในการรับบริการ BookTable ให้ลงทะเบียนเป็น constructor dependency ใน TutorialController

การพึ่งพาตัวสร้างนี้ช่วยในการรับบริการ BookTable ในขณะที่ตัวควบคุมเองอยู่ในขั้นตอนการเริ่มต้น อัปเดตส่วนคอนโทรลเลอร์ของการกำหนดค่าโมดูลการสอนmodule.config.php ดังแสดงด้านล่าง

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

ขั้นตอนที่ 11: อัปเดตตัวควบคุมการสอน

ทำได้โดยปฏิบัติตามสามขั้นตอนต่อไปนี้

  • เพิ่มตัวสร้างด้วยBookTableเป็นอาร์กิวเมนต์
private $table;
public function __construct(BookTable $table) { $this->table = $table; 
}
  • ดึงข้อมูลหนังสือโดยใช้ไฟล์ BookTable's fetchAll() วิธีการและลงทะเบียนในมุมมอง

public function indexAction() { 
   $view = new ViewModel([ 
      'data' => $this->table->fetchAll(), ]); return $view; 
}
  • แสดงข้อมูลหนังสือในสคริปต์มุมมอง

<table class = "table"> 
   <tr> 
      <th>Author</th> 
      <th>Title</th> 
      <th> </th> 
   </tr> 
   <?php foreach ($data as $sampledata) : ?> 
   <tr> 
      <td><?php echo $this->escapeHtml($data->author);?></td>  
      <td><?php echo $this->escapeHtml($data->title);?></td> 
   </tr> 
   <?php endforeach ?> 
</table>

ขั้นตอนที่ 12: เรียกใช้แอปพลิเคชัน

ตรวจสอบแอปพลิเคชันโดยเรียกใช้ - http://localhost:8080/tutorial.

ตามที่กล่าวไว้ในบทสุดท้าย Zend framework ให้วิธีการทั่วไปในการเข้าถึงฐานข้อมูลโดยใช้ไฟล์ Database Driverแนวคิด. การทำงานกับฐานข้อมูลขึ้นอยู่กับข้อมูลไดรเวอร์เท่านั้นดังนั้นการเชื่อมต่อกับฐานข้อมูลอื่นจึงเกี่ยวข้องกับการเปลี่ยนข้อมูลไดรเวอร์เท่านั้น

ตอนนี้ให้เราเปลี่ยน book ตัวอย่างเพื่อเชื่อมต่อกับไฟล์ postgresql ฐานข้อมูลด้วยขั้นตอนต่อไปนี้

Step 1 - สร้างฐานข้อมูลแบบฝึกหัดในฐานข้อมูล postgresql ในเครื่องโดยใช้คำสั่งต่อไปนี้ -

CREATE DATABASE tutorials

Step 2 - เพิ่ม bookตาราง. ย้ายไปยังฐานข้อมูลใหม่และเรียกใช้สคริปต์การสร้างตาราง

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

Step 3 - เพิ่มข้อมูลหนังสือตัวอย่างโดยใช้สคริปต์ต่อไปนี้ -

INSERT INTO book (author, title) VALUES ('Dennis Ritchie', 'C Programming'); 
INSERT INTO book (author, title) VALUES ('James gosling', 'Java Programming'); 
INSERT INTO book (author, title) VALUES ('Rasmus Lerdorf', 'Programming PHP');

Step 4 - เปลี่ยนข้อมูลไดรเวอร์ในไฟล์ global.config file.

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

Step 5 - เปลี่ยนข้อมูลรับรองฐานข้อมูลในไฟล์ local.config ไฟล์.

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

Step 6 - สุดท้ายเรียกใช้แอปพลิเคชัน http://localhost:8080/tutorial. ผลลัพธ์จะเหมือนกับแอปพลิเคชัน MySQL

Zend Framework มีองค์ประกอบแยกต่างหาก zend-formเพื่อเร่งการสร้างแบบฟอร์มและกระบวนการตรวจสอบความถูกต้อง มันเชื่อมต่อโมเดลและเลเยอร์มุมมอง มันมีชุดขององค์ประกอบฟอร์มเพื่อสร้างแบบฟอร์ม html ที่สมบูรณ์จากแบบจำลองที่กำหนดไว้ล่วงหน้าซึ่งเป็นไฟล์InputFilter คลาสเพื่อตรวจสอบความถูกต้องของโมเดลกับฟอร์มและอ็อพชันเพื่อผูกข้อมูลจากฟอร์มกับโมเดลและในทางกลับกัน

ติดตั้งส่วนประกอบของฟอร์ม

สามารถติดตั้งคอมโพเนนต์ฟอร์ม Zend โดยใช้ไฟล์ Composer คำสั่งตามที่ระบุด้านล่าง -

composer require zendframework/zend-form

กรอบรูปแบบ Zend มีองค์ประกอบย่อยสามส่วนในการจัดการแบบฟอร์ม ดังที่อธิบายไว้ด้านล่างโดยละเอียด -

  • Elements - ใช้เพื่อกำหนดตัวควบคุมอินพุต html เดียวที่แมปกับคุณสมบัติในโมเดล

  • Fieldset - ใช้เพื่อจัดกลุ่มองค์ประกอบและอื่น ๆ fieldset ในลักษณะที่ซ้อนกัน

  • Form - ใช้เพื่อสร้างรูปแบบ html และประกอบด้วยองค์ประกอบและชุดฟิลด์

แบบฟอร์ม Zend มักจะสร้างขึ้นภายใต้ module//src/Form ไดเรกทอรี

ตัวอย่าง

ตอนนี้ให้เราสร้างแบบฟอร์มง่ายๆเพื่อเพิ่ม bookลงในฐานข้อมูล ในการดำเนินการนี้เราควรปฏิบัติตามขั้นตอนต่อไปนี้ -

ขั้นตอนที่ 1: สร้าง BookForm

สร้าง“ BookForm.php” ภายใต้ไดเร็กทอรี * myapp / module / Tutorial / src / Form” เพิ่มการเปลี่ยนแปลงต่อไปนี้ในไฟล์ -

<?php  
namespace Tutorial\Form;  
use Zend\Form\Form;  

class BookForm extends Form {
   
   public function __construct($name = null) { parent::__construct('book'); $this->add(array( 
         'name' => 'id', 
         'type' => 'Hidden', 
      ));  
      $this->add(array( 'name' => 'author', 'type' => 'Text', 'options' => array( 'label' => 'Author', ), )); $this->add(array( 
         'name' => 'title', 
         'type' => 'Text', 
         'options' => array( 
            'label' => 'Title', 
         ), 
      ));  
      $this->add(array( 
         'name' => 'submit', 
         'type' => 'Submit', 
         'attributes' => array( 
            'value' => 'Go', 
            'id' => 'submitbutton', 
         ), 
      )); 
   } 
}

Form คลาสให้ไฟล์ add methodเพื่อแมปโมเดลและรายละเอียดแบบฟอร์มที่เกี่ยวข้อง เราได้สร้างไฟล์BookForm โดยการขยายไฟล์ Form ชั้นเรียนและเพิ่มรายละเอียดแบบฟอร์มสำหรับ Book แบบ.

ขั้นตอนที่ 2: อัปเดตโมเดลหนังสือ Book.php

อัปเดตโมเดล ‘Book’ พร้อมตัวกรองและการตรวจสอบตามที่ระบุด้านล่าง -

<?php 
namespace Tutorial\Model;  
use Zend\InputFilter\InputFilterInterface; 
use Zend\InputFilter\InputFilterAwareInterface; 
use Zend\InputFilter\InputFilter;  

class Book implements InputFilterAwareInterface { 
   public $id; 
   public $author; public $title;  
   protected $inputFilter; public function setInputFilter(InputFilterInterface $inputFilter) { 
      throw new \Exception("Not used"); 
   }  
   public function getInputFilter() { 
      if (!$this->inputFilter) { $inputFilter = new InputFilter(); 
         $inputFilter->add(array( 'name' => 'id', 'required' => true, 'filters' => array( array('name' => 'Int'), ), )); $inputFilter->add(array( 
            'name' => 'author', 
            'required' => true, 
            'filters' => array( 
               array('name' => 'StripTags'), 
               array('name' => 'StringTrim'), 
            ), 
            'validators' => array( 
               array( 
                  'name' => 'StringLength', 
                  'options' => array( 
                     'encoding' => 'UTF-8', 
                     'min' => 1, 
                     'max' => 100, 
                  ), 
               ), 
            ), 
         )); 
         $inputFilter->add(array( 'name' => 'title', 'required' => true, 'filters' => array( array('name' => 'StripTags'), array('name' => 'StringTrim'), ), 'validators' => array( array( 'name' => 'StringLength', 'options' => array( 'encoding' => 'UTF-8', 'min' => 1, 'max' => 100, ), ), ), )); $this->inputFilter = $inputFilter; } return $this->inputFilter; 
   }  
   public function exchangeArray($data) { $this->id = (!empty($data['id'])) ? $data['id'] : null; 
      $this->author = (!empty($data['author'])) ? $data['author'] : null; $this->title = (!empty($data['title'])) ? $data['title'] : null; 
   } 
}

แต่ละรุ่นควรใช้ InputFilterAwareInterface. InputFilterAwareInterface มีสองวิธีคือsetInputFilter() และ getInputFilter().

getInputFilter ใช้เพื่อรับรายละเอียดการตรวจสอบความถูกต้องของโมเดล Zend framework มีชุดตัวกรองและตัวตรวจสอบความถูกต้องมากมายเพื่อตรวจสอบความถูกต้องของแบบฟอร์ม ตัวกรองและตัวตรวจสอบความถูกต้องบางส่วนที่ใช้ในแบบจำลองหนังสือมีดังนี้ -

  • StripTags - ลบ HTML ที่ไม่ต้องการ

  • StringTrim - ลบพื้นที่สีขาวที่ไม่จำเป็น

  • StringLength validator - ตรวจสอบให้แน่ใจว่าผู้ใช้ไม่ได้ป้อนอักขระเกินจำนวนที่กำหนด

ขั้นตอนที่ 3: อัปเดตคลาส BookTable

รวมไฟล์ saveBook วิธีการเพิ่มหนังสือลงในฐานข้อมูล

BookTable.php

<?php  
namespace Tutorial\Model;  
use Zend\Db\TableGateway\TableGatewayInterface;  

class BookTable {
   protected $tableGateway; public function __construct(TableGatewayInterface $tableGateway) { 
      $this->tableGateway = $tableGateway; 
   }  
   public function fetchAll() { 
      $resultSet = $this->tableGateway->select(); 
      return $resultSet; } public function getBook($id) { 
      $id = (int) $id; 
      $rowset = $this->tableGateway->select(array('id' => $id)); $row = $rowset->current(); if (!$row) { 
         throw new \Exception("Could not find row $id"); } return $row; 
   }  
   public function saveBook(Book $book) { $data = array ( 
         'author' => $book->author, 'title' => $book->title, 
      );  
      $id = (int) $book->id; 
      if ($id == 0) { $this->tableGateway->insert($data); } else { if ($this->getBook($id)) { $this->tableGateway->update($data, array('id' => $id));  
         } else { 
            throw new \Exception('Book id does not exist'); 
         } 
      } 
   } 
}

ขั้นตอนที่ 4: อัปเดตคลาส TutorialController

เพิ่มการดำเนินการ addAction ใหม่ในตัวควบคุมบทช่วยสอน - myapp / module / Tutorial / src / Controller / TutorialController.php

public function addAction() { 
   $form = new BookForm(); $form->get('submit')->setValue('Add');  
   $request = $this->getRequest(); 
   if ($request->isPost()) { $book = new Book(); 
      $form->setInputFilter($book->getInputFilter()); 
      $form->setData($request->getPost());  
      if ($form->isValid()) { $book->exchangeArray($form->getData()); $this->bookTable->saveBook($book); // Redirect to list of Tutorial return $this->redirect()->toRoute('tutorial'); 
      } 
   }  
   return array('form' => $form); 
}

addAction วิธีการทำกระบวนการต่อไปนี้ -

  • รับวัตถุคำขอ

  • ตรวจสอบว่าเมธอด http ของคำขอเป็นไฟล์ post วิธี.

  • หากวิธีการ http ของคำขอไม่ใช่ postเพียงแค่แสดงเทมเพลต add.phtml

  • หากวิธีการ http ของคำขอไม่ใช่ postจากนั้นจะตั้งค่า inputfilterรับข้อมูลคำขอและตั้งค่าลงใน inputfiler

  • ตรวจสอบว่าแบบฟอร์มถูกต้องหรือไม่โดยใช้ isValid() วิธีการของคลาสแบบฟอร์ม

  • ถ้าแบบฟอร์มไม่ถูกต้องฟอร์มจะแสดงเทมเพลตอีกครั้ง add.phtml

  • หากแบบฟอร์มถูกต้องจะบันทึกหนังสือลงในฐานข้อมูลและเปลี่ยนเส้นทางไปที่โฮมเพจ

ขั้นตอนที่ 5: เพิ่มเทมเพลต add.phtml

สร้างเทมเพลต - add.phtml ใต้ myapp / module / Tutorial / view / tutorial / tutorial / add.phtml

Add.phtml

<?php  
$title = 'Add new Book'; 
$this->headTitle($title);  
?>  
<h1><?php echo $this->escapeHtml($title); ?></h1>  
<?php  
if(!empty($form)) { $form->setAttribute('action', $this->url('tutorial', array('action' => 'add'))); $form->prepare();  
   echo $this->form()->openTag($form); 
   echo $this->formHidden($form->get('id')); 
   echo $this->formRow($form->get('author'))."<br>"; 
   echo $this->formRow($form->get('title'))."<br>"; 
   echo $this->formSubmit($form->get('submit')); 
   echo $this->form()->closeTag(); 
}

ที่นี่เรากำลังสร้างแบบฟอร์มหนังสือโดยใช้ไฟล์ Form ตัวอย่าง, $form.

ขั้นตอนที่ 6: เรียกใช้แอปพลิเคชัน

ตอนนี้เราสามารถเรียกใช้แอปพลิเคชัน - http://localhost:8080/tutorial/add.

Form Page

Validate Error Page

การอัปโหลดไฟล์เป็นหนึ่งในแนวคิดหลักในการเขียนโปรแกรมแบบฟอร์ม Zend framework ให้รายการที่จำเป็นทั้งหมดในการอัปโหลดไฟล์ผ่านไฟล์zend-form และ zend-inputfilter ส่วนประกอบ.

คลาส FileInput

คอมโพเนนต์ zend-inputfilter จัดเตรียมคลาส Zend \ InputFilter \ FileInput เพื่อจัดการองค์ประกอบอินพุตไฟล์ html - <input type = 'file' />. FileInputก็เหมือนกับตัวกรองอินพุตอื่น ๆ ที่มีข้อยกเว้นบางประการ มีดังนี้ -

  • เนื่องจาก PHP บันทึกรายละเอียดไฟล์ที่อัปโหลดในรูปแบบ $_FILES อาร์เรย์ส่วนกลาง FileInput รวบรวมข้อมูลไฟล์ที่อัปโหลดผ่าน $ _FILES เท่านั้น

  • จำเป็นต้องทำการตรวจสอบความถูกต้องก่อนที่คลาส FileInput จะประมวลผลข้อมูล มันเป็นพฤติกรรมที่ตรงกันข้ามกับตัวกรองอินพุตอื่น ๆ

  • Zend \ Validator \ File \ UploadFile เป็นตัวตรวจสอบค่าเริ่มต้นที่จะใช้ UploadFile ตรวจสอบรายละเอียดการป้อนไฟล์

ในการเพิ่มประเภทการอัปโหลดไฟล์ในแบบฟอร์มเราจำเป็นต้องใช้ประเภทอินพุต File. รหัสบางส่วนมีดังนี้ -

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

คลาสอื่นที่ใช้ในการอัปโหลดไฟล์คือ Zend \ Filter \ File \ RenameUpload RenameUploadใช้เพื่อย้ายไฟล์ที่อัพโหลดไปยังตำแหน่งที่เราต้องการ คลาสบางส่วนที่จะใช้ตัวกรองไฟล์มีดังนี้ -

$file = new FileInput('imagepath'); 
$file->getValidatorChain()->attach(new UploadFile()); $file->getFilterChain()->attach( 
   new RenameUpload([ 
      'target'    => './public/tmpuploads/file', 
      'randomize' => true, 
      'use_upload_extension' => true 
   ]));
$inputFilter->add($file);

ที่นี่ตัวเลือกของ RenameUpload มีดังนี้ -

  • target - เส้นทางปลายทางของไฟล์ที่อัปโหลด

  • randomize - เพิ่มสตริงแบบสุ่มเพื่อป้องกันการทำซ้ำไฟล์ที่อัปโหลด

  • use_upload_extension - ต่อท้ายนามสกุลไฟล์กับไฟล์ที่อัพโหลดไปยังเป้าหมาย

อัปโหลดไฟล์ - ตัวอย่างการทำงาน

ให้เราแก้ไขโมดูลการสอนและรวมคุณสมบัติการอัปโหลดรูปภาพ

ปรับเปลี่ยนตารางฐานข้อมูล

ให้เราเพิ่มไฟล์ imagepath คอลัมน์ไปยังตารางหนังสือโดยดำเนินการคำสั่ง SQL ต่อไปนี้ -

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

อัพเดท BookForm.php

เพิ่มองค์ประกอบการป้อนไฟล์เพื่ออัปโหลดรูปภาพในรูปแบบหนังสือ - myapp / module / Tutorial / src / Model / BookForm.php

รวมรหัสต่อไปนี้ในไฟล์ __constructmethod ของคลาส BookForm

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

อัพเดท Book.php

ทำการเปลี่ยนแปลงต่อไปนี้ในคลาสหนังสือ - myapp / module / Tutorial / src / Model / Book.php

  • เพิ่มคุณสมบัติใหม่ imagepath สำหรับรูปภาพ

public $imagepath;
  • อัปเดตไฟล์ getInputFilter วิธีการดังแสดงด้านล่าง -

    • เพิ่มไฟล์ FileInput กรององค์ประกอบอินพุตไฟล์

    • ตั้งค่า UploadFile การตรวจสอบความถูกต้องเพื่อตรวจสอบองค์ประกอบอินพุตไฟล์

    • กำหนดค่า RenameUpload เพื่อย้ายไฟล์ที่อัปโหลดไปยังปลายทางที่เหมาะสม

รายการรหัสบางส่วนมีดังนี้ -

$file = new FileInput('imagepath'); $file->getValidatorChain()->attach(new UploadFile()); 
$file->getFilterChain()->attach( new RenameUpload([ 'target' => './public/tmpuploads/file', 'randomize' => true, 'use_upload_extension' => true ])); $inputFilter->add($file);
  • อัปเดตไฟล์ exchangeArray วิธีการรวมไฟล์ imagepathทรัพย์สิน. อิมเมจพา ธ อาจมาจากฟอร์มหรือฐานข้อมูล หากอิมเมจพา ธ มาจากฟอร์มรูปแบบจะเป็นอาร์เรย์ที่มีข้อกำหนดดังต่อไปนี้ -

array(1) { 
   ["imagepath"] => array(5) { 
      ["name"]     => string "myimage.png" 
      ["type"]     => string "image/png"           
      ["tmp_name"] => string 
         "public/tmpuploads/file_<random_string>.<image_ext>" 
      ["error"]    => int <error_number> 
      ["size"]     => int <size> 
   } 
}
  • ถ้าอิมเมจพา ธ มาจากฐานข้อมูลก็จะเป็นสตริงธรรมดา รายการรหัสบางส่วนเพื่อแยกวิเคราะห์ imagepath มีดังนี้ -

if(!empty($data['imagepath'])) { 
   if(is_array($data['imagepath'])) { $this->imagepath = str_replace("./public", "", $data['imagepath']['tmp_name']); } else { $this->imagepath = $data['imagepath']; } } else { $data['imagepath'] = null; 
}

รายชื่อทั้งหมดของไฟล์ Book โมเดลมีดังนี้ -

<?php  
namespace Tutorial\Model;  
use Zend\InputFilter\InputFilterInterface; 
use Zend\InputFilter\InputFilterAwareInterface;  
use Zend\Filter\File\RenameUpload; 
use Zend\Validator\File\UploadFile; 
use Zend\InputFilter\FileInput; 
use Zend\InputFilter\InputFilter;  

class Book implements InputFilterAwareInterface { 
   public $id; public $author; 
   public $title; public $imagepath;  
   protected $inputFilter; public function setInputFilter(InputFilterInterface $inputFilter) { 
      throw new \Exception("Not used");
   }  
   public function getInputFilter() { 
      if (!$this->inputFilter) { $inputFilter = new InputFilter(); 
         $inputFilter->add(array( 'name' => 'id', 'required' => true, 'filters' => array( array('name' => 'Int'), ), )); $inputFilter->add(array( 
            'name' => 'author', 
            'required' => true, 
            'filters' => array( 
               array('name' => 'StripTags'), 
               array('name' => 'StringTrim'), 
            ), 
            'validators' => array( 
               array( 
                  'name' => 'StringLength', 
                  'options' => array( 
                     'encoding' => 'UTF-8', 
                     'min' => 1, 
                     'max' => 100, 
                  ), 
               ), 
            ), 
         )); 
         $inputFilter->add(array( 'name' => 'title', 'required' => true, 'filters' => array( array('name' => 'StripTags'), array('name' => 'StringTrim'), ), 'validators' => array( array( 'name' => 'StringLength', 'options' => array( 'encoding' => 'UTF-8', 'min' => 1, 'max' => 100, ), ), ), )); $file = new FileInput('imagepath'); 
         $file->getValidatorChain()->attach(new UploadFile()); $file->getFilterChain()->attach( 
            new RenameUpload([ 
               'target'    => './public/tmpuploads/file', 
               'randomize' => true, 
               'use_upload_extension' => true 
            ])); 
            $inputFilter->add($file);  
            $this->inputFilter = $inputFilter; 
      } 
      return $this->inputFilter; } public function exchangeArray($data) { 
      $this->id = (!empty($data['id'])) ? $data['id'] : null; $this->author = (!empty($data['author'])) ? $data['author'] : null; 
      $this->title = (!empty($data['title'])) ? $data['title'] : null; if(!empty($data['imagepath'])) { 
         if(is_array($data['imagepath'])) { $this->imagepath = str_replace("./public", "", 
               $data['imagepath']['tmp_name']); } else { $this->imagepath = $data['imagepath']; } } else { $data['imagepath'] = null; 
      } 
   } 
}

อัพเดท BookTable.php

เราอัปเดตแล้ว BookForm และ Book model. ตอนนี้เราอัปเดตไฟล์BookTable และแก้ไขไฟล์ saveBookวิธี. นี่เพียงพอที่จะรวมรายการอิมเมจพา ธ ในอาร์เรย์ข้อมูล$data.

รายการรหัสบางส่วนมีดังนี้ -

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

รายการรหัสที่สมบูรณ์ของไฟล์ BookTable คลาสมีดังนี้ -

<?php  
namespace Tutorial\Model;  
use Zend\Db\TableGateway\TableGatewayInterface;  

class BookTable {  
   protected $tableGateway; 
   public function __construct(TableGatewayInterface $tableGateway) { $this->tableGateway = $tableGateway; } public function fetchAll() { $resultSet = $this->tableGateway->select(); return $resultSet; 
   }  
   public function getBook($id) { $id  = (int) $id; $rowset = $this->tableGateway->select(array('id' => $id)); 
      $row = $rowset->current(); 
      if (!$row) { throw new \Exception("Could not find row $id"); 
      } 
      return $row; } public function saveBook(Book $book) { 
      $data = array ( 'author' => $book->author,
         'title'  => $book->title, 'imagepath' => $book->imagepath 
      );  
      $id = (int) $book->id; 
      if ($id == 0) { $this->tableGateway->insert($data); } else { if ($this->getBook($id)) { $this->tableGateway->update($data, array('id' => $id)); 
         } else { 
            throw new \Exception('Book id does not exist'); 
         } 
      } 
   } 
}

Update addAction in the TutorialController.php: ข้อมูลการอัปโหลดไฟล์จะอยู่ในไฟล์ $_FILES global array และสามารถเข้าถึงได้โดยใช้ Request's getFiles()วิธี. ดังนั้นรวมทั้งข้อมูลที่โพสต์และข้อมูลการอัปโหลดไฟล์ดังที่แสดงด้านล่าง

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

รายชื่อทั้งหมดของไฟล์ addAction() วิธีการมีดังนี้ -

public function addAction() { 
   $form = new BookForm(); $form->get('submit')->setValue('Add');  
   $request = $this->getRequest(); 
   if ($request->isPost()) { $book = new Book(); 
      $form->setInputFilter($book->getInputFilter()); 
      $post = array_merge_recursive( $request->getPost()->toArray(), 
         $request->getFiles()->toArray() ); $form->setData($post); if ($form->isValid()) { 
         $book->exchangeArray($form->getData());  
         $this->bookTable->saveBook($book);  
         
         // Redirect to list of Tutorial 
         return $this->redirect()->toRoute('tutorial'); } } return array('form' => $form); 
}

อัปเดตมุมมองของ add.phtml

สุดท้ายเปลี่ยน“ add.phtml” และรวมองค์ประกอบอินพุตไฟล์ imagepath ดังที่แสดงด้านล่าง -

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

รายชื่อที่สมบูรณ์มีดังนี้ -

<?php 
$title = 'Add new Book'; $this->headTitle($title); ?> <h1><?php echo $this->escapeHtml($title); ?></h1> <?php if(!empty($form)) {  
   $form->setAttribute('action', $this->url('tutorial', array('action' => 'add'))); 
   $form->prepare(); echo $this->form()->openTag($form); echo $this->formHidden($form->get('id')); echo $this->formRow($form->get('author'))."<br>"; echo $this->formRow($form->get('title'))."<br>"; echo $this->formRow($form->get('imagepath'))."<br>"; echo $this->formSubmit($form->get('submit')); echo $this->form()->closeTag(); 
}

เรียกใช้แอปพลิเคชัน

สุดท้ายเรียกใช้แอปพลิเคชันที่ http://localhost:8080/tutorial/add และเพิ่มระเบียนใหม่

ผลลัพธ์จะเป็นดังที่แสดงในภาพหน้าจอต่อไปนี้ -

Form Page

Index Page

AJAX เป็นเทคโนโลยีที่ทันสมัยในการเขียนโปรแกรมบนเว็บ มีตัวเลือกในการส่งและรับข้อมูลในหน้าเว็บแบบอะซิงโครนัสโดยไม่ต้องรีเฟรชหน้า Zend framework มีตัวเลือกในการทำงานกับไฟล์json แบบจำลองผ่าน zend-view และ zend-jsonส่วนประกอบ. ให้เราเรียนรู้การเขียนโปรแกรม Zend AJAX ในบทนี้

ติดตั้งส่วนประกอบ json

ส่วนประกอบ Zend json สามารถติดตั้งได้โดยใช้ไฟล์ Composer คำสั่งตามที่ระบุด้านล่าง -

composer require zendframework/zend-json

แนวคิด

Zend framework มีสองวิธีในการเขียนเว็บแอปพลิเคชันที่เปิดใช้งาน AJAX ได้อย่างง่ายดาย มีดังนี้ -

  • isXmlHttpRequest() วิธีการใน Requestobject - หากมีการร้องขอ AJAX เมธอด isXmlHttpRequest () ของอ็อบเจ็กต์ที่ร้องขอจะคืนค่า true หรือเป็นเท็จ วิธีนี้ใช้เพื่อจัดการคำขอ AJAX อย่างถูกต้องในฝั่งเซิร์ฟเวอร์

if ($request->isXmlHttpRequest()) { 
   // Ajax request 
} else { 
   // Normal request 
}
  • Zend / View / Model / JsonModel - The JsonModel เป็นอีกทางเลือกหนึ่งสำหรับ ViewModelเพื่อใช้เฉพาะสำหรับ AJAX และสถานการณ์ REST API JsonModel พร้อมด้วยJsonStrategy (กำหนดค่าในบล็อกตัวจัดการมุมมองของโมดูล) เข้ารหัสข้อมูลโมเดลลงใน Json และส่งกลับเป็นการตอบกลับแทนมุมมอง (phtml)

AJAX - ตัวอย่างการทำงาน

ให้เราเพิ่มเพจ ajax ใหม่ ajaxในโมดูลการสอนและดึงข้อมูลหนังสือแบบอะซิงโครนัส ในการดำเนินการนี้เราควรปฏิบัติตามขั้นตอนต่อไปนี้

ขั้นตอนที่ 1: เพิ่ม JsonStrategy ในการกำหนดค่าโมดูล

อัปเดตบล็อกตัวจัดการมุมมองในไฟล์คอนฟิกูเรชันโมดูลบทช่วยสอน - myapp / module / Tutorial / config / module.config.php จากนั้นJsonStrategy จะทำงานร่วมกับ JsonModel เพื่อเข้ารหัสและส่งข้อมูล json

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

ขั้นตอนที่ 2: เพิ่มเมธอด ajaxAction ใน TutorialController.php

เพิ่มเมธอด ajaxAction ใน TutorialController.php ด้วยรหัสต่อไปนี้ -

public function ajaxAction() { 
   $data = $this->bookTable->fetchAll(); $request = $this->getRequest(); $query = $request->getQuery(); if ($request->isXmlHttpRequest() || $query->get('showJson') == 1) { $jsonData = array(); 
      $idx = 0; foreach($data as $sampledata) { $temp = array( 
            'author' => $sampledata->author, 'title' => $sampledata->title, 
            'imagepath' => $sampledata->imagepath ); $jsonData[$idx++] = $temp; 
      } 
      $view = new JsonModel($jsonData); 
      $view->setTerminal(true); } else { $view = new ViewModel(); 
   }  
   return $view; 
}

ที่นี่ ajaxAction จะตรวจสอบว่าคำขอที่เข้ามาคือ AJAX หรือไม่ หากคำขอที่เข้ามาคือ AJAX ดังนั้นไฟล์JsonModelจะถูกสร้างขึ้น มิฉะนั้นปกติViewModel จะถูกสร้างขึ้น

ในทั้งสองกรณีข้อมูลหนังสือจะถูกดึงมาจากฐานข้อมูลและเติมข้อมูลในโมเดล หากโมเดลนั้นเป็น JsonModel ดังนั้นJsonStrategy จะถูกเรียกใช้และจะเข้ารหัสข้อมูลเป็น json และส่งกลับเป็นการตอบสนอง

$query->get('showJson') == 1ใช้เพื่อวัตถุประสงค์ในการดีบัก เพียงแค่เพิ่มshowJson=1 ใน url และหน้าจะแสดงข้อมูล json

ขั้นตอนที่ 3: เพิ่ม ajax.phtml

ตอนนี้เพิ่มสคริปต์มุมมอง ajax.phtmlสำหรับวิธี ajaxAction หน้านี้จะมีลิงค์พร้อมป้าย -Load book information.

การคลิกลิงก์นั้นจะเป็นการร้องขอ AJAX ซึ่งจะดึงข้อมูลหนังสือเป็นข้อมูล Json และแสดงข้อมูลหนังสือเป็นตารางที่จัดรูปแบบ การประมวลผล AJAX ทำได้โดยใช้ไฟล์JQuery.

รายการรหัสที่สมบูรณ์มีดังนี้ -

<a id = "loadbook" href = "#">Load book information</a> 
</br> </br> 

<table class = "table"> 
   <tbody id = "book"> 
   </tbody> 
</table>  

<script language = "javascript"> 
$(document).ready(function(){ $("#loadbook").on("click", function(event){ 
      $.ajax({ url: '/tutorial/ajax', type: 'POST', dataType: 'json', async: true, success: function(data, status) { var e = $('<tr><th>Author</th><th>Title</th><th>Picture</th></tr>'); 
            $('#book').html(''); $('#book').append(e); 
            
            for(i = 0; i < data.length; i++) { 
               book = data[i]; 
               var e = $('<tr><td id = "author"></td><td id = "title"></td> <td id="imagepath"><img src = ""/></td></tr>'); $('#author', e).html(book['author']); 
               $('#title', e).html(book['title']); $('#imagepath img', e).attr('src', book['imagepath']); 
               $('#book').append(e); 
            } 
         }, 
         error : function(xhr, textStatus, errorThrown) { 
            alert('Ajax request failed.'); 
         } 
      }); 
   }); 
}); 
</script>

ขั้นตอนที่ 4: เรียกใช้แอปพลิเคชัน

สุดท้ายเรียกใช้แอปพลิเคชัน - http://localhost:8080/tutorial/ajax แล้วคลิกลิงก์โหลดข้อมูลหนังสือ

ผลลัพธ์จะเป็นดังภาพด้านล่าง -

Ajax Page -

Ajax Page with Book Information

Ajax page with debugging information

คุกกี้เป็นแนวคิดที่สำคัญมากในเว็บแอปพลิเคชัน มีตัวเลือกในการเก็บรักษาข้อมูลของผู้ใช้โดยปกติจะเป็นข้อมูลชิ้นเล็ก ๆ ในเบราว์เซอร์ในช่วงเวลาที่ จำกัด

คุกกี้ใช้เพื่อรักษาสถานะของเว็บแอปพลิเคชัน Zend framework มีโมดูลคุกกี้ภายในไฟล์zend-httpส่วนประกอบ. zend-http นี้ให้นามธรรม HTTP และการนำไปใช้งาน

การติดตั้งคอมโพเนนต์ HTTP

ส่วนประกอบ HTTP สามารถติดตั้งได้อย่างง่ายดายโดยใช้ไฟล์ Composer ตามที่ระบุไว้ในรหัสด้านล่าง

composer require zendframework/zend-http

แนวคิด

zend-http จัดเตรียมไฟล์ Zend\Http\Cookiesคลาสในการจัดการคุกกี้ ใช้ร่วมกับZend\Http\Clientคลาสซึ่งใช้ในการส่งคำขอไปยังเว็บเซิร์ฟเวอร์ คุกกี้สามารถเริ่มต้นได้ตามที่แสดงในโค้ดด้านล่าง -

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

เมื่อไคลเอนต์ HTTP (Zend \ Http \ Client) ส่งคำขอ URI ไปยังเว็บเซิร์ฟเวอร์เป็นครั้งแรกจะไม่มีคุกกี้ใด ๆ เมื่อเว็บเซิร์ฟเวอร์ได้รับคำขอแล้วจะรวมคุกกี้ไว้ในวัตถุตอบสนองเป็นไฟล์HTTP Header, Set-Cookieและส่งไปยังไคลเอนต์ HTTP ไคลเอ็นต์ HTTP จะดึงคุกกี้ออกจากการตอบสนอง http และส่งต่อเป็น HTTP Header เดียวกันในการร้องขอในภายหลัง โดยทั่วไปคุกกี้แต่ละรายการจะถูกจับคู่กับโดเมนและเส้นทางของโดเมน

วิธีการที่มีอยู่ใน Cookies ชั้นเรียนมีดังนี้ -

  • addCookie(uri) - ใช้เพื่อเพิ่มคุกกี้ลงในออบเจ็กต์คำขอของ URI ที่กำหนด

  • getCookie(cookieName, $cookieForm) - ใช้เพื่อรับคุกกี้ $ cookieName ที่มีอยู่ใน URI ที่กำหนด $uri. อาร์กิวเมนต์ที่สามคือวิธีที่จะส่งคืนคุกกี้ไม่ว่าจะเป็นสตริงหรืออาร์เรย์

  • fromResponse(uri) - ใช้เพื่อแยกคุกกี้ออกจากวัตถุตอบสนองของ URI ที่กำหนด

  • addCookiesFromResponse - เหมือนกับ fromResponse แต่จะแยกและเพิ่มอีกครั้งในออบเจ็กต์คำขอของ URI ที่กำหนด

  • isEmpty() - ใช้เพื่อค้นหาว่า Cookie วัตถุมีคุกกี้หรือไม่

  • reset() - ใช้เพื่อล้างคุกกี้ทั้งหมดใน URI ที่กำหนด

ในบทถัดไปเราจะพูดถึงการจัดการเซสชันใน Zend Framework

เซสชันเป็นแนวคิดที่สำคัญมากในเว็บแอปพลิเคชัน มีตัวเลือกในการเก็บรักษาข้อมูลของผู้ใช้ในเว็บเซิร์ฟเวอร์เป็นระยะเวลา จำกัด Zend framework มีองค์ประกอบแยกต่างหากzend-session เพื่อจัดการข้อมูลเซสชัน

ติดตั้งส่วนประกอบเซสชัน

คอมโพเนนต์เซสชันสามารถติดตั้งได้โดยใช้ Composer ตามที่ระบุด้านล่าง -

composer require zendframework/zend-session

ส่วนประกอบของเซสชัน

Zend framework มีส่วนประกอบหกส่วนเพื่อจัดการกับการจัดการเซสชัน ส่วนประกอบทั้งหมดนี้ได้อธิบายไว้ด้านล่าง -

  • Zend\Session\Container - API หลักในการอ่านและเขียนข้อมูลเซสชัน

  • Zend\Session\SessionManager - ใช้เพื่อจัดการวงจรชีวิตทั้งหมดของเซสชัน

  • Zend\Session\Storage - ใช้เพื่อระบุวิธีจัดเก็บข้อมูลเซสชันในหน่วยความจำ

  • Zend\Session\SaveHandler - ใช้เพื่อจัดเก็บและดึงข้อมูลเซสชันไปยังตำแหน่งทางกายภาพเช่น RDBMS, Redis, MangoDB เป็นต้น

  • Zend\Session\Validator - ใช้เพื่อป้องกันเซสชันจากการไฮแจ็คโดยการตรวจสอบที่อยู่ระยะไกลเริ่มต้นและที่อยู่ระยะไกลของคำขอในภายหลังและตัวแทนผู้ใช้

  • Zend\Session\Config\SessionConfig - ใช้เพื่อกำหนดค่าว่าเซสชันควรทำงานอย่างไร

การกำหนดค่าเริ่มต้นเพียงพอที่จะทำงานกับเซสชัน การใช้ส่วนประกอบข้างต้นสามารถจัดการทุกแง่มุมของเซสชันได้อย่างง่ายดาย

ตัวอย่างส่วนประกอบของเซสชัน

ให้เราปฏิบัติตามประเด็นต่อไปนี้เพื่อสร้างเพจใหม่เพื่อทำความเข้าใจเซสชันใน Zend framework ตามค่าเริ่มต้นก็เพียงพอที่จะสร้างอินสแตนซ์ของไฟล์Container ชั้นเรียนเพื่อจัดการเซสชัน

  • สร้างการกระทำใหม่ sessionAction ใน TutorialController.

  • เริ่มต้นไฟล์ Container วัตถุ.

$c = new Container();
  • ตรวจสอบว่าเป็นคีย์โดยพลการ countมีอยู่ หากไม่มีคีย์ให้เริ่มต้นไฟล์count ด้วยค่า 1 หากมีให้เพิ่มค่าตามที่แสดงในรหัสต่อไปนี้

if (!isset($c->count)) { $c->count = 0; 
} else { 
   $c->count++; 
}
  • ลงทะเบียนจำนวนใน ViewModel

  • สร้างไฟล์เทมเพลตสำหรับ - sessionAction, session.phtml ใน myapp / module / Tutorial / view / tutorial / tutorial / session.phtml จากนั้นแสดงผล count มูลค่า.

  • Refreshing the page will increase the value of count in the session. The complete listing is as follows −

TutorialController.php

public function sessionAction() { 
   $c = new Container();  
   if (!isset($c->count)) { $c->count = 0; 
   } else { 
      $c->count++; } $view = new ViewModel([ 
      'count' => $c->count, ]); return $view; 
}

session.pthml

Session data, COUNT = <?= $this->count ?>

Sample Result

Session data, Count = 5

Authentication is one of the most significant and must-have feature in any web application. Zend Framework provides a separate component to handle authentication, which is called as the zend-authentication.

Install an Authentication Component

The authentication component can be installed using the following Composer command.

composer require zendframework/zend-authentication

Concept

Usually, a developer writes a php function to authenticate the user details against a datasource. Once the authentication is done, the authentication details are persisted for subsequent requests. Zend Framework generalizes this concept and provides two classes, which are explained below −

Class 1 Zend\Authentication\Adaptor\AdaptorInterface

This class provides a single method, authenticate to write the authentication logic. The authenticate method returns an instance of Zend\Authentication\Result class.

This Result object holds the authentication status; identity if the authentication succeeds and an error message, if the authentication fails. The signature of the authenticate interface and result class is as follows −

AdaptorInterface

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

Result class

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

The Zend Framework provides a default implementation to authenticate against the database, ldap, http basic and digest credentials. An Adaptor authenticates but does not persist the details for any future requests.

Class 2 Zend\Authentication\AuthenticationService

The AuthenticationService is the main component, which uses the already configured adaptor for authentication purposes. Once the authentication is done, it persists the authentication details and provides methods, hasIdentity() to check whether an identity is available, getIdentity() to get the authentication details and clearIdentity() to clear the authentication details.

The partial code listing to use this AuthenticationService is as follows −

$adap = new Adapter($username, $password); $auth = new AuthenticationService(); 
$result = $auth->authenticate($adap); if($result->isValid) { 
   $identity = $auth->getIdentity(); 
} else { 
   // process $result->getMessages() } // clear $auth->clearIdentity();

The stuff related to authorization are packaged as two separate modules, which are – zend-permissions-acl and zend-permissions-rbac. The zend-permissions-acl is based on the Access control list and the zend-permissions-rbac is based on the role based access control list. They provide high-level abstraction of ACL & RBAC concept and aids in writing the enterprise grade application.

The Zend Framework provides a separate component called as zend-mail to send email messages. The zend-mail component also provides an option to read and write email messages with attachments both in text and html format. Sending an email in Zend is much easier and simple to configure.

Let us go through the email concepts, basic settings, advanced settings such as SMTP transport, etc., in this chapter.

Install Mail Component

The mail component can be installed using the following Composer command.

composer require zendframework/zend-mail

Basic Email Configuration

A basic email consists of one or more recipients, a subject, a body and a sender. Zend provides Zend\Mail\Message class to create a new email message. To send an email using the zend-mail, you must specify at least one recipient as well as a message body.

The partial code to create a new mail message is as follows −

use Zend\Mail;
$mail = new Mail\Message(); $mail->setSubject('Zend email sample'); 
$mail->setBody('This is content of the mail message'); $mail->setFrom('[email protected]', "sender-name"); 
$mail->addTo('[email protected]', "recipient-name");

Zend provides Zend\Mail\Sendmail class to send the mail message. Sendmail uses the php native mail function, mail to send the mail message and we can configure the transport layer using php configuration file.

The partial coding using Sendmail is as follow −

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

The zend-mail provides many transport layer and each may require many additional parameters such as username, password, etc

Email Management Methods

Some of the notable email management methods are as follows −

  • isValid − Messages without a ‘From’ address is invalid.

isValid() : bool
  • setEncoding − Set the message encoding.

setEncoding(string $encoding) : void
  • getEncoding − Get the message encoding.

getEncoding() : string
  • setHeaders − Compose headers.

setHeaders(Zend\Mail\Headers $headers) : void
  • getHeaders − Access headers collection.

getHeaders() : Zend\Mail\Headers
  • setFrom − Set (overwrite) From addresses. It contains a key/value pairs where the key is the human readable name and the value is the email address.

setFrom( 
   string|AddressInterface|array|AddressList|Traversable $emailOrAddressList, string|null $name 
) : void
  • addFrom − Add a ‘From’ address.

addFrom( 
   string|AddressInterface|array|AddressList|Traversable $emailOrAddressOrList, string|null $name 
) : void
  • getFrom − Retrieve list of ‘From’ senders.

getFrom() : AddressList 
setTo - Overwrite the address list in the To recipients. 
setTo( 
   string|AddressInterface|array|AddressList|Traversable $emailOrAddressList, null|string $name 
) : void
  • setSubject − Set the message subject header value.

setSubject(string $subject) :void
  • setBody − Set the message body.

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

ชั้นการขนส่ง SMTP

zend-mail มีตัวเลือกในการส่งอีเมลโดยใช้เซิร์ฟเวอร์ SMTP ผ่านไฟล์ Zend\Mail\Transport\Smtpclass. มันเป็นเหมือนSendmail ยกเว้นว่าจะมีตัวเลือกเพิ่มเติมบางประการในการกำหนดค่าโฮสต์ SMTP พอร์ตชื่อผู้ใช้รหัสผ่าน ฯลฯ

รหัสบางส่วนมีดังนี้ -

use Zend\Mail\Transport\Smtp as SmtpTransport; 
use Zend\Mail\Transport\SmtpOptions;  
$transport = new SmtpTransport(); $options = new SmtpOptions([ 
   'name' => 'localhost', 
   'host' =>'smtp.gmail.com', 
   'port' => 465, 
]); 
$transport->setOptions($options);

ที่นี่

  • name - ชื่อโฮสต์ SMTP

  • host - ชื่อโฮสต์ระยะไกลหรือที่อยู่ IP

  • port - พอร์ตที่โฮสต์ระยะไกลกำลังรับฟัง

แนวคิดจดหมาย - ตัวอย่าง

ให้เราทำตามประเด็นต่อไปนี้เพื่อเขียนแอปพลิเคชัน php console อย่างง่ายเพื่อทำความเข้าใจแนวคิดเมล

  • สร้างโฟลเดอร์“ mailapp”

  • ติดตั้ง zend-mail โดยใช้เครื่องมือแต่งเพลง

  • สร้างไฟล์ php Mail.php ภายในโฟลเดอร์“ mailapp”

  • สร้างข้อความโดยใช้ไฟล์ Zend\Mail\Message.

$message = new Message(); $message->addTo('[email protected]'); 
$message->addFrom('[email protected]'); $message->setSubject('Hello!'); 
$message->setBody("My first Zend-mail application!");
  • สร้างเลเยอร์การขนส่ง SMTP และเพิ่มการกำหนดค่าที่จำเป็น

// Setup SMTP transport using LOGIN authentication 
$transport = new SmtpTransport(); 
$options = new SmtpOptions([ 'name' => 'localhost', 'host' => 'smtp.gmail.com', // or any SMTP server 'port' => 465, // port on which the SMTP server is listening 'connection_class' => 'login', 'connection_config' => [ username' => '<your username>', 'password' => '<your password>', 'ssl' => 'ssl'], ]); $transport->setOptions($options);
  • ส่งอีเมลโดยใช้ send วิธี.

$transport->send($message);

รายชื่อที่สมบูรณ์Mail.phpมีดังนี้ -

<?php  
require __DIR__ . '/vendor/autoload.php';  

use Zend\Mail\Message; 
use Zend\Mail\Transport\Smtp as SmtpTransport; 
use Zend\Mail\Transport\SmtpOptions;  
  
$message = new Message(); 
$message->addTo('[email protected]'); $message->addFrom('[email protected]'); 
$message->setSubject('Hello!'); $message->setBody("My first Zend-mail application!");  
  
// Setup SMTP transport using LOGIN authentication 
$transport = new SmtpTransport(); $options = new SmtpOptions([ 
   'name' => 'localhost', 
   'host' => 'smtp.gmail.com', // or any SMTP server 
   'port' => 465, // port on which the SMTP server is listening 
   'connection_class' => 'login', 
   'connection_config' => [ 
      'username' => '<your username>', 'password' => '<your password>', 
      'ssl' => 'ssl'], 
]); 
$transport->setOptions($options); 
$transport->send($message);

ตอนนี้เรียกใช้แอปพลิเคชันในพรอมต์คำสั่ง php Mail.php. สิ่งนี้จะส่งอีเมลตามที่กำหนดไว้ในแอปพลิเคชัน

โดยทั่วไปเราสามารถดีบักแอปพลิเคชัน PHP โดยใช้ไฟล์ advanced debugger tool หรือโดยใช้คำสั่งง่ายๆเช่น echo และ die. ในสถานการณ์บนเว็บเราจำเป็นต้องทดสอบลอจิกทางธุรกิจรวมทั้งเลเยอร์การนำเสนอ แบบฟอร์มในเว็บแอปพลิเคชันสามารถทดสอบได้โดยป้อนข้อมูลการทดสอบที่เกี่ยวข้องเพื่อให้แน่ใจว่าแบบฟอร์มทำงานตามที่คาดไว้

การออกแบบเว็บไซต์สามารถทดสอบได้ด้วยตนเองโดยใช้เบราว์เซอร์ กระบวนการทดสอบประเภทนี้สามารถทำได้โดยอัตโนมัติโดยใช้การทดสอบหน่วย การทดสอบหน่วยเป็นสิ่งสำคัญในโครงการขนาดใหญ่ การทดสอบหน่วยเหล่านี้จะช่วยทำให้กระบวนการทดสอบเป็นไปโดยอัตโนมัติและแจ้งเตือนนักพัฒนาเมื่อมีสิ่งผิดปกติเกิดขึ้น

การตั้งค่า PHPUnit

Zend framework ผสานรวมกับกรอบการทดสอบหน่วย PHPUnit ในการเขียน unit test สำหรับ Zend framework เราต้องตั้งค่า PHPUnit ซึ่งสามารถทำได้อย่างง่ายดายโดยใช้คำสั่ง Composer ต่อไปนี้

$ composer require --dev phpunit/phpunit

หลังจากดำเนินการคำสั่งข้างต้นคุณจะได้รับคำตอบดังที่แสดงในบล็อกโค้ดต่อไปนี้

Using version ^5.7 for phpunit/phpunit 
./composer.json has been updated 
Loading composer repositories with package information 
Updating dependencies (including require-dev) 
Nothing to install or update 
Writing lock file 
Generating autoload files

ตอนนี้เมื่อคุณเปิดไฟล์“ composer.json” คุณจะเห็นการเปลี่ยนแปลงต่อไปนี้ -

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

TestCase และ Assertions

เฟรมเวิร์ก Zend จัดเตรียมคลาสผู้ช่วยเหลือเพื่อทดสอบหน่วยควบคุม TestCase เป็นองค์ประกอบหลักในไฟล์ PHPUnit กรอบการเขียนกรณีทดสอบและ Zend Framework จัดเตรียมการใช้งาน TestCase แบบนามธรรมที่เรียกว่า AbstractHttpControllerTestCase.

AbstractHttpControllerTestCase นี้มีหลากหลาย Assertวิธีการและสามารถจัดกลุ่มตามฟังก์ชันการทำงาน มีดังนี้ -

  • Request Assertions- ใช้เพื่อยืนยันคำขอ http ตัวอย่างเช่น assertControllerName

  • CSS Select Assertions - ใช้เพื่อตรวจสอบการตอบกลับ HTML โดยใช้แบบจำลอง HTML DOM

  • XPath Assertions - อีกทางเลือกหนึ่งของการยืนยันการเลือก CSS ตาม XPath

  • Redirect Assertions - ใช้เพื่อตรวจสอบการเปลี่ยนเส้นทางหน้า

  • Response Header Assertions - ใช้เพื่อตรวจสอบส่วนหัวการตอบสนองเช่นรหัสสถานะ (assertResponseStatusCode)

สร้างไดเรกทอรีการทดสอบ

การทดสอบหน่วยสามารถเขียนแยกกันสำหรับแต่ละโมดูล ต้องสร้างการเข้ารหัสที่เกี่ยวข้องกับการทดสอบทั้งหมดภายในไฟล์test โฟลเดอร์ภายใต้ไดเร็กทอรีรากของโมดูล

ตัวอย่างเช่นในการเขียนการทดสอบสำหรับ TutorialController ที่มีอยู่ภายใต้โมดูลการสอนจำเป็นต้องวางคลาสทดสอบไว้ในไดเร็กทอรี myapp / module / Tutorial / test / Controller /

ตัวอย่าง

ให้เราเขียนคลาสทดสอบเพื่อทดสอบหน่วย TutorialController.

เริ่มต้นด้วยการเขียนคลาสที่เรียกว่า TutorialControllerTest และขยายไปยัง AbstractHttpControllerTestCase

ขั้นตอนต่อไปคือการเขียนไฟล์ Setupวิธีการตั้งค่าสภาพแวดล้อมการทดสอบ ซึ่งสามารถทำได้โดยเรียกไฟล์setApplicationConfig วิธีการและส่งไฟล์ config แอปพลิเคชันหลักของเรา myapp / config / application.config.php

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

เขียนวิธีการอย่างน้อยหนึ่งวิธีและเรียกวิธีการยืนยันต่างๆขึ้นอยู่กับความต้องการ

$this->assertMatchedRouteName('tutorial');

เราได้เขียนคลาสทดสอบและรายชื่อทั้งหมดมีดังนี้ -

<?php  
namespace TutorialTest\Controller;  
use Tutorial\Controller\TutorialController; 
use Zend\Stdlib\ArrayUtils; 
use Zend\Test\PHPUnit\Controller\AbstractHttpControllerTestCase;  

class TutorialControllerTest extends AbstractHttpControllerTestCase { 
   public function setUp() { 
      $configOverrides = [];  
      $this->setApplicationConfig(ArrayUtils::merge( include __DIR__ . '/../../../../config/application.config.php', $configOverrides 
      ));  
      parent::setUp(); 
   }  
   public function testIndexActionCanBeAccessed() { 
      $this->dispatch('/tutorial', 'GET'); $this->assertResponseStatusCode(200); 
      $this->assertModuleName('tutorial'); $this->assertControllerName(TutorialController::class); 
      $this->assertControllerClass('TutorialController'); $this->assertMatchedRouteName('tutorial'); 
   } 
}

ตอนนี้เปิดพรอมต์คำสั่งไปที่ไดเรกทอรีรากของแอปพลิเคชันและเรียกใช้ไฟล์ phpunit ปฏิบัติการที่มีอยู่ภายในไฟล์ vendor โฟลเดอร์

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

ผลลัพธ์จะเป็นดังที่แสดงในบล็อกโค้ดต่อไปนี้ -

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

ความล้มเหลวของระบบจะต้องได้รับการจัดการอย่างมีประสิทธิภาพเพื่อให้ระบบทำงานได้อย่างราบรื่น Zend Framework มาพร้อมกับไฟล์default error trappingที่พิมพ์และบันทึกข้อผิดพลาดเมื่อเกิดขึ้น ตัวจัดการข้อผิดพลาดเดียวกันนี้ถูกใช้เพื่อตรวจจับExceptions.

ตัวจัดการข้อผิดพลาดแสดงข้อผิดพลาดเมื่อการดีบักเป็นจริงและบันทึกข้อผิดพลาดเมื่อการดีบักเป็นเท็จ Zend Framework มีคลาสข้อยกเว้นหลายคลาสและการจัดการข้อยกเว้นในตัวจะดักจับข้อยกเว้นที่ไม่ถูกตรวจจับและแสดงผลเพจที่มีประโยชน์

การจัดการข้อผิดพลาดเริ่มต้น

เราสามารถกำหนดการตั้งค่าข้อผิดพลาดเริ่มต้นในไฟล์คอนฟิกูเรชันแอปพลิเคชัน myapp / module / Application / config / module.config.php

ตัวอย่างโค้ดบางส่วนมีดังนี้ -

'view_manager' => [ 
   'display_not_found_reason' => true, 
   'display_exceptions'       => true, 
   'doctype'                  => 'HTML5', 
   'not_found_template'       => 'error/404', 
   'exception_template'       => 'error/index', 
   'template_map' => [ 
      'layout/layout'           => __DIR__ . '/../view/layout/layout.phtml', 
      'application/index/index' => __DIR__ . '/../view/application/index/index.phtml', 
      'error/404'               => __DIR__ . '/../view/error/404.phtml', 
      'error/index'             => __DIR__ . '/../view/error/index.phtml', 
   ], 
   'template_path_stack' => [ 
      __DIR__ . '/../view', 
   ], 
],

ที่นี่ display_exception, not_found_template, exception_template, error / 404 และ error / index เป็นรายการคอนฟิกูเรชันที่เกี่ยวข้องกับข้อผิดพลาดและอธิบายได้ด้วยตนเอง

รายการที่สำคัญที่สุดในกลุ่มนี้คือ error/index. นี่คือเทมเพลตที่แสดงเมื่อมีข้อยกเว้นเกิดขึ้นในระบบ เราสามารถแก้ไขเทมเพลตนี้ myapp / module / Application / view / error / index.phtml เพื่อควบคุมจำนวนข้อผิดพลาดที่จะแสดง

ในบทนี้เราจะเรียนรู้วิธีการสร้างแอปพลิเคชันพนักงานตาม MVC ที่สมบูรณ์ใน Zend Framework ทำตามขั้นตอนที่ระบุด้านล่าง

ขั้นตอนที่ 1: Module.php

ขั้นแรกเราควรสร้างโมดูลพนักงานภายในไดเร็กทอรี - myapp / module / Employee / src / จากนั้นใช้อินเทอร์เฟซ ConfigProviderInterface

รหัสที่สมบูรณ์สำหรับคลาสโมดูลมีดังนี้ -

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

ขั้นตอนที่ 2: composer.json

กำหนดค่า Tutorial โมดูลใน composer.json ภายใต้ส่วนโหลดอัตโนมัติโดยใช้รหัสต่อไปนี้

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

ตอนนี้อัปเดตแอปพลิเคชันโดยใช้คำสั่งอัปเดตผู้แต่ง

composer update

คำสั่ง Composer จะทำการเปลี่ยนแปลงที่จำเป็นกับแอปพลิเคชันและแสดงบันทึกดังที่แสดงในพรอมต์คำสั่งด้านล่าง

Loading composer repositories with package information 
Updating dependencies (including require-dev) 
   - Removing zendframework/zend-component-installer (0.3.0) 
   - Installing zendframework/zend-component-installer (0.3.1) 
   Downloading: 100%           
    
   - Removing zendframework/zend-stdlib (3.0.1) 
   - Installing zendframework/zend-stdlib (3.1.0) 
   Loading from cache  
    
   - Removing zendframework/zend-eventmanager (3.0.1) 
   - Installing zendframework/zend-eventmanager (3.1.0) 
   Downloading: 100%           
    
   - Removing zendframework/zend-view (2.8.0) 
   - Installing zendframework/zend-view (2.8.1) 
   Loading from cache  
    
   - Removing zendframework/zend-servicemanager (3.1.0) 
   - Installing zendframework/zend-servicemanager (3.2.0) 
   Downloading: 100%           
    
   - Removing zendframework/zend-escaper (2.5.1) 
   - Installing zendframework/zend-escaper (2.5.2) 
   Loading from cache  
   
   - Removing zendframework/zend-http (2.5.4) 
   - Installing zendframework/zend-http (2.5.5) 
   Loading from cache  
    
   - Removing zendframework/zend-mvc (3.0.1)
   - Installing zendframework/zend-mvc (3.0.4)  
   Downloading: 100%           
   
   - Removing phpunit/phpunit (5.7.4) 
   - Installing phpunit/phpunit (5.7.5) 
   Downloading: 100%           
  
Writing lock file 
Generating autoload files

ขั้นตอนที่ 3: module.config.php สำหรับโมดูลพนักงาน

สร้างไฟล์คอนฟิกูเรชันโมดูล“ module.config.php” ภายใต้ myapp / module / Employee / config ด้วยรหัสต่อไปนี้

<?php  
namespace Employee;  
use Zend\ServiceManager\Factory\InvokableFactory; 
use Zend\Router\Http\Segment;  
return [ 
   'controllers' => [ 
      'factories' => [ 
         Controller\EmployeeController::class => InvokableFactory::class, 
      ], 
   ], 
   'view_manager' => [ 
      'template_path_stack' => ['employee' => __DIR__ . '/../view',], 
   ], 
];

ตอนนี้กำหนดค่าโมดูลพนักงานในไฟล์การกำหนดค่าระดับแอปพลิเคชัน - myapp / config / modules.config.php

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

ขั้นตอนที่ 4: EmployeeController

สร้างคลาส PHP ใหม่ EmployeeController โดยขยาย AbstractActionController และวางไว้ที่ไดเร็กทอรี myapp / module / Employee / src / Controller

รายการรหัสที่สมบูรณ์มีดังนี้ -

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

ขั้นตอนที่ 5: การกำหนดค่าเราเตอร์

ให้เราเพิ่มเส้นทางส่วนในโมดูลพนักงานของเรา อัพเดตไฟล์คอนฟิกูเรชันโมดูลพนักงาน module.config.php ที่ myapp / module / Employee / config

<?php  
namespace Employee;
use Zend\ServiceManager\Factory\InvokableFactory; 
use Zend\Router\Http\Segment;  
return [ 
   'controllers' => [ 
      'factories' => [ 
         Controller\EmployeeController::class => InvokableFactory::class, 
      ], 
   ], 
   'router' => [ 
      'routes' => [ 
         'employee' => [ 
            'type' => Segment::class,
            'options' => [ 
               'route' => '/employee[/:action[/:id]]',
               'constraints' => [
                  'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
                  'id' => '[0-9]+', 
               ], 
               'defaults' => [ 
                  'controller' => Controller\EmployeeController::class,
                  'action' => 'index', 
               ], 
            ], 
         ], 
      ], 
   ], 
   'view_manager' => [ 
      'template_path_stack' => [ 
         'employee' => __DIR__ . '/../view', 
      ], 
   ], 
];

เราได้เพิ่มเส้นทางสำหรับโมดูลพนักงานของเราเรียบร้อยแล้ว ขั้นตอนต่อไปคือการสร้างสคริปต์มุมมองสำหรับแอปพลิเคชัน Employee

ขั้นตอนที่ 6: สร้าง ViewModel

สร้างไฟล์ชื่อ“ index.phtml” ภายใต้ไดเร็กทอรี myapp / module / Employee / view / Employee / Employee

เพิ่มการเปลี่ยนแปลงต่อไปนี้ในไฟล์ -

<div class = "row content"> 
   <h3>This is my first Zend application</h3> 
</div> 
Move to “EmployeeController.php” file and edit the following changes, 

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

ในที่สุดเราก็ทำโมดูลพนักงานสำเร็จแล้ว เราสามารถเข้าถึงได้โดยใช้ url ต่อไปนี้ -http://localhost:8080/employee.

ผลลัพธ์

ในขั้นตอนต่อไปเราจะดำเนินการ add, edit และ deleteการดำเนินการข้อมูลในแอปพลิเคชันของพนักงาน ในการดำเนินการเหล่านี้เราควรสร้างแบบจำลองฐานข้อมูลก่อน มีการอธิบายไว้ในขั้นตอนถัดไป

ขั้นตอนที่ 7: สร้างแบบจำลอง

ให้เราสร้างแบบจำลองพนักงานในโมดูลของเรา src directory. โดยทั่วไปโมเดลจะถูกจัดกลุ่มไว้ในโฟลเดอร์ Model (myapp / module / Employee / src / Model / Employee.php)

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

ขั้นตอนที่ 8: ตาราง MySQL

สร้างฐานข้อมูลชื่อเป็น tutorials ในเซิร์ฟเวอร์ MYSQL ภายในโดยใช้คำสั่งต่อไปนี้ -

create database tutorials;

ให้เราสร้างตารางชื่อเป็น employee ในฐานข้อมูลโดยใช้คำสั่ง SQL ต่อไปนี้ -

use tutorials;  
CREATE TABLE employee ( 
   id int(11) NOT NULL auto_increment, 
   emp_name varchar(100) NOT NULL, 
   emp_job varchar(100) NOT NULL, 
   PRIMARY KEY (id) 
);

แทรกข้อมูลลงในไฟล์ employee ตารางโดยใช้แบบสอบถามต่อไปนี้ -

INSERT INTO employee (emp_name, emp_job) VALUES ('Adam',  'Tutor'); 
INSERT INTO employee (emp_name, emp_job) VALUES ('Bruce',  'Programmer'); 
INSERT INTO employee (emp_name, emp_job) VALUES ('David',  'Designer');

ขั้นตอนที่ 9: อัปเดตการกำหนดค่าฐานข้อมูล

อัพเดตไฟล์ Global Configuration myapp / config / autoload / global.php ด้วยข้อมูลไดรฟ์ฐานข้อมูลที่จำเป็น

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

ตอนนี้อัปเดตข้อมูลรับรองฐานข้อมูลในไฟล์กำหนดค่าภายใน - myapp / config / autoload / local.php ด้วยวิธีนี้เราสามารถแยกข้อมูลรับรองการเชื่อมต่อฐานข้อมูลแบบโลคัลและแบบสดได้

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

ขั้นตอนที่ 10: ใช้ exchangeArray

ใช้ฟังก์ชัน exchangeArray ในรูปแบบพนักงาน

<?php 
namespace Employee\Model; 
class Employee { 
   public $id; 
   public $emp_name; public $emp_job;  
   public function exchangeArray($data) { $this->id = (!empty($data['id'])) ? $data['id'] : null; 
      $this->emp_name = (!empty($data['emp_name'])) ? $data['emp_name'] : null; $this->emp_job = (!empty($data['emp_job'])) ? $data['emp_job'] : null; 
   } 
}

ขั้นตอนที่ 11: ใช้ TableGateway เพื่อดึงข้อมูลพนักงาน

สร้างคลาส EmployeeTable ในโฟลเดอร์ Model เอง ถูกกำหนดไว้ในบล็อกรหัสต่อไปนี้

<?php  
namespace Employee\Model;  
use Zend\Db\TableGateway\TableGatewayInterface;  
class EmployeeTable { 
   protected $tableGateway; public function __construct(TableGatewayInterface $tableGateway) { 
      $this->tableGateway = $tableGateway; 
   }
   public function fetchAll() { 
      $resultSet = $this->tableGateway->select();  
      return $resultSet; 
   } 
}

ขั้นตอนที่ 12: กำหนดค่าคลาส EmployeeTable

การบริการของพนักงานในการปรับปรุงModule.phpใช้GetServiceConfig ()วิธีการ

<?php
namespace Employee;
use Zend\Db\Adapter\AdapterInterface;
use Zend\Db\ResultSet\ResultSet;
use Zend\Db\TableGateway\TableGateway;
use Zend\ModuleManager\Feature\ConfigProviderInterface;

class Module implements ConfigProviderInterface {
   public function getConfig() {
      return include __DIR__ . '/../config/module.config.php';
   }
   public function getServiceConfig() {
      return [
         'factories' => [
            Model\EmployeeTable::class => function (    $container) {
               $tableGateway = $container>get( Model\EmployeeTableGateway::class);
               $table = new Model\EmployeeTable($tableGateway);
               return $table; }, Model\EmployeeTableGateway::class => function ($container) {
               $dbAdapter = $container->get(AdapterInterface::class);
               $resultSetPrototype = new ResultSet(); $resultSetPrototype->setArrayObjectPrototype(new Model\Employee());
               return new TableGateway('employee', $dbAdapter, null, $resultSetPrototype);
            },
         ],
      ];
   }
}

ขั้นตอนที่ 13: เพิ่มบริการพนักงานในตัวควบคุม

อัปเดตส่วนคอนโทรลเลอร์ของการกำหนดค่าโมดูลพนักงานใน - myapp / module / config / module.config.php ดังที่แสดงด้านล่าง

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

ขั้นตอนที่ 14: เพิ่ม Constructor สำหรับ EmployeeController

เพิ่มตัวสร้างด้วย EmployeeTable เป็นอาร์กิวเมนต์และแก้ไขการเปลี่ยนแปลงต่อไปนี้

<?php  
namespace Employee\Controller; 
use Zend\Mvc\Controller\AbstractActionController; 
use Zend\View\Model\ViewModel;
use Employee\Model\Employee; 
use Employee\Model\EmployeeTable;  

class EmployeeController extends AbstractActionController { 
   private $table; public function __construct(EmployeeTable $table) { 
      $this->table = $table; 
   }  
   public function indexAction() { 
      $view = new ViewModel([ 'data' => $this->table->fetchAll(), 
      ]);  
      return $view; 
   } 
}

ขั้นตอนที่ 15: แสดงข้อมูลพนักงานในสคริปต์มุมมอง“ index.phtml”

ย้ายไปที่ไฟล์ - index.phtml และทำการเปลี่ยนแปลงต่อไปนี้ -

<?php 
$title = 'Employee application'; 
$this->headTitle($title); 
?>  

<table class="table"> 
   <tr> 
      <th>Employee Name</th> 
      <th>Employee Job</th> 
      <th>Edit/Delete operations</th>
   </tr> 
   <?php foreach ($data as $empdata) : ?> 
   <tr>  
      <td><?php echo $this->escapeHtml($empdata->emp_name);?></td> 
      <td><?php echo $this->escapeHtml($empdata->emp_job);?></td> 
      <td> 
         <a href="<?php echo $this->url('employee', array('action'=>'edit', 'id' =>$empdata->id));?>">Edit</a> 
         <a href="<?php echo $this->url('employee', array('action'=>'delete', 'id' => $empdata->id));?>">Delete</a> 
      </td> 
   </tr> 
   <?php endforeach; ?> 
</table>

ตอนนี้เราได้สร้างแบบจำลองฐานข้อมูลเรียบร้อยแล้วและสามารถดึงบันทึกภายในแอปพลิเคชันได้

ขอใบสมัครโดยใช้ url - http://localhost:8080/employee.

ผลลัพธ์

ขั้นตอนต่อไปจะอธิบายเกี่ยวกับไฟล์ insert, edit และ delete การดำเนินการข้อมูลในโมดูลพนักงาน

ขั้นตอนที่ 16: สร้างแบบฟอร์มพนักงาน

สร้างไฟล์ชื่อ EmployeeForm.phpในไดเร็กทอรี myapp / module / Employee / src / Form มีอธิบายไว้ในบล็อกโค้ดด้านล่าง

<?php  
namespace Employee\Form; 
use Zend\Form\Form;  

class EmployeeForm extends Form { 
   public function __construct($name = null) { / / we want to ignore the name passed parent::__construct('employee'); $this->add(array( 
         'name' => 'id', 
         'type' => 'Hidden', 
      )); 
      $this->add(array( 'name' => 'emp_name', 'type' => 'Text', 'options' => array( 'label' => 'Name', ), )); $this->add(array( 
         'name' => 'emp_job', 
         'type' => 'Text', 
         'options' => array( 
            'label' => 'Job', 
         ), 
      )); 
      $this->add(array( 
         'name' => 'submit', 
         'type' => 'Submit', 
         'attributes' => array(
            'value' => 'Go', 
            'id' => 'submitbutton', 
         ), 
      )); 
   } 
}

ขั้นตอนที่ 17: อัปเดตโมเดลพนักงาน

อัปเดตโมเดลพนักงานและใช้ InputFilterAwareInterface ย้ายไปที่ไดเร็กทอรี myapp / module / Employee / src / Employee / Model และเพิ่มการเปลี่ยนแปลงต่อไปนี้ในไฟล์Employee.phpfile.

<?php  
namespace Employee\Model;  

// Add these import statements 
use Zend\InputFilter\InputFilter; 
use Zend\InputFilter\InputFilterAwareInterface; 
use Zend\InputFilter\InputFilterInterface;  

class Employee implements InputFilterAwareInterface { 
   public $id; 
   public $emp_name; public $emp_job; 
   protected $inputFilter; public function exchangeArray($data) { 
      $this->id = (isset($data['id'])) ? $data['id'] : null; $this->emp_name = (isset($data['emp_name'])) ? $data['emp_name'] : null;         
      $this->emp_job = (isset($data['emp_job']))  ? $data['emp_job'] : null; } // Add content to these methods: public function setInputFilter(InputFilterInterface $inputFilter) { 
      throw new \Exception("Not used"); 
   }  
   public function getInputFilter() { 
      if (!$this->inputFilter) { $inputFilter = new InputFilter();  
         $inputFilter->add(array( 'name' => 'id', 'required' => true, 'filters' => array( array('name' => 'Int'), ), )); $inputFilter->add(array( 
            'name' => 'emp_name', 
            'required' => true, 
            'filters' => array( 
               array('name' => 'StripTags'), 
               array('name' => 'StringTrim'), 
            ), 
            'validators' => array( 
               array('name' => 'StringLength', 
                        'options' => array( 
                           'encoding' => 'UTF-8', 
                           'min' => 1, 
                           'max' => 50, 
                        ), 
                    ), 
                ), 
            ));
         $inputFilter->add(array( 'name' => 'emp_job', 'required' => true, 'filters' => array( array('name' => 'StripTags'), array('name' => 'StringTrim'), ), 'validators' => array( array('name' => 'StringLength', 'options' => array( 'encoding' => 'UTF-8', 'min' => 1, 'max' => 50, ), ), ), )); $this->inputFilter = $inputFilter; } return $this->inputFilter; 
   } 
}

ขั้นตอนที่ 18: เพิ่ม addAction ในตัวควบคุมพนักงาน

เพิ่มการเปลี่ยนแปลงต่อไปนี้ในไฟล์ EmployeeController ชั้นเรียน.

<?php  
use Zend\Mvc\Controller\AbstractActionController; 
use Zend\View\Model\ViewModel; 
use Employee\Model\Employee;       
use Employee\Model\EmployeeTable;    
use Employee\Form\EmployeeForm;

public function addAction() { 
   $form = new EmployeeForm(); $form->get('submit')->setValue('Add');  
   $request = $this->getRequest(); 
   
   if ($request->isPost()) { $employee = new Employee(); 
      $form->setInputFilter($employee->getInputFilter()); 
      $form->setData($request->getPost());  
      
      if ($form->isValid()) { $employee->exchangeArray($form->getData()); $this->table->saveEmployee($employee); // Redirect to list of employees return $this->redirect()->toRoute('employee'); 
      } 
   } 
   return array('form' => $form); 
}

ขั้นตอนที่ 19: เพิ่มฟังก์ชันการบันทึกในคลาส EmployeeTable

เพิ่มสองฟังก์ชันต่อไปนี้ในคลาส EmployeeTable - myapp / module / Employee / src / Model / EmployeeTable.php

public function getEmployee($id) { 
   $id = (int) $id; 
   $rowset = $this->tableGateway->select(array('id' => $id)); $row = $rowset->current(); if (!$row) { 
      throw new \Exception("Could not find row $id"); } return $row; 
}  
public function saveEmployee(Employee $employee) { $data = array (  
      'emp_name' => $employee->emp_name, 'emp_job' => $employee->emp_job, 
   );  
   $id = (int) $employee->id; 
   if ($id == 0) { $this->tableGateway->insert($data); } else { if ($this->getEmployee($id)) { $this->tableGateway->update($data, array('id' => $id)); 
      } else { 
         throw new \Exception('Employee id does not exist'); 
      } 
   } 
}

ขั้นตอนที่ 20: สร้างสคริปต์ View สำหรับเมธอด AddAction, Add.phtml

เพิ่มการเปลี่ยนแปลงต่อไปนี้ในไฟล์“ Add.phtml” ใน - myapp / module / view / workers / workers

<?php 
   $title = 'Add new employee'; $this->headTitle($title); ?> <h1><?php echo $this->escapeHtml($title); ?></h1> <?php $form->setAttribute('action', $this->url('employee', array('action' => 'add'))); $form->prepare(); 
   echo $this->form()->openTag($form); 
   echo $this->formHidden($form->get('id')); 
   echo $this->formRow($form->get('emp_name'))."<br>"; 
   echo $this->formRow($form->get('emp_job'))."<br>";   
   echo $this->formSubmit($form->get('submit')); 
   echo $this->form()->closeTag(); 
Request the application using the url, http://localhost:8080/employee/add

ผลลัพธ์

เมื่อเพิ่มข้อมูลแล้วข้อมูลจะเปลี่ยนเส้นทางไปยังโฮมเพจ

ขั้นตอนที่ 21: แก้ไขประวัติพนักงาน

ให้เราดำเนินการแก้ไขข้อมูลในโมดูลพนักงาน อัปเดตการเปลี่ยนแปลงต่อไปนี้ในไฟล์Employeecontroller.php.

public function editAction() { 
   $id = (int) $this->params()->fromRoute('id', 0); if (!$id) { 
      return $this->redirect()->toRoute('employee', array( 'action' => 'add' )); } try { $employee = $this->table->getEmployee($id); 
   } catch (\Exception $ex) { return $this->redirect()->toRoute('employee', array( 
         'action' => 'index' 
      )); 
   }  
   $form = new EmployeeForm(); $form->bind($employee); $form->get('submit')->setAttribute('value', 'Edit');  
   $request = $this->getRequest(); 
   
   if ($request->isPost()) { $form->setInputFilter($employee->getInputFilter()); $form->setData($request->getPost()); if ($form->isValid()) { 
         $this->table->saveEmployee($employee);  
         
         // Redirect to list of employees 
         return $this->redirect()->toRoute('employee'); } } return array('id' => $id, 'form' => $form,); 
}

ที่นี่เรามองหาไฟล์ idซึ่งอยู่ในเส้นทางที่ตรงกันจากนั้นโหลดรายละเอียดพนักงานสำหรับการดำเนินการแก้ไข

ขั้นตอนที่ 22: Employee.php

ตอนนี้เพิ่มการเปลี่ยนแปลงต่อไปนี้ในไฟล์“ Employee.php” ซึ่งอยู่ในไดเร็กทอรี - myapp / module / Employee / src / Employee / Model /

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

ที่นี่ Zend \ Stdlib \ Hydrator \ ArraySerializable คาดว่าจะพบสองวิธีในแบบจำลอง: getArrayCopy() และ exchangeArray().

ซึ่ง exchangeArray () ใช้สำหรับการวนซ้ำ ฟังก์ชันนี้ใช้สำหรับการผูกข้อมูลจากตารางพนักงาน

ตอนนี้เราต้องสร้างสคริปต์มุมมองสำหรับ editAction().

ขั้นตอนที่ 23: สร้าง Edit.phtml

สร้างไฟล์สคริปต์มุมมองในโมดูล / พนักงาน / มุมมอง / พนักงาน / พนักงาน / edit.phtml

<?php 
   $title = 'Edit employee records'; $this->headTitle($title); ?> <h1><?php echo $this->escapeHtml($title); ?></h1> <?php $form = $this->form; $form->setAttribute('action', $this->url( 'employee', array('action' => 'edit', 'id' => $this->id,) 
)); 
$form->prepare(); echo $this->form()->openTag($form); echo $this->formHidden($form->get('id')); echo $this->formRow($form->get('emp_name'))."<br>"; echo $this->formRow($form->get('emp_job'))."<br>"; echo $this->formSubmit($form->get('submit')); echo $this->form()->closeTag();

การแก้ไขรายละเอียดพนักงานจะแสดงในภาพหน้าจอต่อไปนี้

เมื่อแก้ไขข้อมูลแล้วข้อมูลจะเปลี่ยนเส้นทางไปที่โฮมเพจ

ขั้นตอนที่ 24: เพิ่มเมธอด deleteEmployee

เพิ่มเมธอด deleteEmployee ในคลาส EmployeeTable - myapp / module / Employee / src / Model / EmployeeTable.php

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

ขั้นตอนที่ 25: ลบประวัติพนักงาน

ตอนนี้ให้เราดำเนินการลบข้อมูลในโมดูลพนักงาน เพิ่มวิธีการต่อไปนี้deleteAction ในคลาส EmployeeController

public function deleteAction() { 
   $id = (int) $this->params()->fromRoute('id', 0); if (!$id) { 
      return $this->redirect()->toRoute('employee'); } $request = $this->getRequest(); if ($request->isPost()) { 
      $del = $request->getPost('del', 'No');  
      if ($del == 'Yes') { $id = (int) $request->getPost('id'); $this->table->deleteEmployee($id); } return $this->redirect()->toRoute('employee'); 
   }  
   return array( 
      'id' => $id, 'employee' => $this->table->getEmployee($id) 
   ); 
}

ที่นี่วิธี deleteEmployee () จะลบพนักงานโดย id และเปลี่ยนเส้นทางไปยังหน้ารายชื่อพนักงาน (โฮมเพจ)

ให้เราสร้างสคริปต์มุมมองที่เกี่ยวข้องสำหรับเมธอด deleteAction ()

ขั้นตอนที่ 26: สร้าง View Script

สร้างไฟล์ที่ชื่อ delete.phtml ใน - myapp / module / Employee / view / workers / workers / delete.phtmlและเพิ่มโค้ดต่อไปนี้

<?php 
   $title = 'Delete an employee record'; 
   $this->headTitle($title);  
?> 
<h1><?php echo $this->escapeHtml($title); ?></h1>  

'<?php echo $this->escapeHtml($employee->emp_name); ?>' by 
'<?php echo $this->escapeHtml($employee->emp_job); ?&'?  
<?php 
   $url = $this->url('employee', array('action' => 'delete', 'id' => $this->id,)); ?> <form action ="<?php echo $url; ?>" method = "post">
   <div> 
      <input type = "hidden" name = "id" value = "<?php echo (int) $employee->id; ?>" /> 
      <input type = "submit" name = "del" value = "Yes" /> 
      <input type = "submit" name = "del" value = "No" /> 
   </div> 
</form>

ตอนนี้ลบพนักงานโดยใช้ไฟล์ edit ลิงค์ในโฮมเพจและผลลัพธ์จะเป็นดังที่แสดงในภาพหน้าจอต่อไปนี้

ผลลัพธ์

เราได้ทำโมดูลพนักงานสำเร็จแล้วโดยใช้คุณสมบัติที่จำเป็นทั้งหมด

สรุป

ในสภาพแวดล้อมการแข่งขันปัจจุบัน Zend framework ถูกวางไว้ที่จุดสูงสุดโดยนักพัฒนา ให้ความเป็นนามธรรมแก่โปรแกรมใด ๆ หรือแอปพลิเคชันประเภทใดก็ได้ในภาษา PHP เป็นเฟรมเวิร์กที่ครบกำหนดและรองรับคุณสมบัติภาษา PHP ที่ทันสมัย เป็นเรื่องสนุกเป็นมืออาชีพมีการพัฒนาและก้าวทันเทคโนโลยีในปัจจุบัน