記錄下thinkphp5自定義底層基類、內部類函數使用筆記 大部分筆記來自tp手冊。php
在控制器中基類的起着相當重要的做用,整個項目的代碼安全,複雜程度,易讀性都要看你項目的基類架構的.html
好比api中都須要某一個功能函數,咱們就能夠寫在基類裏。ajax
貼上一個基類返回錯誤碼的例子:thinkphp
<?php
namespace app\member\controller; class Base extends \app\base\controller\Base { static public function showReturnCode($code = '', $data = [], $msg = '') { $return_data = [ 'code' => '500', 'msg' => '未定義消息', 'data' => $code == 1001 ? $data : [], ]; if (empty($code)) return $return_data; $return_data['code'] = $code; if(!empty($msg)){ $return_data['msg'] = $msg; }else if (isset(ReturnCode::$return_code[$code]) ) { $return_data['msg'] = ReturnCode::$return_code[$code]; } return $return_data; } static public function showReturnCodeWithOutData($code = '', $msg = '') { return self::showReturnCode($code,[],$msg); } }
基類:數據庫
<?php namespace app\base\controller; class ReturnCode { static public $return_code = [ '1001' => '操做成功', '1002' => '你想作什麼呢', //非法的請求方式 非ajax '1003' => '請求參數錯誤', //如參數不完整,類型不正確 '1004' => '請先登錄再訪問', //未登陸 或者 未受權 '1005' => '請求受權不符', ////非法的請求 無受權查看 '1006' => '數據加載失敗', // '1010' => '數據不存在', // '1020' => '驗證碼輸入不正確', // '1021' => '用戶帳號或密碼錯誤', // '1022' => '用戶帳號被禁用', // '1030' => '數據操做失敗', // ]; }
而後就能夠調用了json
private function getUid(){ //數據庫字段 網頁字段轉換 $param = [ 'userid' => 'userid', 'userpwd' => 'userpwd', 'mobile' => 'mobile', ]; $param_data = $this->buildParam($param); if (empty($param_data['userid'])&&empty($param_data['mobile'])) return self::showReturnCodeWithOutData(1003); $check_login = $this->doModelAction($param_data, 'base/Member.login', 'base/Member', 'checkLogin'); if (!isset($check_login['code'])) $this->showReturnCodeWithSaveLog(1111); if ($check_login['code'] == 1001) { } return $check_login; }
構造函數 在類的初始化時候執行的一個方法,構造函數中不要使用return關鍵詞。api
那麼咱們常常在構造函數裏面作作什麼呢?瀏覽器
咱們看一下TP5 控制器的構造函數,他在初始化時候注入了request對象,咱們繼承了控制器,直接就可使用$this->request調用,同時也封裝了View類.同時對前置的beforeActionList屬性的方法 進行處理.安全
public function __construct(Request $request = null) { if (is_null($request)) { $request = Request::instance(); } $this->view = View::instance(Config::get('template'), Config::get('view_replace_str')); $this->request = $request; // 控制器初始化 $this->_initialize(); // 前置操做方法 if ($this->beforeActionList) { foreach ($this->beforeActionList as $method => $options) { is_numeric($method) ? $this->beforeAction($options) : $this->beforeAction($method, $options); } } }
對於權限判斷的例子:微信
public function _initialize() { parent::_initialize(); // TODO: Change the autogenerated stub $user_agent = $this->request->server('HTTP_USER_AGENT'); if (! strpos($user_agent, 'MicroMessenger') === false ) $this->isWechatBrowser = true; //判斷提交方式和是否微信瀏覽器 if ($this->request->method() == 'GET' && $this->isWechatBrowser === true){ //未登陸 從新登陸 if (!$this->checkAuth()&& !$this->no_login ) $this->wxoauth(); $this->isLogin=true; //設置全局登陸 $this->loginGlobal(); if(!$this->isReg){ if(!$this->checkUuidMobile()) $this->redirect('user/user_blind.html'); } } }
控制起來繼承:
<?php namespace app\api\controller; class WxpayAction extends Auth { public function _initialize() { config('default_return_type','html'); parent::_initialize(); // TODO: Change the autogenerated stub } public function index($order_no='2017020453102495'){ if(!$this->isWechatBrowser){ //******* 爲了演示方便 這裏省略了訂單的是否支付驗證 另外 微信支付自己就有支付重複驗證 這裏並無加入樂觀鎖過濾 //******* $data=controller('base/WxPay')->payByOrderNo($order_no); $assign_data=[ 'title'=>'爲了家健康--訂單支付', 'amount'=>$data['amount'], 'order_no'=>$order_no, "jsApiParameters" =>$data['jsApiParameters'], 'openid'=>$this->open_id, 'data_md5'=>md5($order_no.$this->open_id.$data['amount']), //md5驗證( 訂單號 openid 金額) ]; $this->assign($assign_data); return $this->fetch('wxpay/index'); } public function showOrdersPayOk($order_no,$order_amount,$data_md5){ //md5驗證( 訂單號 openid 金額) if (md5($order_no.$this->open_id.$order_amount)<>$data_md5){ $assign_data=[ 'title'=>'爲了家健康--支付出錯了', 'content'=>'你要支付的訂單號不存在請覈對後再支付!', ]; $this->assign($assign_data); return $this->fetch('wxpay/err'); }else{ $assign_data=[ 'title'=>'爲了家健康--該訂單已經支付成功', 'amount'=>$order_amount, 'order_no'=>$order_no, ]; $this->assign($assign_data); return $this->fetch('wxpay/ok'); } } public function jsSign($url=''){ $url= $url ? : $this->request->server('HTTP_REFERER'); return json(controller('base/WxApi')->getJsSign($url)); }
析構函數就是一個收尾的一個方法,
例子:建立一個虛擬基類
<?php namespace app\base\controller; use think\Cache; use think\Controller; use think\Session; use think\Loader; abstract class Base extends Controller { protected $error; //出錯時候的記錄 protected $log=[]; //要保存的記錄 protected $saveLog = false ; static public function showReturnCode($code = '', $data = [], $msg = '') { $return_data = [ 'code' => '500', 'msg' => '未定義消息', 'data' => $code == 1001 ? $data : [], ]; if (empty($code)) return $return_data; $return_data['code'] = $code; if(!empty($msg)){ $return_data['msg'] = $msg; }else if (isset(ReturnCode::$return_code[$code]) ) { $return_data['msg'] = ReturnCode::$return_code[$code]; } return $return_data; } protected function addLog($code='',$msg=''){ $this->log[] =[ 'uuid' => $this->uuid, 'url' => $this->request->url(true), 'method' => $this->request->method(), 'data' => $this->getData(), 'ip' => $this->request->ip(), 'code'=>$code, 'desc' => $msg, ]; } protected function toSaveLog(){ $this->saveLog = true ; $this->addLog(); } protected function showReturnCodeWithSaveLog($code = '', $data = [], $msg = ''){ $this->saveLog = true ; $this->addLog($code,$msg); return self::showReturnCode($code, $data, $msg); } protected function getData(){ if ($this->request->isPost()){ return $this->request->post(); }else{ return $this->request->get(); } } protected function saveLogAction(){ if (!empty($this->log)){ foreach($this->log as $value){ dump($value); } } } public function __destruct() { // TODO: Implement __destruct() method. //記錄日誌 if (!empty($this->log) && $this->saveLog == true){ $this->saveLogAction(); } } }
控制器繼承:
<?php namespace app\member\controller; use app\base\model\Member; use think\Cache; use think\Db; class Test extends Base { public function index(){ return $this->showReturnCodeWithSaveLog(1001,'演示析構函數成功了'); } }