วันอังคารที่ 7 ธันวาคม พ.ศ. 2553

โครงสร้าง MVC ของ Zend Framework

MVC


M (Model) คือเนื้อหาที่อยู่ใน application เช่น data, web service, rss feed
V (View) คือส่วนแสดงผลที่แสดงต่อผู้ใช้
C (Controller) คือส่วนจัดการกับการ request และควบคุมการทำงาน

Controller สามารถบอกให้ View แสดงผลต่างๆ ในแบบต่างๆ
View สามารถส่งข้อมูลไปให้กับ Controller

Controller สามารถดึงเอาข้อมูลจาก Model มาใช้ในการตัดสินใจต่างๆ
และสามารถส่งข้อมูลไปให้ Model เพื่อให้บันทึกข้อมูล

View สามารถเข้าถึง Model เพื่อดึงเอาข้อมูลมาใช้ แต่ไม่สามารถส่งข้อมูลเพื่อให้ Model บันทึกข้อมูล


Front Controller


จัดการกับการ requests
ส่งต่อการควบคุมให้กับ Action Controller
คืนค่า response

Zend_Controller


เกี่ยวกับ Controller
ในการสร้าง Action Controller เราจะสร้าง class ซึ่ง extends Zend_Controller_Action
ในการตั้งชื่อ class เราจะตั้งชื่อให้ลงท้ายว่า Controller ยกตัวอย่างเช่น IndexController
ตัวอักษร _ ในชื่อ class จะแทน subdirectory อย่างเช่น Test_MyController จะหมายถึง Test/MyController.php
URL ของ DoraemonNobitaController คือ /doraemon-nobita หรือ /doraemon.nobita หรือ /doraemonIndex

เกี่ยวกับ Action
คือ method ที่ controller นำมาใช้งาน
โดยจะต้องเป็น public method ที่มีชื่อลงท้ายว่า Action เช่น indexAction(), viewAction()
URL ของ magicItemAction() คือ /doraemon-nobita/magic-item หรือ /doraemon-nobita/magic.item หรือ /doraemon-nobita/magic_item

เกี่ยวกับ Modules
คือกลุ่มของ action controllers, models และ views ที่สัมพันธ์กัน
โครงสร้าง directory จะสัมพันธ์กับโครงสร้าง application directory
ชื่อคลาสของ Controller ควรจะนำหน้าด้วยชื่อ Module
  ยกตัวอย่างเช่น Cartoon_DoraemonController.php ซึ่งจะมีโครงสร้าง directory เป็น Cartoon/controller/DoraemonController.php
ชื่อของ Module จะต้องเป็น camel case เช่นเดียวกับชื่อของ Controller

Request Object  จะบรรจุข้อมูลเกี่ยวกับการ request เอาไว้ทั้งหมด
Router จะแยกข้อมูลจากการ request เช่น url ออกเป็น token ที่แสดงถึง action, controller และ module ของการ request
Dispatcher นำเอา token ที่ได้จากการ routing มาเป็นข้อมูลในการเลือก คลาส metod ของ action controller, จากนั้นจึงสั่งให้มันทำงาน
Response Object จะบรรจุข้อมูล response ที่สมบูรณ์ และมีความสามารถในการส่งข้อมูลกลับไปให้ user

Dispatch Loop

  1. Zend_Controller_Front::getInstance()->dispatch(); จัดการกับ request ที่เข้ามา

  2. สร้าง ออปเจค request และ ออปเจค response ถ้ายังไม่ได้ถูกสร้างขึ้น

  3. ทำการ route request

  4. เข้าสู่ dispatch loop

    • ในการ dispatch action ประกอบด้วยการสร้างออปเจค controller และการเรียก method ของ controller

    • ซึ่งจะทำการ dispatch ไปเรื่อยๆ จนกว่าออปเจค request จะรายงานกลับมาว่าไม่มี action ที่จะต้อง dispatch อีก



  5. คืนค่า response



Routing
default routing ได้แก่
/controller/action/key1/value1/key2/value2
/module/controller/action/key1/value1/key2/value2

