欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

自制PHP框架之路由與控制器

 更新時間:2017年05月07日 09:17:14   作者:編程老頭  
本文給大家介紹的是自制php框架的第一步,學會使用路由和控制器,非常的詳細,有需要的小伙伴可以參考下

我們?yōu)槭裁匆褂寐酚桑吭?:一個更漂亮的URI

1.URI的改進

剛剛開始學PHP時,我們一定寫過blog.php?id=1之類的URI,使用GET方式獲取參數。這樣的URI有兩個缺點,一是容易被SQL注射攻擊,二是維護性可讀性差,大家可以比較下面兩種URI哪一種更具備可讀性。

www.mysite.com/blog.php?id=1

上面URI是我們初學PHP最常用的。

www.mysite.com/blog/1

這種URI是目前最流行的URI,舉個例子,比如很多讀書類,電影類網站,都使用了這樣的URI,這樣的URI要比index.php?a=1&b=2&c=3&d=4....要簡潔很多。

2.實現方法

在WEB項目的根目錄下寫一個.htaccess文件

RewriteEngine On

RewriteRule ^([a-zA-Z0-9/]*)$ index.php/$1

重寫規(guī)則,讓域名后面的字符串直接做為一個參數傳入index.php,這樣index.php就成為了你整個WEB應用的中心,定義了“請求和響應的映射”。

原因2:單一入口機制的易維護性

1.路由數組

一個PHP初學者,剛開始做項目,項目做著做著規(guī)模做大了,常常這個PHP頁面給另一個PHP頁面用GET方法傳值,有時傳的值還不止一個,時間一久,你的WEB項目,N個PHP頁面宛如一個復雜的蜘蛛網,讓你難以維護。一旦有修改,會涉及很多PHP文件,工作量很大。

MVC的單一入口機制可以解決維護難的問題,路由就是一套映射,可以讓你一個URI對應一個方法。

$route=[

  ''=>'IndexController@Index',

  'blog'=>'BlogController@Show',

  'blog/{id}/{name}'=>'BlogController@Show',

];

2.獲取參數

$path=$_SERVER['PATH_INFO'];

$path=ltrim($path,'/');

echo $path.PHP_EOL;

我們在瀏覽器里輸入:www.mysite.com/blog/1后,path變量為/blog/1。使用ltrim函數刪除左邊的斜杠,然后使用explode把字符串拆解成數組。

$path_arr=explode('/', $path);

核心代碼如下:

if(isset($_SERVER['PATH_INFO'])){

  $path=$_SERVER['PATH_INFO'];

  $path=ltrim($path,'/');

  $path_arr=explode('/', $path);

}

 

if(isset($path_arr[0])){

  $key=$path_arr[0];

  unset($path_arr[0]);

}

else{

  $key='';

}

 

if(isset($path_arr[1])){

  $parameters=array_values($path_arr);

}

 

 

if(isset($route[$key])){

  $arr=explode('@', $route[$key]);

   

  $controller=new $arr[0];

  $action=$arr[1];

   

  if(isset($parameters)){

    $controller->$action($parameters);

  }

  else{

    $controller->$action();

  }  

}

else{

  require 'error.html.php';

}

unset函數可以銷毀數組中key和value,但是并不會重建索引,所以path_arr[0]是要調用的控制器類和方法名,path_arr[1]或者path_arr[1..N]就作為傳入方法的參數。

重定向和錯誤頁面是WEB系統(tǒng)中最常見的,如果不用路由機制,你可能要沒完沒了的重復寫重定向或者錯誤頁面的顯示或者跳轉代碼,有了路由,只需要一句話就可以完成。

原因3:減少資源的消耗

MVC采用了控制器(controller)來響應請求(request),每次請求來時,應該在指定的一個PHP文件中初始化這個控制器,而不是分別在不同的PHP文件中做初始化工作,這樣可以減少資源的消耗。

是不是一定要用控制器?方案1:不用控制器

我們現在路由數組里添加一項,value不是一個字符串,而是一個匿名函數(Closure)

$route=[

  ''=>'Index',

  'blog'=>'BlogController@Show',

  'blog/{id}/{name}'=>'BlogController@Show',

  'f'=>function(){echo 'hello';}

]; 

這里的route[f]是一個匿名函數,并不是一個控制器類的方法,所以,我們要把上一節(jié)路由代碼做一下修改:

if(isset($route[$key])){

  if($route[$key] instanceof Closure){

    $route[$key]();

  }

  else{

    $arr=explode('@', $route[$key]);  

    $controller=new $arr[0];

    $action=$arr[1];  

    if(isset($parameters)){

      $controller->$action($parameters);

    }

    else{

      $controller->$action();

    }

  }

}

else{

  require 'error.html.php';

}

方案2:使用控制器

每一次都require一個html頁面是一件很不優(yōu)雅的事情,所以我們寫一個render函數

function render($path,array $args){

  extract($args);

  require($path);

}

接上一篇博客,我們知道每個URI對應了一個方法,但是我們常常遇到這樣的問題:

<?php 

 

class Controller{

