首頁  >  文章  >  後端開發  >  PHP路由實作原理,求指教

PHP路由實作原理,求指教

WBOY
WBOY原創
2016-12-01 00:56:231685瀏覽

用了一段時間框架才恍然大悟,貌似MVC框架的核心在於路由,請各位大俠指教下具體原理,例如TP5的路由就很強大,但源碼基本沒註釋看了2小時,楞是沒整明白整個流程是怎麼樣的。

我現在能做到的只有pathinfo這一步,後面的各種規則路由、正則路由就看不懂了,希望你能給我一個實現流程,或者俱體demo、在或則教程,能有相關書籍也可以O(∩_∩)O謝謝!

回覆內容:

用了一段時間框架才恍然大悟,貌似MVC框架的核心在於路由,請各位大俠指教下具體原理,例如TP5的路由就很強大,但源碼基本沒註釋看了2小時,楞是沒整明白整個流程是怎麼樣的。

我現在能做到的只有pathinfo這一步,後面的各種規則路由、正則路由就看不懂了,希望你能給我一個實現流程,或者俱體demo、在或則教程,能有相關書籍也可以O(∩_∩)O謝謝!

閱讀別人的程式碼除了硬讀, 更好的方式是開調試器(如xdebug)走單步調試, 一方面你有來自於調試器的信息, 另一方面有你自己的實際的可以跑起來的用例(你寫的測試用的程式碼), 能夠更方便你理解

回到路由這個話題, 說到底你其實只要想明白怎麼拆分解析pathinfo就可以了, 直接根據pathinfo映射到namespace還是通過正則表達式映射到某個controller都只是其中的一個解析方式罷了

如果如果要試著造輪子的話, 你可以試著實現一個最簡單的直接映射到namespace下面的class的方法的

hello/world -> HelloController->world()

test/hello/world -> testHelloController->world()

路由解析出來之後是分發, 這塊可以去了解反射, Closure等等相關的知識

最後, github上有很多只實現router的組件可以找到, 比起整體框架, 你也可以選擇只讀那些組件的代碼 (實際使用可以通過composer引入你的項目)

例如:

  • https://github.com/nikic/Fast...

  • https://github.com/dannyvanko...

  • https://github.com/mrjgreen/p...

給你推薦一個路由實作

https://github.com/bephp/router

  1. 程式碼很短,約100行

  2. 支援get,post等方式定義路由,只要是callable的都能行。

  3. 除了符合pathinfo裡面的參數意以外,還會透過反射自動取得參數.(這個特性比較有用)

  4. 使用樹形結構儲存路由映射表,比常用的幾個路由效能好(有beachmark)

  5. 支援“編譯”,相當於快取路由表,取得更快效能

  6. 可以使用composer安裝,零依賴

當然,還有更簡單直接的

<code>class R{function($r,$c){$this->r[$r]=$c;} function($r){$this->r[$r]();}}
$r=new R;
$r->a('/', function(){echo 'hello world';});
$r->e('/');
</code>

MVC的核心思想是分離介面和邏輯,個人認為跟前端路由沒什麼關係,前端路由只不過是為了統一入口.

不要把問題想得太複雜,其實就是提取出字串,然後套數組,其實就是一行程式碼的事.

<code><?php
$_SERVER['REQUEST_URI'] = '/post/edit/1024?foo=bar';
$uri = explode('/', parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH));
var_export($uri);
//输出
array (
  0 => '',
  1 => 'post', //控制器(控制器存在就require)
  2 => 'edit', //方法
  3 => '1024', //参数(获取参数foo就用传统的$_GET['foo'])
)

$class = $uri[1];
require 'controller/'.$class.'.php'; // controller/post.php
$object = new $class();
$action = $uri[2];
$parameter = $uri[3];
echo call_user_func_array(array($object, $action), array($parameter)); //调用对象里的方法并传参

controller/post.php:
class post {
    public function edit($id) {
        return '$'.__CLASS__.'->'.__FUNCTION__.'('.$id.')'; //输出 $post->edit(1024)
    }
}</code>

這個 最近自己在寫了一個小框架 路由的實作我裡面寫的比較簡單,我覺得看看還是可以的。
位址:https://github.com/zhoujiangy...
core資料夾下面的route就是路由實作類別

基本想法是瀏覽器端透過URL字串提供控制器類別的名字和方法的名字,PHP據此找到對應的類別和方法。

具體demo代碼可猛戳這裡,http://www.jianshu.com/p/d4ce...

可以嘗試看看ci的路由,多種匹配模式,是利用了迭代器模式,迭代自訂的路由,迭代出能符合SERVER['REQUEST_URI']中匹配的值,即取出控制器和方法,在使用new 類別->方法或call_user_func()的方式呼叫對應的方法;

花錢去看雲買教學吧,官方出了路由詳細說明

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