簡述框架是如何解析URL到對應的Action中去的

MVC是目前常用的開發架構,基於MVC模式的php開發框架種類繁多,但其原理大同小異。下面粗略的講解一下MVC中的URL解析過程。
    衆所周知,MVC架構往往採用單一文件入口,通過URL地址映射,調用相應的controller,model,view完成業務邏輯和頁面顯示。爲了對搜索引擎友好,URL地址往往寫成這樣:http://localhost/web/action/method/id/1
或者http://localhost/web/action/method/id/1.shtml的形式,即,調用web下的action類中的 method方法,參數是id=1。如何從URL中分離這些類,方法和參數呢?這就需要寫一個URL解析類(class.route.php),URL解析完成後,需要調用相應的類完成任務,所以還需要一個分發類(class.dispatcher.php),不要忘了,還有入口文件和配置文件。
    一、配置文件:config.php
    爲了簡單起見,我們只配置一下url的僞靜態後綴。
    <?php
        return array(
        'HTML_URL_SUFFIX'=>'.shtml'  //僞靜態後綴shtml,html,htm都可以
        );
    ?>
    二、.htaccess文件:過濾掉index.php
    # Turn on URL rewriting  
    RewriteEngine On  
  
    # Installation directory 如果你的項目在非根目錄的話,就填目錄名,比如:/test/  
    RewriteBase /urltest/  
  
    # Protect application and system files from being viewed  
    RewriteRule ^(application|modules|system) - [F,L]  
  
    # Allow any files or directories that exist to be displayed directly  
    RewriteCond %{REQUEST_FILENAME} !-f  
    RewriteCond %{REQUEST_FILENAME} !-d  
  
    # Rewrite all other URLs to index.php/URL  
    RewriteRule .* index.php/$0 [PT,L]  
    # or  
    #RewriteRule .* index.php?arg=$0 [PT,L]  
 
    三、入口文件:index.php
    <?php
        require 'class.route.php';
        require 'class.dispacher.php';
        $route = new Route();
        $dis = new Dispatcher($route);
        $dis->dispatch();
    ?>
    四、Route類:用於解析URL
    <?php
        class Route{
            private $action;
            private $method;
            private $params = array();
            public function __construct(){
                $this->parseURL();
            }
            public function __get($name){
                return $name;
            }
            //URL解析
            public function parseURL(){
                $str1 = $_SERVER['PHP_SELF'];
                $str2 = $_SERVER['SCRIPT_NAME'];
                $len = strlen($str2);
                $des = substr($str1,$len+1,strlen($str1)); 
                $config = require("config.php");
                if($suffix = $config['HTML_URL_SUFFIX'])
                    $des = substr($des,0,strlen($des)-strlen($suffix));
                //分別取出action,method,id,1
                $arr = explode("/",$des);
                $this->action = array_shift($arr);
                $this->method = array_shift($arr);
                $this->params = array();   //參數數組params[參數名稱]=參數值
                for($i=0;$i<count($arr);$i=$i+2){
                    $this->params[$arr[$i]] = $arr[$i+1]; 
                }
            }
            public function getAction(){
                return $this->action;
            }
            public function getMethod(){
                return $this->method;
            }
            public function getParams(){
                return $this->params;
            }
        }
    ?>
    五、Dispatcher類:調用解析出來的類和方法,完成業務邏輯
    <?php
        class Dispatcher{
            private $route = NULL;
            private $action;
            private $method;
            private $params = array();
            public function __construct($route){
                $this->route = $route;
                $this->action = $route->getAction();
                $this->method = $route->getMethod();
                $this->params = $route->getParams();
            }
            public function dispatch(){
                //加載action類,method方法
                if(empty($this->action))
                    $this->action="Index";
                if(empty($this->method))
                    $this->method = "index";
                if(!file_exists($this->action."Action.php"))
                    echo "{$this->action}Action not found!";
                else{
                    require($this->action."Action.php");
                    $className = $this->action."Action";
                    $action = new $className();
                    $method = $this->method;
                    if(!method_exists($action,$this->method))
                        echo "{$method}() not found";
                    else
                    $action->$method($this->params);
                 }
             }
        }
    ?>
    六、測試的action類:IndexAction包含inde()方法,用於默認訪問
    <?php
        class IndexAction{
            public function index($arr){
                echo "<pre>";
                print_r($arr);
                echo "</pre>";
                echo "Hello,world!";
            }
        }
    ?>
    程序的執行過程是這樣的:用戶輸入http://localhost/web/Index/index/id/1,index.php文件接 收,調用route解析URL地址,dispatcher通過解析結果調用相應的action和method。過程是不是很簡單呢,此文只爲抱磚引玉,簡 述原理。讀者可根據自己的需要,根據原理架構自己的MVC框架。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章