  public function __call($method,$args){

    echo 'has not this function'.$method;

  }

}

 

class IndexController extends Controller{

  public function Index(){

    echo __CLASS__;

    for($i=1;$i<=20;++$i){

      $data[$i]='content';

    }

 

    render('template.html.php',['data'=>$data]);

  }

}

 

class BlogController extends Controller{

  public function Show(){

    echo __CLASS__;

    for($i=1;$i<=10;++$i){

      $data[$i]='blog';

    }

    render('template.html.php',['data'=>$data]);

  }

}

 

?>

用不用控制器,取決于你的業(yè)務復雜度。個人建議使用控制器,但是對于業(yè)務很簡單的頁面跳轉或檢查,可以直接寫在一個匿名函數里。

控制器里寫些什么?

我們也許寫過這樣的代碼:

class IndexController extends Controller{

  public function Index($content){

    return '<html><head></head><body>'.$content.'</body></html>';

  }

}

這樣把界面的代碼嵌入的寫法是非常難以維護的,也是很多開發(fā)人員(包括我)最厭惡的寫法,因為這種寫法并沒有做好界面與業(yè)務邏輯的分離,所以我們需要使用視圖。

<html>

  <head>

   

  </head>

   

  <body>

    <?php foreach($data as $key=>$value){ ?>  

      <div>

        <?php echo $key.':'.$value; ?>  

      </div>

    <?php } ?>

  </body>

</html>

每一次調用控制器的某個方法時,render函數都會把參數以關聯數組的形式傳入,做到“業(yè)務邏輯”和“表現”的淺層次分離,但是這種分離還不是最好的,因為前端開發(fā)人員仍然需要面對甚至處理PHP代碼,后端開發(fā)人員也有和前端人員溝通的成本,所以后面某一節(jié),會再談一種更好的分離方式。

相關文章

  • php多進程中的阻塞與非阻塞操作實例分析

    php多進程中的阻塞與非阻塞操作實例分析

    這篇文章主要介紹了php多進程中的阻塞與非阻塞操作,結合實例形式分析了php多進程中的阻塞與非阻塞原理、阻塞控制方法與相關操作技巧,需要的朋友可以參考下
    2020-03-03
  • php代碼收集表單內容并寫入文件的代碼

    php代碼收集表單內容并寫入文件的代碼

    前兩天,一朋友讓我?guī)退麑懸粋€收集表單內容并寫入文件的簡單PHP代碼,由于最近工作忙,也沒有時間來寫,今天終于抽出點時間來完成了這個任務,下面就把相關的代碼開源出來,供大家參考
    2012-01-01
  • php讀取出一個文件夾及其子文件夾下所有文件的方法示例

    php讀取出一個文件夾及其子文件夾下所有文件的方法示例

    這篇文章主要介紹了php讀取出一個文件夾及其子文件夾下所有文件的方法,涉及php遞歸及文件路徑相關操作技巧,需要的朋友可以參考下
    2017-06-06
  • 淺談PHP中常用的3種設計模式

    淺談PHP中常用的3種設計模式

    設計模式是針對軟件開發(fā)中出現的常見問題的可重用解決方案,在本文中,我們將探討在PHP開發(fā)中廣泛使用的三種流行設計模式:單例模式、工廠模式和觀察者模式,文中通過代碼示例介紹的非常詳細,需要的朋友可以參考下
    2023-05-05
  • PHP中常見的密碼處理方式和建議總結

    PHP中常見的密碼處理方式和建議總結

    這篇文章主要給大家介紹了關于PHP中常見的密碼處理方式和建議的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2018-10-10
  • php求斐波那契數的兩種實現方式【遞歸與遞推】

    php求斐波那契數的兩種實現方式【遞歸與遞推】

    這篇文章主要介紹了php求斐波那契數的兩種實現方式,結合實例形式分析了php使用遞歸與遞推算法實現求斐波那契數的相關操作技巧與注意事項,需要的朋友可以參考下
    2019-09-09
  • PHP5各個版本的新功能和新特性總結

    PHP5各個版本的新功能和新特性總結

    因為 PHP 那“集百家之長”的語法,加上社區(qū)氛圍不好,很多人對新版本,新特征并無興趣,本文將會介紹自 PHP5.2 起,直至 PHP5.6 中增加的新特征
    2014-03-03
  • PHP學習 變量使用總結

    PHP學習 變量使用總結

    PHP學習 變量使用總結,學習php的朋友可以參考下。
    2011-03-03
  • PHP實現貨幣換算的方法

    PHP實現貨幣換算的方法

    這篇文章主要介紹了PHP實現貨幣換算的方法,以實例形式較為詳細的講述了貨幣轉換的實現方法,并舉英鎊轉換美元為例講述具體用法,需要的朋友可以參考下
    2014-11-11
  • php輸出xml必須header的解決方法

    php輸出xml必須header的解決方法

    這篇文章主要介紹了php輸出xml必須header的解決方法,以實例形式講述了php輸出xml必須header的情況,是很多php初學者都容易犯的錯誤,需要的朋友可以參考下
    2014-10-10

最新評論