การแก้ไข routing เรียกว่า Rewrite Router
Zend_Controller_Router_Rewrite คือส่วนการทำงานของ router ปกติ
อนุญาตให้เพิ่ม named route ได้มากเท่าที่ต้องการ
named route จะช่วยให้สามารถทำงานเกี่ยวกับการ route ได้ในภายหลัง การรวมกันเป็น URL
และการวิเคราะห์หาว่ามีข้อมูลอะไรบ้างที่อยู่ใน URL
การ Route ถูกประมวลผลแบบ LIFO (route ที่นิยามทีหลังสุดจะถูกประมวลผลเป็นอันดับแรก)
Route interface ช่วยให้คุณสามารถสร้างชนิดของการ route ที่จะใช้กับ application ของคุณได้เอง


ชนิดของ Route ที่ได้เตรียมไว้ให้
static: เทียงเคียงอย่างตรงไปตรงมา, ส่งต่อการทำงานสอดคล้องกับการ default route
standard: เทียงเคียงกับส่วนประกอบใน named URL, ยืดหยุ่นและอ่านได้ง่าย แต่ว่าแต่ะละส่วนประกอบจะต้องใช้ regexp ในการเทียบเคียงจึงทำงานค่อนข้างช้า
regex: เทียบเคียงโดยใช้ PCRE, มีความยืดหยุ่นสูงและเร็วกว่าแบบ standard แต่สร้างยากกว่าแบบ standard

ลองดูตัวอย่างการ route นะครับ อันนี้เป็น standard route
เมื่อเพิ่มโค้ดนี้ลงใน c:/www/quick/application/bootstrap.php นะครับ
(ก่อนคำสั่ง unset($frontController, $view, $configuration, $dbAdapter, $registry);)
ก็จะทำให้ http://localhost/quick/public/homepage ชี้ไปที่ controller index, action index ครับผม
หรือ http://localhost/quick/public/homepage ชี้ไปที่เดียวกับ http://localhost/quick/public ครับ

// Create a router
$router = $frontController->getRouter(); // returns a rewrite router by default
$router->addRoute(
'myRouteName',
new Zend_Controller_Router_Route('homepage',
array('controller' => 'index',
'action' => 'index'))
);

Action Controllers


คือคลาสที่ extends จาก Zend_Controller_Action
ใช้กำหนด public action (method ที่ลงท้ายด้วย Action) ที่ต้องการให้ controller ควบคุม
สร้าง public method ถ้าต้องการจะนำกลับมาใช้ใหม่ หรือหากต้องการให้ทดสอบโปรแกรมได้สะดวก

ใน Action Controller เราสามารถสร้าง method เพื่อ listen และแทรกคำสั่งใน event ต่อไปนี้
init(): method ที่จะถูกเรียกเมื่อ object ของ Action Controller ถูกสร้างขึ้น
preDispatch(): method ที่จะถูกเรียกก่อนการ dispatch action
postDispatch(): method ที่จะถูกเรียกหลังการ dispatch action

Utility Methods
_forward : ใช้เพื่อย้ายไปยัง action อื่น
_redirect : ใช้เพื่อย้ายไปยัง url อื่น
render : ใช้เพื่อเปลี่ยนไปใช้ view อื่นแทน default view
__call : สามารถ override method นี้เพื่อควบคุมการทำงาน undefined action ว่าจะให้ forward ไปยัง action ไหน

ViewRenderer


เป็น action helper ตัวนึงที่ ZF จะสร้าง object ขึ้นมาให้โดยอัตโนมัติ
property view ($this->view) ของ controller คือออปเจค view
เราสามารถกำหนดค่าตัวแปรให้ view โดยใช้คำสั่ง
$this->view->varname = $varname;

View Script จะถูกนำมาแสดงผลโดยอัตโนมัติหลังจาก event postDispatch()
view script จะมีชื่อตาม controller และ action
ตัวอย่างเช่น DoraemonController::showItemsAction จะมีไฟล์ view script คือ /view/scripts/doraemon/show-items.phtml
เราสามารถใช้คำสั่ง setNoRender() เพื่อบอกให้ controler ไม่นำ view script มาแสดงผลโดยอัตโนมัติ

คำสั่งเกี่ยวกับ ViewRenderer
setView
setViewSuffix
setView(Base|Script)PathSpec()
setResponseSegment()


Plugins


plugin จะถูกเรียกใน event ของ front controller
มีการแทรก event ในทุกๆ ขบวนการหลักของ front controller
ช่วยให้สามารถสร้าง action แบบ global (แทรกคำสั่งเพิ่มเข้าไปในทุกๆ action)

event
routeStartup(): ทำงานก่อนการ route
routeShutdown(): ทำงานหลังการ route
dispatchLoopStartup(): ทำงานก่อน รอบแรกของ dispatch loop
preDispatch(): ทำงานก่อนการ dispatch action
postDispatch(): ทำงานหลัง dispatch action
dispatchLoopShutdown(): ทำงานหลังจากที่ dispatch loop วนซ้ำจบ

การสร้าง plugins
ให้สร้างคลาส extends Zend_Controller_Plugin_Abstract
เขียน override event ลงใน คลาสดังกล่าว โดยอาจจะเขียนเพียง event เดียวหรือหลาย event ก็ได้


Action Helpers


Action Helper คือคลาสที่รวมเอา function ที่นำกลับมาใช้ได้ใหม่ในหลายๆ controller

การสร้าง Action Helper
สร้างคลาส extends Zend_Controller_Action_Helper_Abstract
ส่วนสุดท้ายของชื่อคลาสคือชื่อของ helper
ตัวอย่างเช่น My_Helper_SuperMan 'SuperMan' คือชื่อของ helper
สร้าง method direct() เพื่อให้ helper ถูกเรียกราวกับว่าเป็น mehod ของ helper broker

การใช้ Action Helper เป็น Action Controller Event Listener

init(): เมื่อ action controller ถูกสร้างขึ้น
preDispatch(): ทำงานหลังจาก preDispatch() ของ front controller plugins แต่ทำงานก่อน preDispatch() ของ action controller
postDispatch(): ทำงานหลังจาก postDispatch() ของ action controller แต่ทำงานก่อน postDispatch() ของ front controller plugins

โน๊ต : event listener ของ helper จะถูก trigger ก็ต่อเมื่อได้ทำการลงทะเบียนกับ broker


Zend_View


สร้างคลาสจาก Zend_View_Interface เพื่อสร้าง template engine ของคุณเอง
default คลาส Zend_View ใช้ ภาษา PHP เป็น template language
สามารถกำหนดค่าตัวแปร view ราวกับว่ามันเป็นสมาชิกของ object อย่างเช่น $view->varname = $varname;
ใช้งานตัวแปร view ใน view script ได้จากออปเจค $this ตัวอย่างเช่น <?= $this->varname ?>


View Helper


เป็นคลาสซึ่ง ขยายความสามารถให้กับ Zend_View
ตัวอย่างเช่นช่วย นำเข้า rss feed มายังเว็บเพจ
จัดรูปแบบ text ให้อยู่ในรูปแบบ xhtml
ช่วยแสดงผลตามเงื่อนไขที่ตั้งไว้อย่างเช่นแสดงผลปุ่ม login ถ้ายังไม่ได้ login
ส่วนแสดงผลที่สามารถนำกลับมาใช้หลายๆ ครั้ง เช่นกล่อง serach

การใช้ View Helper
เรียกใช้งาน Vew Helper ราวกับว่ามันเป็น method ของออปเจค View
<?= $this->formText('username') ?>

การสร้างและใช้งาน View Helper
ชื่อคลาส My_View_Helper_Coffee จะมีชื่อ helper เป็น coffee
ลงทะเบียน helper paths กับออปเจค Zend_View

จะต้องมีชื่อ method ชื่อเดียวกับ helper ดังนี้

<?php
class My_View_Helper_Coffee
{
  function coffee(){
  }
}
?>


View Filter


ช่วยในการกรอง content ก่อนจะนำไปแสดงผลจริงๆ
เหมือนกับ View Helper คือจะต้องสร้างคลาสซึ่งมี 1 method ต่อ 1 class
ประโยชน์ของ Filter เช่นแปลง HTML เป็น PDF, JSON, ลบแท็ก script ออกไปจาก content

Zend_Model


ตัวอย่างของ Model ได้แก่ Database, Web Service, RSS Feeds, FileSystem, Images

Zend Framework ระบุถึง Model ได้อย่างไร
ZF ยังไม่ได้สร้าง Model ที่เป็นแบบทั่วไปขึ้นมา
แต่ ZF สนับสนุน Model ที่มีความเฉพาะเจาะจงตัวอย่างเช่น Zend_Db_Table, Zend_Service, Zend_Feed


reference
Ophinney_Matthew_2007-ZendCon-MVC.pdf

ไม่มีความคิดเห็น:

แสดงความคิดเห็น