## 偽靜態配置及URL跳轉
本章我們會講解偽靜態的配置,還有URL構造的方法等相關內容。
> 新版的sp框架,偽靜態功能是內置支持的。
### 一、特色
在不到80行代碼里面,實現了功能強大的php偽靜態路由功能。(包括偽靜態路由和url產生)
精簡的代碼帶來非常高的執行效率,對比舊版的UrlRewrite擴展速度上有三倍的提升。
> 當然,舊版框架對比其他大型PHP框架的偽靜態已經非常輕量級和快速了。
- 支持moduels多模塊。
- 支持URL和參數定制。
- 支持http開頭的域名適配,對跨站構造URL有良好的支持。
- 支持泛域名適配,如 *.example.com 的適配。
- 規則更簡單,更直觀,更容易配置了。
- 通過url()函數即可構造URL地址。
### 二、服務器配置
一般初學者使用偽靜態時,首先遇到的問題是產生“404找不到頁面”的情況。這情況通常都是因為沒有正確配置服務器的原因。
接下來我們介紹一下較為常見的服務器的偽靜態配置方法。
**Apache**
在默認情況下,sp框架在程序根目錄已經自帶.htaccess文件,該文件在Apache服務器下面是自動加載并且已經完成配置的。
根目錄的.htaccess文件內容是:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]
</IfModule>
注意,有時候我們會發現Apache服務器即使已經有了.htaccess文件,但是還是會發生404的情況,這樣就需要檢查一下Apache本身的配置是否開啟“文件配置”的選項了。
1. 找到httpd.conf文件,一般windows在apache/conf/httpd.conf目錄里面,linux在/etc/httpd/conf/httpd.conf。
2. 打開并且搜索到您的web根目錄配置。如:
<Directory "/var/www/html">
AllowOverride None
</Directory>
改為
<Directory "/var/www/html">
AllowOverride All
</Directory>
主要是修改AllowOverride的值,AllowOverride意思是:是否能通過.htaccess文件配置來覆蓋httpd.conf的配置。
3. 檢查以下語句前面有沒有#號,有的話去掉#。如果無法找到該行配置,則在httpd.conf文件最后增加。
LoadModule rewrite_module modules/mod_rewrite.so
4. 重啟Apache即可。
**Nginx**
Nginx現在非常流行,大多數時候已經替代了Apache的地位。
Nginx需要配置當前站點的配置文件,如下:
location / {
if (!-e $request_filename){
rewrite (.*) /index.php;
}
}
location ^~ /protected {
deny all;
}
> 一般當前站點的配置文件會存儲在/etc/nginx/sites-available/目錄下面,以站點域名為名稱的conf文件。
**新浪SAE平臺**
config.yaml是SAE的配置文件,以下是偽靜態的實例:
name: speedweb
version: 3
handle:
- rewrite: if (!-d && !-f) goto "/index.php?%{QUERY_STRING}"
- hostaccess: if (%{REQUEST_URI} ~ "/protected/") deny "all"
### 三、框架偽靜態配置
sp框架的偽靜態配置,在protected/config.php文件里面,大概是這樣:
$config = array(
'rewrite' => array(
'admin/index.html' => 'admin/main/index',
'admin/<c>_<a>.html' => 'admin/<c>/<a>',
'<c>/<a>' => '<c>/<a>',
'/' => 'main/index',
),
);
這里rewrite數組,就是我們的偽靜態配置,可以看到,左邊key值是URL地址,而右邊是指向的modules/controller/action(當然沒有modules也行)。
如果需要關閉rewrite,可以設置'rewrite' => null,那么全部URL都會變成原來的“**/index.php?m=模塊&c=控制器&a=方法&參數名=參數值**”的形式。
我們來了解幾個規則,非常簡單:
1. <m><c><a>分別指代modules,controller,action。
2. 其他的<單詞>,都是_GET的參數名稱。
3. **越是明確指向的URL配置,越要放前面。比如說'admin/index.html',要放在'admin/<c>_<a>.html'的前面,因為'admin/index.html'是明確的。而'<c>/<a>'和'/'就被放到最后了**。
4. 如果是'admin/<c>\_<a>.html'和'admin/<c>\_<a>\_<username>.html',那么就應該是'admin/<c>\_<a>\_<username>.html'**在前面**,因為它更明確指向有參數username的地址。
我們來看看各種配置對應表:
類型 | 配置 | 實現URL | 指向控制器/方法(或 模塊/控制器/方法) | GET參數
---|---|---|---|---
固定URL | 'index.html' => 'main/index' | /index.html | main/index | -
固定URL | '123.json' => 'view/number' | /123.json | view/number | -
固定URL | 'admin/index.html' => 'admin/main/index' | /admin/index.html | admin/main/index | -
使用<c>,<a> | '<c>_<a>.html' => '<c>/<a>' | /控制器_方法.html | 控制器/方法 | -
使用<m>,<c>,<a> | '<m>/<c>_<a>.html' => '<m>/<c>/<a>' | /模塊/控制器_方法.html | 模塊/控制器/方法 | -
使用<m>,<c>,<a>,固定部分URL | 'user-<a>.html' => 'user/<a>' | /user-方法.html | user/方法 | -
使用參數 | 'blog-<id>.do' => 'user/blog' | /blog-9527.do | user/blog | arg("id") = 9527
使用參數 | 'admin/user/<username>' => 'admin/user/detail' | /admin/user/jake | admin/user/detail | arg("username") = "jake"
使用參數 | 'u/<uid>/album.html' => 'user/album', | /u/123/album.html | user/album | arg("uid") = 123
使用參數 | 'page-<username>/<tid>' => 'page/view', | /page-jake/10086 | page/view | arg("username") = 'jake',arg("tid") = 10086
泛域名 | 'http://<username>.speedphp.com/' => 'main/index' | http://jake.speedphp.com | main/index | arg("username") = 'jake'
泛域名 | 'http://<shopname>.shop.speedphp.com/article-<id>.html' => 'article/show' | http://ak47.shop.speedphp.com/article-520.html | article/show | arg("shopname") = 'ak47',arg("id") = 520
### 四、URL地址函數
當配置好上述的規則后,我們可以通過url()函數,來生成URL地址。
url()函數有三個參數:$c, $a, $param
1. $c參數是控制器名稱,對應到protected/controller目錄下面的controller類,如果用到modules模塊開發,那么參數值是“模塊名/控制器名”。對應該模塊目錄下的controller類。
2. $a參數是方法名稱。對應controller類里面的,帶action前綴的方法。
3. $param是參數數組,鍵是參數名稱,值是參數值。
**在沒有偽靜態的時候**:
> 不設置偽靜態就是配置:'rewrite' => null
類型 | 控制器內使用url()函數 | 模板內使用 | 顯示結果
---|---|---|---
進入控制器/方法 | url("view", "index"); | <{url c="view" a="index"}> | /index.php?c=view&a=index
進入模塊/控制器/方法 | url("admin/view", "index"); | <{url c="admin/view" a="index"}> | /index.php?m=admin&c=view&a=index
帶參數| url("view", "index", array("page" => 100)); | <{url c="view" a="index" page="100"}> | /index.php?c=view&a=index&page=100
帶參數| url("admin/view", "index", array("page" => 100, "sort" => "desc")); | <{url c="admin/view" a="index" page="100" sort="desc"}> | /index.php?m=admin&c=view&a=index&page=100&sort=desc
**在開啟偽靜態之后**:
開啟偽靜態之后,會根據rewrite配置而定URL的生成方式。
配置 | 控制器內使用url()函數 | 模板內使用 | 顯示結果 | 指向控制器/方法(或 模塊/控制器/方法) | GET參數
---|---|---|---|---|---
'index.html' => 'main/index' | url("main", "index"); | <{url c="main" a="index"}> | /index.html | main/index | -
'123.json' => 'view/number' | url("view", "number"); | <{url c="view" a="number"}> | /123.json | view/number | -
'admin/index.html' => 'admin/main/index' | url("admin/main", "index"); | <{url c="admin/main" a="index"}> | /admin/index.html | admin/main/index | -
'<c>_<a>.html' => '<c>/<a>' | url("mycontrol", "myaction"); | <{url c="mycontrol" a="myaction"}> | /mycontrol_myaction.html | mycontrol/myaction | -
'<m>/<c>_<a>.html' => '<m>/<c>/<a>' | url("mod/mycontrol", "myaction"); | <{url c="mod/mycontrol" a="myaction"}> | /mod/mycontrol_myaction.html | mod/mycontrol/myaction | -
'user-<a>.html' => 'user/<a>'| url("user", "myaction"); | <{url c="user" a="myaction"}> | /user-myaction.html | user/myaction | -
'blog-<id>.do' => 'user/blog'| url("user", "blog", array("id"=>9527)); | <{url c="user" a="blog" id="9527"}> | /blog-9527.do | user/blog | arg("id") = 9527
'blog-<id>.do' => 'user/blog'| url("user", "blog", array("page"=>2, "id"=>9527)); | <{url c="user" a="blog" page="2" id="9527"}> | /blog-9527.do**?page=2** | user/blog | arg("id") = 9527, **arg("page") = 2**
'admin/user/<username>' => 'admin/user/detail'| url("admin/user", "detail", array("username"=>"jake")); | <{url c="admin/user" a="detail" username="jake"}> | /admin/user/jake | admin/user/detail | arg("username") = "jake"
'u/<uid>/album.html' => 'user/album', | url("user", "album", array("uid"=>123)); | <{url c="user" a="album" uid="123"}> |/u/123/album.html | user/album | arg("uid") = 123
'u/<uid>/album.html' => 'user/album', | url("user", "album", array("uid"=>123, "sort"=>"2")); | <{url c="user" a="album" uid="123" sort="2"}> |/u/123/album.html?sort=2 | user/album | arg("uid") = 123, arg("sort") = 2
'page-<username>/<tid>' => 'page/view', | url("page", "view", array("username"=>"jake", "tid"=>"10086")); | <{url c="user" a="album" username="jake" tid="10086"}>| /page-jake/10086 | page/view | arg("username") = 'jake',arg("tid") = 10086
'http://<username>.speedphp.com/' => 'main/index' | url("main", "index", array("username"=>"jake")); | <{url c="main" a="index" username="jake"}> | http://jake.speedphp.com | main/index | arg("username") = 'jake'
'http://<shopname>.shop.speedphp.com/article-<id>.html' =>'article/show'| url("article", "showindex", array("shopname"=>"ak47", "id"=>520)); | <{url c="article" a="show" shopname="ak47" id="520"}> | http://ak47.shop.speedphp.com/article-520.html | article/show | arg("shopname") = 'ak47',arg("id") = 520
'http://<shopname>.shop.speedphp.com/article-<id>.html' =>'article/show'| url("article", "showindex", array("shopname"=>"ak47", "id"=>520, "page"=>2)); | <{url c="article" a="show" shopname="ak47" id="520" page="2"}> | http://ak47.shop.speedphp.com/article-520.html?page=2 | article/show | arg("shopname") = 'ak47',arg("id") = 520, arg("page") = 2
這里注意兩個問題:
1. 比配置多出來的參數,那么會以?參數名=參數值的方式跟在URL后面。上表應該可以看得出來。
2. **如果發現取得的URL不是想要的,可以調整一下rewrite配置規則的前后順序,多幾次調整就會正確,并且找到規律。**
- 自述
- 一、入門教程
- 1. 開始使用SpeedPHP
- 2. Hello World
- 3. 理解MVC
- 4. 制作留言本
- 5. 數據操作及Ajax
- 二、框架概述
- 1. 特色
- 2. 版權及開源協議
- 3. 開發環境
- 4. 編碼版本
- 5. SAE平臺使用
- 三、開發指南
- 1. 開發流程
- 2. 架構及擴展
- 3. 程序目錄結構
- 4. 命名建議
- 5. 安全建議
- 6. 用戶自定義
- 7. 模塊modules
- 四、訪問交互
- 1. 表單提交及數據獲取
- 2. session/cookie的使用
- 3. 偽靜態及URL跳轉
- 4. 使用frameset
- 5. 模板引擎特性和使用方法
- 五、數據操作
- 1. 建立數據模型類
- 2. 數據操作教程
- 3. 分頁
- 4. SQL支持及關聯實現
- 5. 多數據庫、主從庫配置