## 用戶自定義
本章講介紹一些開發過程中常用需要自定義的東西。
### 一、自定義404頁面
一般比較完整的站點,都會有自定義的404頁面,既美觀統一、又能保持訪問者不至于因為錯誤頁面而退出網站。
> 比如說duowan.com的404頁面,是一個坦克大戰的小游戲,可以在線玩并且成績還會進入排行榜,和其他網友一較高下。
**對404錯誤頁面的建議:**
- 建議不要使用PHP動態頁面,純HTML頁面會比較好。
- 具特色,但不能過于復雜的頁面,保存頁面可以快速載入和有鮮明的提示。
- 通常會進行一些引導,作為“找不到頁面”的補充,但建議不要過多。
在sp框架中,自定義自己程序的404頁面,也是很簡單的事情。
打開protected/controller/BaseController.php,在BaseController類中,加入以下方法:
public static function err404($module, $controller, $action){
header("HTTP/1.0 404 Not Found");
exit;
}
當你訪問到一個不存在的controller/action的時候,就會出現http 404的提示了。
當然你還可以做得更漂亮一點,比如說做個叫404.html的頁面,放在模板目錄里面。然后修改一下上面的err404()方法:
public static function err404($module, $controller, $action){
header("HTTP/1.0 404 Not Found");
$controlObj = new Controller;
$controlObj->display("404.html");
exit;
}
現在你就可以在404的時候顯示你的404.html頁面了。
> 這里不建議去掉header函數輸出的404頭,因為這樣才比較符合一個404頁面的規范,并且搜索引擎以及內容分發網絡(CDN)等都不會誤會成一個普通的頁面(只是頁面上寫著404),從而引發一些沒必要的問題。
> 另外exit也最好保留,因為404之后你就不需要再執行下去了。
### 二、全局位置
在后面準備講自定義類庫和自定義函數庫的知識之前,我們最好能來了解一下關于程序的全局位置。
全局位置的作用一般是:
- 定義常量:定義在整個程序中使用到的靜態常量,如路徑的定義、數值的定義等。
- 載入文件:載入全局都要使用的類庫/函數庫php文件
- 執行某些代碼:如進行應用程序配置的合并、執行全局函數,GZIP壓縮或輸出處理等。
- 全局性的預操作,如權限控制,菜單構造、全局跳轉等。
在新版的sp框架里面,全局位置更為單一,因為我們認為全局位置就是一個控制專用的位置,所以它必須處在控制器的范疇內。
新版中我們加入了BaseController這個自帶的用戶類,它的位置剛好在Controller控制器父類和用戶自定義控制器的繼承鏈之間。這樣使得BaseController既有普通的Controller的功能,也能覆蓋到全部用戶控制器之前進行操作。所以BaseController是比較適合當做全局位置的地方。
BaseController有一個初始化執行的方法,名為init(),它會在BaseController構造函數內執行,所以進入控制器后最先執行的位置。
**全局定于和全局操作,就可以放在BaseController/init()里面執行。**
> 對比來說,新版的init()和舊版直接使用控制器父類的構造函數,差別并不大。但是直接使用構造函數還是會不太優雅,所以新版加入了init()方法來代替。
### 三、自定義類庫
在之前的快速入門教程中,我們已經講述過,新版sp框架里面,自定義的類庫實際上跟Model模型類一樣,只要滿足以下條件,都可以直接通過new語法來實例化:
- 類名和類文件名一致,當然也必須是大小寫一致才行。
- 類文件放在protected下面的model、include、controller之一的目錄內。
### 四、自定義函數庫
用戶自定義的函數,一般都是比較實用并且經常用到的一些函數集合,如加解密、分片下載、美化時間等函數。
所以我們一般會建議自定義的函數都放到一個函數庫文件里面,在“全局位置”中引入該文件(如BaseController的init()函數),這樣就在程序的大部分地方都可以輕松調用了——包括新版的模板引擎內。
> 是的,新版的模板引擎,已經不再需要“注冊函數”才能在模板里面用函數了。
這里舉個例子,我們為程序引入一個叫mydate()的函數。
<?php
// mydate函數
function mydate($time = null){
if( null == $time )$time = time(); // 默認是當前時間
if( $time > (time() - 3600) ){
return "剛才";
}elseif( $time > (time() - 3600 * 24) ){
return "今天";
}elseif( $time > (time() - 3600 * 24 * 2) ){
return "昨天";
}elseif( $time > (time() - 3600 * 24 * 3) ){
return "前天";
}else{
return date("Y-m-d H:s", $time);
}
}
?>
將以上代碼保存到protected/include/functions.php里面。
> functions.php文件和include目錄都是不存在的,需要自行創建。
然后在BaseController的init()函數內,將它包含進來:
<?php
class BaseController extends Controller{
function init(){
require(APP_DIR.'/protected/include/functions.php');
}
}
?>
那么,在程序的控制器以及模板內,都可以正常使用mydate()函數了。
- 自述
- 一、入門教程
- 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. 多數據庫、主從庫配置