無痛移轉 PHP 網頁至 MVC 架構

相信只要是從事開發網頁的工作的人,在這幾年中,累積了不少用 ASP 或 PHP 開發的網頁程式。剛開始的時後,一切都很簡單。可是隨著網頁變多,要維護或變動,就開始變得很痛苦了。到最後,只要有變動的要求,根本就是夢魘。

最近,流行 MVC 的框架,可以讓開發和維護網頁的工作變得較為輕鬆。那要把原來的網頁程式移轉至 MVC 架構,現有的 PHP 網頁是否必須重新來過,打掉重練? 還是可以逐步移轉至 MVC 架構呢?沒問題,當然可以。在此,提供個人的懶人移植方法,供各位參考。既然稱為「懶人」法,目的只是把原來的程式塞進 MVC 框架中,產生的程式,並不完全符合 MVC 的精神。不過,只要能把程式搬到 MVC 的框架下,就可以等有時間再慢慢修 (refactoring,重構),或者,要新增功能時,就以 MVC 的方式來開發。

在此是以 PHP 的 MVC 框架 -- Laravel 來說明,所以,假如是 ASP 的程式,當然要先轉成 PHP 的程式。要把 ASP 轉成 PHP,不用擔心,早就有人寫好程式 -- asp2php,上網找到,直接使用就是了。轉換後的 PHP 程式,必需要做一些修改才行。例如,它會把資料庫的操作都改成 mysql 的函式。最好是把資料庫操作的部份改成 PDO 界面,一勞永逸,因為在 Laravel 中只支援 PDO 界面。

接下來,進入正題,說明如何將 PHP 網頁程式塞進 MVC 框架,非常簡單。

假如原來有 3 個網頁 page1.php,page2.php,及 page3.php。瀏覽的 url,以 page1.php 為例,如下

http://my.net/page1.php

在 MVC 的 controllers 目錄下,建立一個適當名稱的 controller,例如 web.php。再來,將原來的 PHP 網頁都放到 views 的目錄下。這樣就讓原來的程式變成 MVC 架構中的 View 和 Controller 兩部分了。在 MVC 架構下的瀏覽的 url,以 page1.php 為例,如下

http://my.net/index.php/web/page1

我一般都不會去特意的將 index.php 隱藏,留著似乎也沒人在意,而我自己在意的是程式好維護就好。

其中,假設 page1 為預設的網頁,則網址 http://my.net/index.php/web 將傳回 page1 的內容。

假如要傳參數,怎麼辦? 放在後面就行啦,如下

http://my.net/index.php/web/page1?usr=ajax&role=M

web.php 的內容如下

<?php
class Web_Controller extends Base_Controller {
    // 未登入者,導向登入畫面
    function __construct() {
        if (!Session::has("user")) {
            header("Location: ".url("user/login"));
        }
    }
    public function action_index() {
        return Controller::call('web@page1');
    }
    public function action_page1() {
        return View::make('page1');
    }
    public function action_page2() {
        return View::make('page2');
    }

public function action_page3() {

        return View::make('page3');
    }
} // end of class

在這個 controller 中,有做身分的檢查,這部分可以考慮改成框架提供的功能。若想偷懶,就將就著用吧。就這樣,各個 page 幾乎不用修改,就可以正常運作。在移轉過程中,可以將一些設定值放在 config 目錄下的設定檔,例如 database.php。在舊的程式中要取得這些設定值,例如為舊的程式定義一個資料庫連接函式 get_conn()。

function get_conn() {
    $db_conns = Config::get('database.connections');
    $db = $db_conns[Config::get('database.default')];
   
    $dbsvr = $db['host'];
    $dbnam = $db['database'];
    $dbid  = $db['username'];
    $dbpwd = $db['password'];
    try {
        $conn = new PDO("sqlsrv:server=$dbsvr ; Database=$dbnam", $dbid, $dbpwd);
        $conn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $conn->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER);
    } catch(Exception $e) {
        die( '<pre>'.print_r($e->getMessage(), true).'</pre>' );
    }
    return $conn;
}

綜結一下,目錄架構如下 (只列出上面提到的)

application
  ├- config
  │    └- database.php
  ├- controllers
  │    └- web.php
  └- views
        └- page1.php, page2.php, page3.php

這時,可能會想移轉到 MVC 架構下,有什麼好處呢? 好處是可以慢慢的將一些東西抽出來,改成符合 MVC 架構精神的作法。例如,可以將 view 中的共用部分抽取出來,做成樣版。或者,將一些資料庫的功能放進 model 中。

就這樣,無痛的將舊網頁移轉到 MVC 的架構,然後等有空,心情好時,再慢慢地修飾。

最後,還是得承認,這樣的程式不完全符合所謂的 MVC 分離的精神。但這總是一個很好的起步,讓你脫離害怕面對支離破碎,無法維護的網頁的窘境。日子是自己要過的,沒人規定程式一定得如何寫才可以。

祝 好運,MVC 與你同在!