php實作簡單的偽靜態URL的機制介紹

WBOY
發布: 2016-07-25 09:05:30
原創
1271 人瀏覽過
關於路由設定檔的解析,主要細節全在類RoutePattern中,關於RoutePattern中對規則的解析、URL匹配和轉換URL細節,篇幅和精力有限,今天就不詳細介紹了,下回再仔細分析。
  1. RewriteEngine On
  2. RewriteRule ^index.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-d
  3. RewriteRule (.+) index.php/$1 [L]
複製程式碼 >

上面的程式碼就是將URL結構導入index.php中,具體的rewrite細節就不贅述了。

2.在PHP中設定一個路由規則設定檔routes.php,我簡單的使用了一個hash數組編寫規則:

    /**
  1. *路由設定檔編寫說明:
  2. * 路由配置在一個array數組中,一條記錄代表一個規則
  3. * 其中數組key的資料代表匹配的路徑格式:使用特定的字串標識如: '/{id}'
  4. * 字串中可以包含特定的變量,所有變數使用大括號{}包裹起來
  5. * 數組value裡是一個array數組,是對key中路徑中變量進行特定處理
  6. * 變數寫在陣列的key中,規格寫在陣列的value裡,如:array('id'=>'/d+/','_m'=>'frontpage','_a'=>' index')
  7. * 規格分成兩類:
  8. * 1.格式判斷:例如'/{id}'=> array('id'=>'/d+/','_m'=>'frontpage ','_a'=>'index') 為例,其中'id'=>'/d+/'就是一個格式判斷,
  9. * 表示id變數只能是數字,格式判斷後面只能用正規表達式,由於PHP沒有正規類,所以我指定'/XXX/'和'#XXX#'格式的字串為正規表示式
  10. * 2.預設參數:例如'/{id}'=> array( 'id'=>'/d+/','_m'=>'frontpage','_a'=>'index') 為例,其中'_m'=>'frontpage'就是一個預設參數,
  11. *因為前面的路徑沒有_m和_a訊息,所以後面會使用預設參數作為_m和_a的值
  12. *
  13. * 所以對於規則'/{id}'=> array('id' =>'/d+/','_m'=>'frontpage','_a'=>'index')。我傳入/3 系統會轉換成index.php?_m=frontpage&_a=index&id=3
  14. *
  15. * 規則匹配是按照$routes數組的順序逐一匹配,一旦匹配上了就不往下匹配了。所以一些特定的匹配規則要放在前面,通用的放在後面。
  16. * 否則可能導致不執行特定的匹配規則了
  17. */
  18. $routes= array(
  19. '/' => array('_m'=>' wp_frontpage','_a'=>'index'),
  20. '/{id}'=> array('id'=>'/d+/','_m'=>'wp_frontpage','_a'= >'index'),
  21. '/{_m}/{_a}/{id}'=> array('id'=>'/d+/'),
  22. '/{_m}/{_a }'=> array()
  23. );
複製程式碼

3.路由機制中最複雜也是最重要的一部分,就是解析器。 解析器有兩個類別組成(名字可能起的不佳)。 一個是Route,作為整個解析器對外的接口,用於解析規則,匹配和轉換URL,然而它只是一個代理,實際操作不是直接由它直接做的。 一個是RoutePattern,每個RoutePattern實例對應規則數組中的一筆記錄,一個Route實例包含多個RoutePattern,而Route中的所有操作都會呼叫內部所有RoutePattern實例操作,並進行整合。

  1. class Route
  2. {
  3. private static $instance = null;
  4. private $routepatterns=array()
  5. private function __construct()
  6. {
  7. $routes = array();
  8. include ROOT."/routes.php";
  9. foreach($routes as $key=>$value){
  10. $this->routepatterns[]=new RoutePattern($key,$value);
  11. }
  12. if(!isset($_SERVER['PATH_INFO'])) return false
  13. ; $urlpath= $_SERVER['PATH_INFO'];
  14. $ismatch=$this->match_url($urlpath);
  15. $strip_urlpath=str_replace('/','',$urlpath);
  16. ifpath=str_replace('/','',$urlpath);
  17. if (!$ismatch&&!emptyempty($strip_urlpath)){
  18. Content::redirect(PAGE_404);
  19. }
  20. }
  21. /**
  22. * 用路由規則來匹配對應的url位址,匹配成功將對應url參數放入$_GET中
  23. * @param string url位址
  24. * @return bool 是否符合成功
  25. / public ftion🎜> match_url($urlpath){
  26. foreach($this->routepatterns as $router){
  27. $urlargs=$router->match_url($urlpath);
  28. if($urlargs!==false){
  29. $_GET=array_merge($urlargs,$_GET);
  30. return true;
  31. }
  32. }
  33. return false;
  34. }
  35. publicrite false;
  36. }
  37. publicrite rew_$ urlparams){
  38. foreach($this->routepatterns as $router){
  39. $urlstr=$router->rewrite_url($urlparams);
  40. if($urlstr!==false){
  41. return $urlstr;
  42. }
  43. }
  44. $actualparams=array();
  45. foreach($urlparams as $arg=>$val){
  46. $actualparams[]=$arg." =".urlencode($val);
  47. }
  48. $actualparamstr=implode('&', $actualparams);
  49. $rewriteurl="/index.php";
  50. if(!emptyempty( $rewriteurl))$rewriteurl.="?{$actualparamstr}";
  51. return $rewriteurl;
  52. }
  53. public static function init()
  54. {
  55. if (null = = self::$instance) {
  56. self::$instance = new Route();
  57. }
  58. return self::$instance;
  59. }
  60. }
class RoutePattern{
//...... }

複製程式碼



來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!