ThinkPHP 3.2.3 简单后台模块开发(一)常用配置
一、項目分組
下載解壓 ThinkPHP 3.2.3,在默認的應用 Application(./Application) 中,包含一個默認的模塊 Home(./Application/Home)。
需要在該默認應用中創建一個用于后臺管理的 Admin 模塊,可以通過在應用入口文件(./index.php)中綁定 Admin 模塊來?自動生成?Admin 模塊:
define('BIND_MODULE','Admin');此時訪問 http://serverName/index.php 便會自動在 ./Application 下創建 Admin 目錄(要記得把上面的定義?刪掉,否則通過入口文件訪問網站首頁就會默認訪問 Admin 模塊)。
不需要修改入口文件。
此時訪問 http://serverName/index.php/Admin 就可以訪問后臺的 Index 控制器的 index 方法了。
目錄結構如下:
二、應用配置和模塊配置
應用配置(公共配置文件)位于 ./Application/Common/Conf/config.php ,在 ThinkPHP 調用所有的模塊之前加載。
在這里沒有做特別的配置,只開啟了 Trace?追蹤信息:
<?php return array(//'配置項'=>'配置值'//顯示頁面 Trace 信息'SHOW_PAGE_TRACE' => true, );Admin 模塊的模塊配置位于 ./Application/Admin/Common/Conf/config.php
該項目開啟的配置包括:
① 數據庫
//數據庫配置信息'DB_TYPE' => 'mysql', // 數據庫類型'DB_HOST' => '127.0.0.1', // 服務器地址'DB_NAME' => 'tptest', // 數據庫名'DB_USER' => 'root', // 用戶名'DB_PWD' => '', // 密碼'DB_PORT' => 3306, // 端口'DB_PARAMS' => array(), // 數據庫連接參數'DB_PREFIX' => 'crm_', // 數據庫表前綴 'DB_CHARSET'=> 'utf8', // 字符集'DB_DEBUG' => TRUE, // 數據庫調試模式 開啟后可以記錄SQL日志② ?配置后臺公共文件
由于該項目同時包含 Home、Admin ?模塊,所以公共文件必須分開,因此可以把 Admin 模塊的公共文件放在 ./Application/Public/Admin 下,在 Admin 的模塊配置文件中配置:
//后臺公共文件路徑'TMPL_PARSE_STRING' => array('__PUBLIC__' => __ROOT__.'/Public/Admin'),③ 定義異常頁面
//異常頁面'TMPL_EXCEPTION_FILE' => './Public/Admin/error.html',異常頁面 error.html 中錯誤信息可以用 $e['message'] 表示
如果需要有倒計時跳轉的功能,可以參考 ./ThinkPHP/Tpl/dispatch_jump.tpl 文件
error.html:
<!DOCTYPE html> <html><head><title>error</title><meta charset="UTF-8"></head><body><?php echo $e['message'];?><br /><b id="wait">5</b>秒后跳轉回首頁 或 點擊<a id="href" href="/Admin/Index/index">返回首頁</a><script>(function(){var wait = document.getElementById('wait'),href = document.getElementById('href').href;var interval = setInterval(function(){var time = --wait.innerHTML;if(time <= 0) {location.href = href;clearInterval(interval);};}, 1000);})();</script></body> </html>例如訪問了不存在的方法,頁面會輸出:
無法加載控制器:Login2 3秒后跳轉回首頁 或 點擊返回首頁?然后跳轉回后臺主頁。
注:該頁面中不能使用 ThinkPHP 的標簽,只能使用原生的 PHP 語句。
三、管理員登陸
用于登陸的文件是 Admin 模塊下的 LoginController.class.php
<?php namespace Admin\Controller; use Think\Controller;class LoginController extends Controller{public function index() {$this->display();}//驗證碼public function verify() {$conf = array(//'useZh'=>true,//使用中文'fontSize'=>20,'length'=>1,'imageW'=>100,//驗證碼寬度);$Verify = new \Think\Verify($conf);$Verify->entry();} public function login() {if(!IS_POST) {e('非法登陸');}//檢驗驗證碼if(!check_verify(I('post.code'))) {$this->error('驗證碼錯誤');}$username = I('post.username', '');$user = M('user')->where(array('username'=>$username))->find();if(!$user || md5(I('post.password')) != $user['password']) {$this->error('用戶名或密碼錯誤');} if($user['lock']) $this->error('用戶被鎖定');//更新用戶表$data = array('id'=>$user['id'],'logintime'=>time(),'loginip'=> get_client_ip());M('user')->save($data);//保存sessionsession("user.uid", $user['id']);session("user.username", $user['username']);session("user.logintime", date('Y-m-d H:i:s', $user['logintime']));session("user.loginip", $user['loginip']);//成功跳轉$this->redirect('Admin/Index/index');} }幾點說明:
① IS_POST
位于 ./ThinkPHP/Library/Think/App.class.php(ThinkPHP 應用程序類 執行應用程序管理) 的?static public function init() 方法(應用程序初始化)內
定義當前請求的系統常量,源碼:
define('REQUEST_METHOD', $_SERVER['REQUEST_METHOD']);define('IS_POST', REQUEST_METHOD =='POST' ? true : false);② e 方法
位于 ThinkPHP/Common/functions.php (Think 系統函數庫)
/*** 拋出異常處理* @param string $msg 異常消息* @param integer $code 異常代碼 默認為0* @throws Think\Exception* @return void*/ function E($msg, $code=0) {throw new Think\Exception($msg, $code); }③ 模板路徑
默認情況下,Admin 模塊 Login 控制器的 index 方法對應的模板文件應該是 ./Application/Admin/View/Login/index.html
如果不希望目錄層級太多的話,可以將該方法對應的模板文件設置為 ./Application/Admin/View/Login_index.html,減少了一層目錄,在 Admin 模塊的模塊配置 config.php 中添加:
//模版路徑'TMPL_FILE_DEPR' => '_',登陸以后進入后臺首頁 http://serverName/Admin/Index/index
Admin 模塊的 Index 控制器 ./Application/Admin/Controller/IndexController.class.php:
<?php namespace Admin\Controller;class IndexController extends CommonController {public function index(){$this->display();}//推出登陸public function loginout() {session_unset();session_destroy();$this->redirect('Admin/Login/index');} }注:要進入后臺首頁,必須經過登陸,因此在加載該控制器之前應該先檢查用戶是否登陸,檢查的方法可以寫在 Admin 模塊的 Common 控制器中,然后 Index 控制器繼承 Common 控制。Common 控制器位于 ./Application/Admin/Controller/CommonController.class.php:
<?php namespace Admin\Controller; use Think\Controller;class CommonController extends Controller{public function _initialize() {if(!isset($_SESSION['user']['uid']) || !isset($_SESSION['user']['username'])) {$this->redirect('Admin/Login/index');}} }注:在 ./ThinkPHP/Library/Think/Controller.class.php (ThinkPHP 控制器基類)定義了
/*** 架構函數 取得模板對象實例* @access public*/public function __construct() {Hook::listen('action_begin',$this->config);//實例化視圖類$this->view = Think::instance('Think\View');//控制器初始化if(method_exists($this,'_initialize'))$this->_initialize();}登陸模塊的視圖文件位于 ./Application/Admin/View/Login_index.html:
<!DOCTYPE html> <html><head><link rel="stylesheet" href="__PUBLIC__/Css/login.css" /><meta charset="utf-8"><script src="__PUBLIC__/Js/jquery-1.7.2.min.js"></script><script src="__PUBLIC__/Js/login.js"></script></head><body><div id="top"></div><div class="login"> <form action="{:U('Admin/Login/login')}" method="post" id="login"><div class="title">登錄后臺</div><table border="1" width="100%"><tr><th>管理員帳號:</th><td><input type="username" name="username" class="len250"/></td></tr><tr><th>密碼:</th><td><input type="password" class="len250" name="password"/></td></tr><tr><th>驗證碼:</th><td><input type="code" class="len250" name="code"/> <img src="{:U('Admin/Login/verify','','')}" id="code"/> <a href="javascript:void(change_code(this));">看不清</a></td></tr><tr><td colspan="2" style="padding-left:160px;"> <input type="submit" class="submit" value="登錄"/></td></tr></table></form></div></body> </html>注:
①?U 方法
在控制器使用 U 方法的格式是?U(模塊/控制器/方法, array('參數1'=>'參數1的值','參數2'=>'參數2的值', '偽靜態后綴'))
在模板中使用 U 方法的格式是 {:U(模塊/控制器/方法, array('參數1'=>'參數1的值','參數2'=>'參數2的值', '偽靜態后綴'))}
② 偽靜態后綴
可以在模塊配置文件 config.php 中配置偽靜態后綴,默認為 .html,即 URL 可能是 http://serverName/Admin/Index/index.html。可以設置為空,即 URL 可能為 http://serverName/Admin/Index/index
//偽靜態后綴'URL_HTML_SUFFIX'=>'',Admin 模塊的文件目錄:
crm_user 表:
CREATE TABLE `crm_user` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `username` char(20) NOT NULL DEFAULT '', `password` char(32) NOT NULL DEFAULT '', `logintime` int(10) unsigned NOT NULL, `loginip` varchar(30) NOT NULL, `lock` tinyint(1) unsigned NOT NULL DEFAULT '0', PRIMARY KEY (`id`), UNIQUE KEY `username` (`username`) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8四、自定義 Session 存儲?
① 把 Session 存儲在 MySQL 數據庫中
ThinkPHP 3.2.3 自帶了 Db 類型的 Session 驅動,Db 類位于 ./ThinkPHP/Library/Think/Session/Driver/Db.class.php
框架已經準備好了 session 表:
CREATE TABLE think_session (session_id varchar(255) NOT NULL,session_expire int(11) NOT NULL,session_data blob,UNIQUE KEY `session_id` (`session_id`));修改模塊配置 ./Application/Admin/Common/Conf/config.php,增加以下配置即可:
'SESSION_TYPE'=>'Db',② 把 Session 存儲在 Redeis 中
ThinkPHP 3.2.3 自帶了 Memcache ?驅動,可以參考該驅動來開發 Redis 驅動,新建 Redis.class.php,放在 ./ThinkPHP/Library/Think/Session/Driver 下:
<?php // +--------------------------------------------------------------------- // | Date:2016/01/09 // +---------------------------------------------------------------------- namespace Think\Session\Driver;class Redis {//保存Redis連接對象protected $redis;//Session有效時間private $expire;/*** 打開Session * @access public * @param string $savePath * @param mixed $sessName */public function open($savePath, $sessName) {$this->expire = C('SESSION_EXPIRE') ? C('SESSION_EXPIRE') : ini_get('session.gc_maxlifetime');$this->redis = new Redis();return $this->redis->connect(C('REDIS_HOST'), C('REDIS_PORT'));}/*** 關閉Session * @access public */public function close() {return $this->redis->close();}/*** 讀取Session * @access public * @param string $sessID */public function read($sessID) {$sessID = C('SESSION_PREFIX').$sessID;$sessData = $this->redis->get($sessID);return $sessID ? $sessID : '';}/*** 寫入Session * @access public * @param string $sessID * @param String $sessData */public function write($sessID, $sessData) {$sessID = C('SESSION_PREFIX').$sessID;return $this->redis->set($sessID, $sessData, $this->expire);}/*** 刪除Session * @access public * @param string $sessID */public function destroy($sessID) {$sessID = C('SESSION_PREFIX').$sessID;return $this->redis->delete($sessID);}/*** Session 垃圾回收* @access public * @param string $sessMaxLifeTime */public function gc($sessMaxLifeTime) {return true;} }然后修改模塊配置文件 config.php:
'SESSION_TYPE'=>'Redis',//Redeis服務器地址'REDIS_HOST'=>'127.0.0.1',//Redis端口號'REDIS_PORT'=>'6379',//Session前綴'SESSION_PREFIX'=>'session_',//Session有效時間'SESSION_EXPIRE'=>3600五、文章管理
文章管理的控制器 ArticleManageController.class.php:
<?php /** 文章管理類* date:2016/01/10*/ namespace Admin\Controller; use Think\Page;class ArticleManageController extends CommonController{public function index() {$count = M('article')->count();$page = new Page($count, 3);$limit = $page->firstRow.','.$page->listRows;$show = $page->show();$list = M('article')->limit($limit)->select();$this->assign('list', $list);$this->assign('show', $show);$this->display();} }?注:ThinkPHP 3.2.3 的分頁類位于 ./ThinkPHP/Library/Think/Page.class.php,因此除了使用 use 關鍵字引入命名空間為 Think 的 Page類,然后直接實例化 Page類外,還可以在需要實例化 Page 類的時候 new \Think\Page(); Think 前面的 \ 代表根命名空間。
在使用分頁類的時候只需要把總條數和每頁分配的條數作為參數傳給 Page 類以獲取 limit 參數。
文章管理的視圖文件位于 ./Application/Admin/View/ArticleManage_index.html:
<!DOCTYPE html> <html><head><title>TODO supply a title</title><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><css file='__PUBLIC__/Css/public.css'/></head><body><table class='table'><tr><th>序號</th><th>標題</th><th>發布人</th><th>內容概述</th><th>發布時間</th><th>操作</th></tr><volist name='list' id='vo'><tr><td>{$vo.id}</td><td>{$vo.title}</td><td>{$vo.creat_id}</td><td>{$vo.content}</td><td>{$vo.addtime|date="Y-m-d H:i", ###}</td><td><a href="#">刪除</a></td></tr></volist><tr><td colspan="6" align="center">{$show}</td></tr></table></body> </html>注:模板中使用了點語法解析數組,點語法在模板中除了解析數組外,還可以解析對象。可以在模塊配置中設置點語法只解析數組,可以使模板解析速度更快:
//點語法默認解析'TMPL_VAR_IDENTIFY' => 'array',轉:
http://www.cnblogs.com/dee0912/p/5116695.html 與50位技術專家面對面20年技術見證,附贈技術全景圖
總結
以上是生活随笔為你收集整理的ThinkPHP 3.2.3 简单后台模块开发(一)常用配置的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: G36南京长江大桥能走大车吗?
- 下一篇: 欧马可方向盘右下控制杆向前推什么意思?