- ThinkPHP實戰
- 夏磊
- 1205字
- 2020-11-28 18:26:52
3.2 ThinkPHP的路由
3.2.1 路由模式
ThinkPHP的路由支持以下四種模式:
● 普通模式
● pathinfo模式
● rewrite模式
● 兼容模式
接下來通過一個具體的場景來分析這四種路由模式,假設用戶訪問Home模塊的Index控制器的index方法,這四種模式下的URL如下:
● 普通模式:http://www.example.com/index.php? m=home&c=index&a=index
● pathinfo模式:http://www.example.com/index.php/home/index/index
● rewrite模式:http://www.example.com/home/index/index
● 兼容模式:http://www.example.com/index.php? s=home/index/index
可以看到普通模式和兼容模式可以歸類到動態URL中,pathinfo和rewrite模式可以歸類到偽靜態模式中。rewrite模式和pathinfo模式的區別在于前者沒有index.php,有HTTP基礎的讀者可能有些不理解,如果按照靜態頁面的處理方式,rewrite模式下Web服務器會前往Web目錄下的home/index/index查找默認首頁,如果存在則發送給瀏覽器,否則發送404錯誤頁面。
接下來可以進行測試,觀察這四種URL在瀏覽器中的實際情況,請將www.example.com替換為相應的Web目錄(筆者的為http://localhost/thinkphp-inaction)。
在Web目錄下新建文件夾chapter-3,按照第2章的方法新建入口文件,并且在瀏覽器訪問使ThinkPHP初始化。
編輯Application/Home/Controller/IndexController.class.php,內容如下:
<? php namespace Home\Controller; use Think\Controller; class IndexController extends Controller { public function index() { echo 1; } }
文件內容很簡單,只要瀏覽器輸出“1”證明訪問home/index/index成功。打開瀏覽器分別測試普通模式(見圖3-1)、pathinfo模式(見圖3-2)和rewrite模式(見圖3-3)。

圖3-1

圖3-2

圖3-3
可以看到,rewrite模式下,已經訪問不到home/index/index了,觀察URL發現,Web服務器在home/index/index目錄下查找默認文件了。這時候就需要對Web服務器進行URL重寫設置。
在chapter-3下級目錄新建文件“.htaccess”,文件無名稱,擴展名為“htaccess”,該文件為Apache服務器的分布式配置文件(通俗點說,就是每個站點可以單獨設置,互不影響),文件結構如圖3-4所示。

圖3-4
文件內容如下:
RewriteEngine on RewriteCond %{REQUEST_FILENAME} ! -d RewriteCond %{REQUEST_FILENAME} ! -f RewriteRule ^(.*)$ index.php/$1 [L]
文件第1行:打開重寫引擎。
文件第2行和第3行:如果請求文件不是目錄而且不是文件(證明服務器上沒有該請求文件或請求目錄)。
文件第4行:將所有請求重定向到當前目錄下的index.php文件,“L”代表如果該規則成功處理,則不繼續處理下一條規則。
以http://localhost/thinkphp-inaction/chapter-3/home/index/index為例,由于服務器上并不存在home/index/index目錄,故Apache將請求參數“/home/index/index”全部傳給chapter-3/index.php文件處理。
打開瀏覽器刷新,可以看到如圖3-5所示界面。

圖3-5
最后則是兼容模式的測試,結果如圖3-6所示。

圖3-6
3.2.2 路由配置
要使用ThinkPHP的路由功能,只要Web服務器支持除普通模式外的任何一種模式即可,前提是在公共(或模塊)配置文件中啟用路由功能。
編輯Application/Common/Conf/config.php,內容如下:
<? php /** * config.php */ return array( 'URL_ROUTER_ON' => true );
接下來就是配置路由規則了,在模塊的配置文件中使用URL_ROUTE_RULES參數進行配置,配置格式為數組,一個元素就是一個路由規則,編輯Application/Home/Conf/config.php,內容如下:
<? php /** * config.php */ return array( 'URL_ROUTE_RULES' => array( 'posts/:year/:month/:day' => 'Index/index', 'posts/:id' => 'Index/index', 'posts/read/:id' => '/posts/:1', ), );
打開瀏覽器訪問http://localhost/thinkphp-inaction/chapter-3/home/posts/2015/01/01,結果如圖3-7所示。

圖3-7
ThinkPHP已經將請求地址路由到Application/Home/Controller/IndexController.class.php的index方法中去了。
為了測試一下路由圖3-7的結果是否是ThinkPHP路由導致的,編輯Application/Common/Conf/config.php文件,內容如下:
<? php /** * config.php */ return array( 'URL_ROUTER_ON' => false );
刷新瀏覽器,可以看到如圖3-8所示結果。

圖3-8
路由定義的一般規則是:“路由表達式”=>“路由地址和參數”或者array(“路由表達式”,“路由地址”,“傳入參數”)。
“路由表達式”指“以何種規則”匹配瀏覽器中的地址,如果匹配成功,系統將在處理請求的同時把“傳入參數”(如果有配置)傳給指定的動作。
ThinkPHP的路由規則采用順序遍歷方式進行,只要成功匹配一條匹配的路由,則終止繼續匹配。
路由表達式支持規則路由、正則路由、靜態路由。
1.規則路由
'posts/:year/:month/:day' => 'Index/index',是一個典型的規則路由,通過“:”進行參數匹配,如果匹配成功,則將該位置的參數傳給指定的動作。
編輯Application/Common/Conf/config.php文件,將“false”更改為“true”,編輯Application/Home/Controller/IndexController.class.php,內容如下:
<? php namespace Home\Controller; use Think\Controller; class IndexController extends Controller { public function index() { echo "year:".$_GET['year'].", month:".$_GET['month'].",day:".$_GET['day']; } }
刷新瀏覽器,可以看到如圖3-9所示結果。

圖3-9
ThinkPHP已經將URL地址中的各項參數傳給相應的動作,如果是未啟用路由的狀態,需要獲取year、month、day參數就必須訪問形如http://localhost/thinkphp-inaction/chapter-3/index.php? year=2015&month=01&day=01這樣的URL才可以。
2.正則路由
顧名思義,正則路由就是利用正則表達式進行“路由表達式”配置,至于正則表達式相關知識,讀者可以在網上參考相關資料。
編輯Application/Home/Conf/config.php,內容如下:
<? php /** * config.php */ return array( 'URL_ROUTE_RULES' => array( '/^posts\/(\d{4})\/(\d{2})\/(\d{2})$/' =>'Index/index? year=:1&month=:2&day=1', 'posts/:year/:month/:day' => 'Index/index', 'posts/:id' => 'Index/index', 'posts/read/:id' => '/posts/:1', ), );
請注意:正則路由的最后一個“1”前面沒有“:”,固只要URL匹配成功,day參數永遠為1。
刷新瀏覽器,可以看到如圖3-10所示的結果。

圖3-10
正則路由匹配成功,所以day為1;如果正則路由匹配失敗,瀏覽器將輸出12。
接下來將瀏覽器地址欄URL改為http://localhost/thinkphp-inaction/chapter-3/home/posts/2015/01/010,刷新瀏覽器,可以看到如圖3-11所示的結果。

圖3-11
可以看到輸出的day為“121”,證明ThinkPHP匹配到了第二條路由,這就是正則路由的優勢,最嚴格的匹配模式,路由配置中正則表達式的最后一個子模式為“(\d{2})”,該正則只匹配兩位數字,而請求的URL地址中最后一個參數為3位數字,固正則路由匹配失敗,系統使用規則路由。
3.靜態路由
靜態路由定義中不包含任何動態參數,也不需要遍歷路由規則,所以路由效果比前兩者高,為了區分前兩種路由規則,靜態路由采用URL_MAP_RULES進行定義。
編輯Application/Home/Conf/config.php,內容如下:
<? php /** * config.php */ return array( 'URL_ROUTE_RULES' => array( '/^posts\/(\d{4})\/(\d{2})\/(\d{2})$/' => 'Index/index? year=:1&month=:2&day=1', 'posts/:year/:month/:day' => 'Index/index', 'posts/:id' => 'Index/index', 'posts/read/:id' => '/posts/:1', ), 'URL_MAP_RULES' => array( 'site/welcome' => 'Index/index? from=seo' ) );
編輯Application/Home/Controller/IndexController.class.php,內容如下:
<? php namespace Home\Controller; use Think\Controller; class IndexController extends Controller { public function index() { echo $_GET['from']; } }
在瀏覽器中訪問http://localhost/thinkphp-inaction/chapter-3/home/site/welcome,可以看到如圖3-12所示結果。

圖3-12
- C語言程序設計習題解析與上機指導(第4版)
- Oracle Database In-Memory(架構與實踐)
- MongoDB for Java Developers
- C語言程序設計教程(第2版)
- Architecting the Industrial Internet
- ASP.NET動態網頁設計教程(第三版)
- Production Ready OpenStack:Recipes for Successful Environments
- Banana Pi Cookbook
- 手把手教你學C語言
- ADI DSP應用技術集錦
- Oracle JDeveloper 11gR2 Cookbook
- 小學生C++創意編程(視頻教學版)
- INSTANT Yii 1.1 Application Development Starter
- Azure Serverless Computing Cookbook
- HTML+CSS+JavaScript網頁制作:從入門到精通(第4版)