首頁  >  文章  >  後端開發  >  php實作mvc模式的例子

php實作mvc模式的例子

WBOY
WBOY原創
2016-07-25 09:05:30946瀏覽
  1. {some_text}

  2. {some_more_text}

複製程式碼

它們在文件中沒有意義,它們代表的意義只是PHP將用其他的東西來取代它。

如果你同意這種對視圖的鬆散描述,你也會同意絕大多數模板方案並沒有有效的分離視圖和模型。模板標籤將被替換成什麼存放在模型中。

在你實現視圖時問自己幾個問題:「全體視圖的替換容易嗎?」「實現一個新視圖要多久?」 「能很容易的替換視圖的描述語言嗎?(例如在同一個視圖中用SOAP文檔取代HTML文檔)”

二、模型(Model)

模型代表了程式邏輯。 (在企業級程序中常稱為業務層(business layer))

總的來說,模型的任務是把原有數據轉換成包含某些意義的數據,這些數據將被視圖所顯示。通常,模型將封裝資料查詢,可能透過一些抽象資料類別(資料存取層)來實現查詢。舉例說,你希望計算英國年度降雨量(只是為了給你自己找個好點的度假地),模型將接收十年中每天的降雨量,計算出平均值,再傳遞給視圖。

三、控制器(controller)

簡單的說控制器是Web應用中進入的HTTP請求最先呼叫的一部分。它檢查收到的請求,例如一些GET變量,做出合適的回饋。在寫出你的第一個控制器之前,你很難開始寫其他的php程式碼。最常見的用法是index.php中像switch語句的結構:

  1. switch ($_GET['viewpage']) {
  2. case "news":
  3. $page=new NewsRenderer;
  4. break;
  5. case "links":
  6. $page=new LinksRenderer;
  7. break;
  8. default:
  9. $page=new HomePageRenderer;
  10. breakault:
  11. $page=new HomePageRenderer;
  12. breakault; >}
  13. $page->display();
  14. ?>
複製程式碼

這段程式碼混用了面向過程和物件的程式碼,但是對於小的網站來說,這通常是最好的選擇。雖然上邊的程式碼還可以優化。 控制器實際上是用來觸發模型的資料和視圖元素之間的綁定的控制項。

這裡是一個使用MVC模式的簡單範例。 首先我們需要一個資料庫存取類,它是一個普通類。
  1. /**

  2. * 一個用來查詢 MySQL 的簡單類別
  3. */
  4. class DataAccess {
  5. /**
  6. * 私人
  7. * $db 儲存資料庫資源
  8. */
  9. class DataAccess {
  10. /**
  11. * 私有
  12. * $query 儲存查詢資源
  13. */
  14. class DataAccess {
  15. /**
  16. * 建構一個新的DataAccess 物件
  17. * @param $host string dbserver 主機名稱
  18. * @param $user string dbserver 使用者
  19. * @param $pass string dbserver 使用者密碼
  20. * @>* @param $pass string dbserver 使用者密碼
  21. * @>* param $db 字串資料庫名稱
  22. */
  23. class DataAccess {
  24. /**
  25. * 取得查詢資源並將其儲存在本機成員中
  26. * @param $sql string 要執行的資料庫查詢
  27. * @return void
  28. */
  29. var $db;
  30. /**
  31. * 傳回查詢行的關聯陣列
  32. * @return mix
  33. */
  34. var $query; // Query resource
  35. //! A constructor.

  36. /***/
  37. function DataAccess ($host,$user,$pass,$db) {
  38. $this->db=mysql_pconnect($host,$user,$pass) ;
  39. mysql_select_db($db,$this->db);
  40. }
  41. //! An accessor

  42. /***/
  43. function fetch($sql) {
  44. $this->query=mysql_unbuffered_query($sql,$this->db); // Perform query here
  45. }
  46. //! An accessor

  47. /***/
  48. function getRow () {
if ( $row=mysql_fetch_array($this->query,MYSQL_ASSOC) )
return $row; else; return false;
} } ?>複製程式碼

在它上面放上模型。

  1. /**

  2. * 從資料庫取得「產品」
  3. * 連結:http://bbs.it-home.org
  4. */
  5. class ProductModel {
  6. /**
  7. * 私有
  8. * $dao DataAccess 類別的實例
  9. */
  10. var $dao;
  11. //! A constructor.

  12. /**
  13. * 建構一個新的 ProductModel 物件
  14. * @param $dbobject DataAccess 類別的實例
  15. */
  16. function ProductModel (&$dao) {
  17. $this->dao=& $dao;
  18. }
  19. //! A manipulator

  20. /**
  21. * 告訴$dboject 將此查詢儲存為資源
  22. * @param $start 從
  23. 開始的行
  24. * @param $rows 要取得的行數
  25. * @return void
  26. */
  27. function listProducts($ start=1,$rows=50) {
  28. $this->dao->fetch("SELECT * FROM products LIMIT ".$start.", ".$rows);
  29. }
  30. //! A manipulator

  31. /**
  32. * 告訴 $dboject 將此查詢儲存為資源
  33. * @param $id 行的主鍵
  34. * @return void
  35. */
  36. function listProduct($id) {
  37. $this->dao->fetch("SELECT * FROM products WHERE PRODUCTID ='".$id."'");
  38. }
  39. //! A manipulator

  40. /**
  41. * 從 $dbobject 以關聯陣列的形式取得產品
  42. * @return mix
  43. */
  44. function getProduct() {
  45. if ( $product=$this->dao->getRow() )
  46. return $product;
  47. else
  48. return false;
  49. }
  50. }
  51. ?>
複製程式碼

注意:在模型和資料存取類別之間,它們的交互作用從來不會多於一行— —沒有多行被傳送,那樣會很快地讓程式慢下來。同樣的程式對於使用模式的類,它只需要在記憶體中保留一行(Row)-其他的交給已儲存的查詢資源(query resource)-換句話說,我們讓MYSQL替我們保持結果。

接下來是視圖(以下程式碼去掉了html內容)。
  1. /**

  2. * 綁定商品資料到HTML渲染
  3. * 連結:http://bbs.it-home.org
  4. */
  5. class ProductView {
  6. /**
  7. * 私有
  8. * $model ProductModel 類別的實例
  9. */
  10. var $model;
  11. /**

  12. * 私有
  13. * $output 渲染的 HTML 儲存在此處用於顯示
  14. */
  15. var $output;
  16. //! A constructor.

  17. /**
  18. * 建構一個新的 ProductView 物件
  19. * @param $model ProductModel 類別的實例
  20. */
  21. function ProductView (&$model) {
  22. $this->model=& $model;
  23. }
  24. //! A manipulator
  25. /**
  26. * 建立 HTML 頁面的頂部
  27. * @return void
  28. */
  29. function header () {
  30. }

  31. //! A manipulator

  32. /**
  33. * 建立 HTML 頁面的底部
  34. * @return void
  35. */
  36. function footer () {
  37. }

  38. //! A manipulator

  39. /**
  40. * 顯示單一產品
  41. * @return void
  42. */
  43. function productItem($id=1) {
  44. $this->model->listProduct($id);
  45. while ( $product=$this->model- >getProduct() ) {
  46. // Bind data to HTML
  47. }
  48. }
  49. //! A manipulator

  50. /**
  51. * 建立產品表
  52. * @return void
  53. */
  54. function productTable($rownum=1) {
  55. $rowsperpage='20';
  56. $this->model->listProducts($rownum,$rowsperpage);
  57. while ( $product=$this ->model->getProduct() ) {
  58. // Bind data to HTML
  59. }
  60. }
  61. //! An accessor

  62. /**
  63. * 回傳渲染的 HTML
  64. * @return string
  65. */
  66. function display () {
  67. return $this->output;
  68. }
  69. }
  70. ?>
複製程式碼

最後是控制器,我們將把視圖實作為一個子類別。

  1. /**

  2. * 控制應用程式
  3. */
  4. class ProductController extends ProductView {
  5. //! A constructor.

  6. /**
  7. * 建構一個新的 ProductController 物件
  8. * @param $model ProductModel 類別的實例
  9. * @param $getvars 傳入的 HTTP GET 方法變數
  10. */
  11. function ProductController (&$model,$getvars=null) {
  12. ProductView::ProductView($model) ;
  13. $this->header();
  14. switch ( $getvars['view'] ) {
  15. case "product":
  16. $this->productItem($getvars['id'] );
  17. break;
  18. default:
  19. if ( empty ($getvars['rownum']) ) {
  20. $this->productTable();
  21. } else {
  22. $ this->productTable($getvars['rownum']);
  23. }
  24. break;
  25. }
  26. $this->footer();
  27. }
  28. }
  29. ? >
複製程式碼

注意:這不是實現MVC的唯一方式-例如你可以用控制器實作模型同時整合視圖。這只是演示模式的一種方法。 index.php 檔案看起來像這樣:

  1. require_once('lib/DataAccess.php');

  2. require_once('lib/ProduModelModel .php');
  3. require_once('lib/ProductView.php');
  4. require_once('lib/ProductController.php');
  5. $dao=& new DataAccess ( 'localhost','user','pass','dbname');

  6. $productModel=& new ProductModel($dao);
  7. $productController=& new ProductController($productModel,$_GET);
  8. echo $productController->display();
  9. ?>
複製程式碼

有些使用控制器的技巧,在PHP中你可以這樣做: $this->{$_GET['method']}($_GET['param']); 建議最好定義程式URL的名字空間形式(namespace),這樣它會比較規範例如:

  1. "index.php?class=ProductView&method=productItem&id=4"
複製程式碼 >透過它可以這樣處理控制器:

    $view=new $_GET['class'];
  1. $view->{$_GET['method']($_GET[' id']);
複製程式碼
有時建立控制器並非易事,例如需要在開發速度和適應性之間權衡時。 一個獲得靈感的好去處是Apache group 的Java Struts,它的控制器完全是由XML文件定義的。

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn