摘要:相關(guān)信息,面向過(guò)程,面向?qū)ο?,輕量級(jí)。輕量級(jí)功能實(shí)用,面向過(guò)程和面向?qū)ο蠡旌祥_(kāi)發(fā)。找到文件為文件名為驗(yàn)證碼類沒(méi)有在自動(dòng)加載類中載入,需要手動(dòng)載入。底層的和會(huì)影響原始的框架中的引入,可以使用框架中提供的引入。
不使用框架的問(wèn)題
在實(shí)際工作中,如果不使用框架會(huì)遇到的問(wèn)題。
程序項(xiàng)目生命時(shí)間非常短(維護(hù)性,生命力弱)
分共協(xié)作開(kāi)發(fā)項(xiàng)目,彼此代碼風(fēng)格不一致。
開(kāi)發(fā)程序,喜歡挖坑。
開(kāi)發(fā)者離職,需要有人維護(hù)該離職著的代碼風(fēng)格.
牽一發(fā)而動(dòng)全身
框架的最大的特點(diǎn)使得程序的業(yè)務(wù)邏輯與數(shù)據(jù)模型分開(kāi)。
相關(guān)信息
ThinkPhp, 面向過(guò)程,面向?qū)ο?,輕量級(jí)。
重量級(jí):功能多,OOP面向?qū)ο?,維護(hù)性好,生命力頑強(qiáng)。
輕量級(jí):功能實(shí)用,面向過(guò)程和面向?qū)ο蠡旌祥_(kāi)發(fā)。
創(chuàng)建入口文件,并引入核心框架入口文件 (index.php/app.php)
// TP框架核心框架核心程序引入 require("./ThinkPHP/ThinkPHP.php");
訪問(wèn)文件地址,配置虛擬目錄
執(zhí)行流程運(yùn)行入口文件
// 定義系統(tǒng)目錄 define("APP_PATH", "./"); // 修改為調(diào)試模式 define("APP_DEBUG", true);
TP的入口文件ThinkPHP.php
載入Common/runtime.php
聲明常量信息 執(zhí)行:`load_runtime_file()`,作用:加載運(yùn)行時(shí)所需要的文件 并負(fù)責(zé)自動(dòng)目錄生成 執(zhí)行入口:`Think::Start();`
執(zhí)行:Lib/Core/Think.class.php
static public function start() {}; // 應(yīng)用程序初始化 Think::buildApp(); // 預(yù)編譯項(xiàng)目 App::run(); // 運(yùn)行應(yīng)用
執(zhí)行:Lib/Core/App.class.php
static public function run() {}; // 運(yùn)行應(yīng)用實(shí)例 入口文件使用的快捷方法 App::init(); // 應(yīng)用程序初始化 Dispatcher::dispatch(); // URL調(diào)度 // 分析路由(控制器`MODULE_NAME` 方法`ACTION_NAME`) // e.g: index.php?c=控制器&a=方法 App::exec(); // 執(zhí)行應(yīng)用程序 通過(guò)反射ReflectionMethod使得控制器對(duì)象調(diào)用對(duì)應(yīng)的方法.控制器和簡(jiǎn)單模板創(chuàng)建
如何分離控制器
根據(jù)業(yè)務(wù)特點(diǎn),把控制器分離(User, Goods)
路由解析
通過(guò)GET方式告知應(yīng)用,請(qǐng)求控制器和操作方法.
GET最基本方式
http://www.tp.com/shop/go/index.php?m=User&a=register
路徑方式
http://www.tp.com/shop/go/index.php/User/register
偽靜態(tài)方式
http://www.tp.com/shop/go/User/register
兼容模式 (兼容基本方式和路徑方式)
http://www.tp.com/shop/go/index.php?s=User/login
在Tpl目錄下創(chuàng)建對(duì)應(yīng)的控制器標(biāo)識(shí)作為文件夾(Goods),對(duì)應(yīng)控制器的動(dòng)作作為訪問(wèn)文件(showlist.html)。
控制器中調(diào)用display();
display(); } // 查看商品的詳細(xì)信息 public function detail() { $this->display(); } } ?>模板引入框架中
把模板引入ThinkPH框架中,出現(xiàn)的樣式路徑,圖片路徑,JavaScript路徑不正確。
CSS文件和圖片文件位置原則:可以多帶帶被訪問(wèn).
配置資源的public文件,放置css,images,js等文件。
需要配置基本常量.
// 路徑常量 define("SITE_URL", "http://tp.com/"); // 網(wǎng)站地址 define("CSS_URL", SITE_URL . "shop/go/public/css/"); // 前臺(tái)頁(yè)面CSS路徑 define("IMAGE_URL", SITE_URL . "shop/go/public/images"); // 前臺(tái)頁(yè)面圖片路徑常量
模板中如何使用常量
利用thinkphp默認(rèn)的模板引擎調(diào)用常量。{$Think.const.常量名}
空操作和空模塊空操作
空請(qǐng)求:http://xxxx/index.php?m=user&a=pink;
pink沒(méi)有對(duì)應(yīng)的操作動(dòng)作,是一個(gè)空請(qǐng)求。
空操作,一個(gè)類實(shí)例化對(duì)象,對(duì)象調(diào)用類中不存在的方法。在OOP中有魔術(shù)方法,__call(),自動(dòng)調(diào)用該魔術(shù)方法。
空操作處理:
對(duì)應(yīng)的控制器中定義方法_empty()
在應(yīng)用Common/common.php中添加一個(gè)函數(shù)名:__hack_action()。
空模塊
ThinkPHP中把MVC中的控制器稱之為:模塊(module).
空模塊:http://xxxx/index.php?m=color&a=pink;
color不存在的控制器
空模塊處理方式:
對(duì)應(yīng)的控制器中定義模塊:EmptyAction.class.php
在應(yīng)用Common/common.php中添加一個(gè)函數(shù)名: __hack_module
項(xiàng)目分組設(shè)置ThinkPHP模塊的分組:
"APP_GROUP_LIST" => "home,admin", // 項(xiàng)目分組設(shè)定,多個(gè)組之間用逗號(hào)分隔,例如"Home,Admin"
項(xiàng)目分組對(duì)路由的影響:
http://www.xxxx.com/index.php/分組名稱/控制器/方法
分組的范圍:
Action控制器分組
Tpl模板分組
配置文件
靜態(tài)資源分組
frameset搭建后臺(tái)頁(yè)面使用:frameset標(biāo)簽進(jìn)行搭建.
獲得常量信息:get_defined_constants(true); // true參數(shù)表示分類
修改路由鏈接(使用絕對(duì)地址)
后臺(tái)商品列表后臺(tái)商品列表-修改-增加
display(); } // 添加商品 public function add() { $this->display(); } // 修改商品 public function upd() { $this->display(); } } ?>跨模塊調(diào)用
利用自動(dòng)加載
$user = new UserAction(); $user->number();
系統(tǒng)提供:A函數(shù)調(diào)用
// A函數(shù)用于實(shí)例化Action 格式:[項(xiàng)目://][分組/]模塊 // 調(diào)用當(dāng)前項(xiàng)目 $user = A("home/User"); $user->number(); // 調(diào)用不同項(xiàng)目中的控制器 $user = A("book://Index"); echo $user->info();
系統(tǒng)提供:遠(yuǎn)程調(diào)用模塊的操作方法 URL
// 遠(yuǎn)程調(diào)用模塊的操作方法 URL 參數(shù)格式 [項(xiàng)目://][分組/]模塊/操作方法 echo R("home/User/number");簡(jiǎn)單model模型創(chuàng)建
數(shù)據(jù)庫(kù)連接
在配置文件中配置數(shù)據(jù)庫(kù)基本信息
// 數(shù)據(jù)庫(kù) "DB_TYPE" => "mysql", // 數(shù)據(jù)庫(kù)類型 "DB_HOST" => "localhost", // 服務(wù)器地址 "DB_NAME" => "shop", // 數(shù)據(jù)庫(kù)名 "DB_USER" => "root", // 用戶名 "DB_PWD" => "", // 密碼 "DB_PORT" => "", // 端口 "DB_PREFIX" => "sw_", // 數(shù)據(jù)庫(kù)表前綴 "DB_FIELDTYPE_CHECK" => false, // 是否進(jìn)行字段類型檢查 "DB_FIELDS_CACHE" => true, // 啟用字段緩存
數(shù)據(jù)庫(kù)中每張數(shù)據(jù)表都對(duì)應(yīng)一個(gè)數(shù)據(jù)model模型類。
簡(jiǎn)單model模型創(chuàng)建與使用
創(chuàng)建文件:GoodsModel.class.php
字段緩存:
// 出于性能考慮,要把數(shù)據(jù)表字段放入緩存中,下次訪問(wèn)就避免執(zhí)行SQL語(yǔ)句重復(fù)執(zhí)行。 // 前提,是生產(chǎn)模式,字段緩存有效. "DB_FIELDS_CACHE" => true, // 啟用字段緩存
基類Model部分屬性:
實(shí)例化的三種方法普通的實(shí)例化方法
$goods_model = new GoodsModel();
快捷方式
// D(); D函數(shù)用于實(shí)例化Model 格式 項(xiàng)目://分組/模塊 $goods_model = D("Goods");
實(shí)例化沒(méi)有模型文件的Model
$model = new Model(); // 實(shí)例化基類 // 指定實(shí)例化Model $model = M("CateGory"); // 調(diào)用M(); 函數(shù) // M函數(shù)用于實(shí)例化一個(gè)沒(méi)有模型文件的Model查詢數(shù)據(jù)select方法 查詢基本使用
// 查詢數(shù)據(jù) $goods_model = new GoodsModel(); // 查詢?nèi)繑?shù)據(jù) $info = $goods_model->select(); // select(記錄主鍵值); 方法查詢數(shù)據(jù) // 返回二維數(shù)據(jù) // 查詢一條記錄 $info = $goods_model->select(7); // 查詢多條記錄 $info = $goods_model->select("17, 20, 23"); // SELECT * FROM `sw_goods` WHERE ( `goods_id` IN ("17"," 20"," 23") )查詢相關(guān)操作方法
find() 返回一條記錄
// 返回一維數(shù)組, 每次只返回一條數(shù)據(jù) $info = $goods_model->find(7); // SELECT * FROM `sw_goods` WHERE ( `goods_id` = 7 ) LIMIT 1
field() 固定字段
// 查詢固定字段 // 指定查詢字段 支持字段排除 $info = $goods_model->field("goods_name, goods_price, goods_number, goods_cretae_time")->select();
limit() 查詢條
// 查詢條數(shù) // $info = $goods_model->limit(長(zhǎng)度) // $info = $goods_model->limit(偏移量, 長(zhǎng)度) $info = $goods_model->limit(5, 5)->select();
order() 排序
// 排序 // $info = $goods_model->order(條件 倒序/正序); $info = $goods_model->order("goods_price desc")->select(); // 鏈?zhǔn)秸{(diào)用 $info = $goods_model->order("goods_price desc")->limit(5)->select();
order()是Model不存在的方法,會(huì)執(zhí)行魔術(shù)方法__call()自動(dòng)調(diào)用
where() 設(shè)置條件
// 設(shè)置條件 $info = $goods_model->where("goods_price > 5000")->select();
table() 設(shè)置表名
// 設(shè)置表名 $info = $goods_model->table("sw_goods")->select();
group() 分組
// 分組 $info = $goods_model->group("goods_category_id")->select();
模型相關(guān)方法分析
Model.class.php 類本身就存在該方法。例如:where(), filed(), limit(), select()
__call() 自動(dòng)調(diào)用方法集成了一些方法,可以鏈?zhǔn)秸{(diào)用 例如:table(), order(), group()
getByXXX() 查詢數(shù)據(jù)
返回一維數(shù)組信息.
根據(jù)指定字段查詢數(shù)據(jù)信息
$info = $goods_model->getByGoods_price("5999"); // 自動(dòng)調(diào)用`__call()`魔術(shù)方法
having() 設(shè)置查詢條件
和where一樣效果,比where 執(zhí)行晚. 可以對(duì)結(jié)果結(jié)果集進(jìn)行操作.
having 可以和聚合函數(shù)一起使用
$info = $goods_model->having("goods_name like "A%"")->select();
model 聚合函數(shù)
// 聚合函數(shù) $info = $goods_model->where("goods_id>50")->select(); $num = $goods_model->where("goods_id>50")->count(); // SELECT COUNT(*) AS tp_count FROM `sw_goods` WHERE ( goods_id>50 ) LIMIT 1 echo $num; $total_price = $goods_model->where("goods_id>50")->sum("goods_price"); // SELECT SUM(goods_price) AS tp_sum FROM `sw_goods` WHERE ( goods_id>50 ) LIMIT 1 echo $total_price;
sum(字段),count(*/字段),max(字段),min(字段),avg(字段)。
原生SQL語(yǔ)句
提供2個(gè)方法:
$model->query() 查詢語(yǔ)句, 返回二維數(shù)據(jù)
$model->execute() 增加,修改,刪除, 返回受影響記錄數(shù)目
// 執(zhí)行原生SQL // select g.goods_name, g.goods_price, c.cat_name from sw_goods as g left join sw_category as c on g.goods_category_id = c.cat_id; $sql = "select g.goods_name, g.goods_price, c.cat_name from sw_goods as g left join sw_category as c on g.goods_category_id = c.cat_id"; $info = $goods_model->query($sql);smaty模板使用
在Extend/Vendor放入smart模板
ThinkPHP配置信息有兩部分:convertion.php和Lib/Behavior/* 配置
在配置文件中配置模板類型:
"TMPL_ENGINE_TYPE" => "Smarty", // 修改模板引擎
顯示日志信息
配置信息中配置日志信息顯示:
前提:必須調(diào)用$this->display()才會(huì)顯示日志信息。就必須顯示模板
"SHOW_PAGE_TRACE" => true, // 顯示頁(yè)面Trace信息操作數(shù)據(jù) 數(shù)據(jù)添加
兩種方式實(shí)現(xiàn)數(shù)據(jù)添加: 數(shù)組方式,AR方式
數(shù)組方式
// 模型對(duì)象 $goods_model = new GoodsModel(); // 實(shí)現(xiàn)數(shù)據(jù)添加 // 數(shù)組下標(biāo)與數(shù)據(jù)庫(kù)字段名一致. // 獲取數(shù)據(jù) $data = array( "goods_name" => "htc100", "goods_price" => "3999", "goods_numer" => 45, "goods_weight" => 103 ); $goods_model->add($data); // 返回自動(dòng)生成的ID值
AR 方式
Active Record 活躍記錄
AR記錄的規(guī)則:
數(shù)據(jù)庫(kù)中的每個(gè)數(shù)據(jù)表對(duì)應(yīng)一個(gè)類
數(shù)據(jù)表中的每條記錄都是一個(gè)類的一個(gè)對(duì)象
記錄信息的每個(gè)字段都是對(duì)象的屬性
// AR方式實(shí)現(xiàn)數(shù)據(jù)添加 // 對(duì)象調(diào)用不存在的屬性需要調(diào)用魔術(shù)方法`__set()` $goods_model->goods_name = "iphone7puls"; $goods_model->goods_price = "5700"; $goods_model->goods_number = 41; $goods_model->goods_weight = 100; $rst = $goods_model->add(); // 返回影響記錄的條數(shù)收集表單數(shù)據(jù)
Array
$data = $_POST; $cnt = $goods_model->add($data);
AR方式
foreach( $_POST as $k => $v ) { $goods_model->$k = $v; } $goods_model->add();
ThinkPHPcreate方式
$data = $goods_model->create(); $cnt = $goods_model->add($data);數(shù)據(jù)修改
save()方法保存數(shù)據(jù)
// 修改商品 public function upd() { $goods_model = new GoodsModel(); // 修改數(shù)據(jù), 需要設(shè)置主鍵ID和where條件 $data = array( "goods_id" => 55, "goods_name" => "紅米", "goods_price" => 4000 ); $rst = $goods_model->save($data); // 返回受影響記錄的數(shù)目 $data = array( "goods_name" => "香米", "goods_price" => 4000 ); $rst = $goods_model->where("goods_id=57")->save($data); echo $rst; $this->display(); }
AR方式
// 主鍵方式 $goods_model->goods_id = 58; $goods_model->goods_name = "APPLE"; $goods_model->goods_price = 4000; $goods_model->save(); // where 條件方式 $goods_model->goods_name = "huawei"; $goods_model->goods_price = 4000; $snt = $goods_model->where("goods_id=56")->save();
修改數(shù)據(jù)注意:設(shè)置where條件,或者主鍵條件。
刪除數(shù)據(jù)
delete(主鍵)
$goods_model->delete(57);
路由獲取形式
// 獲取參數(shù)形式 // http://www.tp.com/index.php?m=控制器&a=操作&goods_id=100&goods_price=2300 // http://www.tp.com/index.php/控制器/操作/參數(shù)1/值1/參數(shù)2/值2 // function upd( 參數(shù)1, 參數(shù)2 ) { // $_GET["goods_id"]; // } // URL地址參數(shù)要與方法參數(shù)一致
錯(cuò)誤信息處理
在控制器中調(diào)用方法:
$this->success("修改成功", __URL__ ."/showList");
系統(tǒng)會(huì)尋找dispatch_jump.tpl文件
在Lib/Core/View.class.php中修改parseTemplate方法
/** * 自動(dòng)定位模板文件 * @access protected * @param string $template 模板文件規(guī)則 * @return string */ public function parseTemplate($template="") { / 判斷是否存在模板文件 移動(dòng)到后面判斷. if(is_file($template)) { return $template; } }表單驗(yàn)證
前提:收集表單數(shù)據(jù)必須通過(guò)create()方法來(lái)收集. 定義的驗(yàn)證規(guī)則通過(guò)create()方法觸發(fā).
ThinkPHP自動(dòng)驗(yàn)證:TP自動(dòng)驗(yàn)證
在UserModel.class.php中重寫(xiě)$_validate:
Smarty引入流程
控制器IndexAction.class.php
function index()
$this->display(); (父類Action的display)
父類ThinkPHP/Lib/Core/Action.class.php
$this->view->display();
ThinkPHP/Lib/Core/View.class.php
function display()
// 解析并獲取模板內(nèi)容 $content = $this->fetch($templateFile,$content,$prefix);
// 解析和獲取模板內(nèi)容 用于輸出
function fetch()
tag("view_parse",$params);
ThinkPHP/Conf/tags.php
"view_parse" => array(
"ParseTemplate", // 模板解析 支持PHP、內(nèi)置模板引擎和第三方模板引擎 (Bahavior行為)
),
parseTempliteBahavior.class.php
function run()
$class = "TemplateSmarty"
// ThinkPHP/Extend/Dirver/Template/TemplateSmarty.class.php if(class_exists($class)) { // 通過(guò)自動(dòng)加載機(jī)制引入對(duì)應(yīng)類文件. $tpl = new $class; $tpl->fetch($_content,$_data["var"]); }else { // 類沒(méi)有定義 throw_exception(L("_NOT_SUPPERT_").": " . $class); }
ThinkPHP/Extend/Dirver/Template/TemplateSmarty.class.php
public function fetch($templateFile,$var)
// 尋找Smarty實(shí)體. // ThinkPHP/Extend/Vendor/Smarty/Smarty.class.php vendor("Smarty.Smarty#class"); // 獲取真正的Smarty $tpl = new Smarty(); C(); // 會(huì)讀取配置文件信息
smarty布局與繼承
利用extends和include完成
{extends file="public/layout.html"} {block name="main"} // 子模板代碼 {/block}
{include file="public/ucenterleft.tpl"}
問(wèn)題:當(dāng)代碼公共出去之后,對(duì)應(yīng)不同標(biāo)簽需要顯示不同的樣式?
通過(guò)路由解析 (如何在模板中拿到路由中的操作方法$smarty.const.ACTION_NAME)
通過(guò)路由參數(shù)
display() 顯示模板的四種方法
ThinkPHP框架調(diào)用模板:
$this->display() ThinkPHP會(huì)自動(dòng)把模板名稱拼裝好,與操作名一致。
調(diào)用當(dāng)前模塊下的模板:
$this->display(模板名字) 模板名字沒(méi)有后綴
調(diào)用其它模塊下的模板:
$this->display(模塊/模板名)
相對(duì)路徑找到模板文件:(相對(duì)于入口文件index.html)
$this->dispaly(相對(duì)路徑)
import引入機(jī)制
例如:import("a.b.c"); // a/b/c.class.php
可以引入那些位置的類文件?
本身項(xiàng)目的類文件 [對(duì)應(yīng)的類文件都需要?jiǎng)?chuàng)建在Lib目錄下]
import("@.dir.dir.file"); e.g:import("@.Model.QqModel.class.php"); // Lib/Model/QqModel.class.php
ThinkPHP核心類文件
import("think.dir.dir.file"); e.g:import("think.car.dirver"); // ThinkPHP/Lib/car/dirver.class.php
擴(kuò)展的類文件(ThinkPHP/Extend), 第三庫(kù)文件引入
import("ORG.dir.dir.file"); e.g: import("ORG.color.pink"); // ThinkPHP/Extend/Library/ORG/color/pink.class.php
引入一個(gè)特殊文件名的類文件。#號(hào)使用。
// 找到文件為:// Lib/apple/bananer.good.flash.class.php import("@.apple.bananer#good#flash"); // 文件名為:`bananer.good.flash.class.php`驗(yàn)證碼
Image類沒(méi)有在自動(dòng)加載類中載入,需要手動(dòng)載入。PHP底層的include和require會(huì)影響原始的框架中的引入,可以使用框架中提供的import引入。
import("ORG/Util/Image"); echo Image::buildImageVerify();
顯示驗(yàn)證碼
驗(yàn)證驗(yàn)證碼
if ( !empty($_POST["captcha"]) && md5($_POST["captcha"]) == $_SESSION["verify"] ) {}用戶登陸
登陸信息在模型中驗(yàn)證
getByMg_name($name); // 用戶名和密碼是否正確 if ( $name_info != null ) { // 密碼 if ( $name_info["mg_pwd"] != $pwd ) { return false; } else { return $name_info; } } else { return false; } } } ?>
thinkphp中的session
session的操作:
session(name, value) // 設(shè)置session session(name, null) // 刪除指定session session(name) // 獲取session信息 session(null) // 清空全部session
驗(yàn)證驗(yàn)證碼 --> 校驗(yàn)用戶名和密碼 --> 判斷用戶名 .
checkNamePwd($_POST["mg_name"], $_POST["mg_pwd"]); // 判斷密碼 if ( $user_info != false ) { // 持久化用戶信息(id和名字) session("mg_name", $user_info["mg_name"]); session("mg_id", $user_info["mg_id"]); // 頁(yè)面重定向 $this->redirect("Index/index"); } else { echo "用戶名或密碼錯(cuò)誤"; } } else { echo "驗(yàn)證碼不正確"; } } $this->display(); } // 退出系統(tǒng) public function logout() { // 刪除session信息 session("mg_name", null); // 刪除用戶名 session("mg_id", null); // 刪除id $this->redirect("Manager/login"); } // 生成驗(yàn)證碼 public function verifyImg() { import("ORG/Util/Image"); echo Image::buildImageVerify(); } } ?>數(shù)據(jù)分頁(yè)
自定義的分頁(yè)類
"個(gè)記錄", "prev"=>"上一頁(yè)", "next"=>"下一頁(yè)", "first"=>"首 頁(yè)", "last"=>"尾 頁(yè)"); private $listNum = 8; /* * $total * $listRows */ public function __construct($total, $listRows=10, $pa=""){ $this->total=$total; $this->listRows=$listRows; $this->uri=$this->getUri($pa); $this->page=!empty($_GET["page"]) ? $_GET["page"] : 1; $this->pageNum=ceil($this->total/$this->listRows); $this->limit=$this->setLimit(); } private function setLimit(){ return "Limit ".($this->page-1)*$this->listRows.", {$this->listRows}"; } private function getUri($pa){ $url=$_SERVER["REQUEST_URI"].(strpos($_SERVER["REQUEST_URI"], "?")?"":"?").$pa; $parse=parse_url($url); if(isset($parse["query"])){ parse_str($parse["query"],$params); unset($params["page"]); $url=$parse["path"]."?".http_build_query($params); } return $url; } public function __get($args){ if($args=="limit") return $this->limit; else return null; } private function start(){ if($this->total==0) return 0; else return ($this->page-1)*$this->listRows+1; } private function end(){ return min($this->page*$this->listRows,$this->total); } private function first(){ $html = ""; if($this->page==1) $html.=""; else $html.=" {$this->config["first"]} "; return $html; } private function prev(){ $html = ""; if($this->page==1) $html.=""; else $html.=" page-1)."">{$this->config["prev"]} "; return $html; } private function pageList(){ $linkPage=""; $inum=floor($this->listNum/2); for($i=$inum; $i>=1; $i--){ $page=$this->page-$i; if($page<1) continue; $linkPage.=" {$page} "; } $linkPage.=" {$this->page} "; for($i=1; $i<=$inum; $i++){ $page=$this->page+$i; if($page<=$this->pageNum) $linkPage.=" {$page} "; else break; } return $linkPage; } private function next(){ $html = ""; if($this->page==$this->pageNum) $html.=""; else $html.=" page+1)."">{$this->config["next"]} "; return $html; } private function last(){ $html = ""; if($this->page==$this->pageNum) $html.=""; else $html.=" pageNum)."">{$this->config["last"]} "; return $html; } private function goPage(){ return " pageNum.")?".$this->pageNum.":this.value;location="".$this->uri."&page="+page+""}" value="".$this->page."" style="width:25px">pageNum.")?".$this->pageNum.":this.previousSibling.value;location="".$this->uri."&page="+page+"""> "; } public function fpage($display=array(0,1,2,3,4,5,6,7,8)) { $html[0]=" 共有{$this->total}{$this->config["header"]} "; $html[1]=" 每頁(yè)顯示".($this->end()-$this->start()+1)."條,本頁(yè){$this->start()}-{$this->end()}條 "; $html[2]=" {$this->page}/{$this->pageNum}頁(yè) "; $html[3]=$this->first(); $html[4]=$this->prev(); $html[5]=$this->pageList(); $html[6]=$this->next(); $html[7]=$this->last(); $html[8]=$this->goPage(); $fpage=""; foreach($display as $index){ $fpage.=$html[$index]; } return $fpage; } }
使用:
public function showList() { $goods_model = new GoodsModel(); // 引入分頁(yè)類 import("@.Components.Page"); // 計(jì)算當(dāng)前記錄總數(shù)目 $total = $goods_model->count(); // 每頁(yè)5條 $per = 5; // 實(shí)例化分頁(yè)對(duì)象 $page = new Page($total, $per); // 獲得頁(yè)面列表 $page_list = $page->fpage(); // $page_list = $page->fpage(array(3, 4, 5, 6, 7, 8)); // SQL語(yǔ)句,獲得每頁(yè)的信息 $sql = "select * from sw_goods " . $page->limit; $info = $goods_model->query($sql); // 設(shè)置數(shù)據(jù) $this->assign("info", $info); $this->assign("page_list", $page_list); // 顯示 $this->display(); }緩存
把數(shù)據(jù)庫(kù)中的信息獲取出來(lái),放到一個(gè)緩存介質(zhì)里邊,在相當(dāng)長(zhǎng)的一段時(shí)間之內(nèi),重復(fù)的數(shù)據(jù)在緩存中讀取。
緩存介質(zhì):內(nèi)存,file文件,數(shù)據(jù)庫(kù)(超多張表,聯(lián)表查詢)。
// 設(shè)置緩存 public function sSet() { // 緩存周期,默認(rèn)永久。 增加緩存有效期 S("username", "admin", 1800); // 1800 半個(gè)小時(shí) // 過(guò)期自動(dòng)刪除 S("goods_info", array("apple", "WeChat")); // 數(shù)組 } // 獲取緩存 public function gGet() { echo S("username"); } // 刪除緩存 public function dDel() { S("username", null); }
緩存使用規(guī)則:
public function getInfo() { // 1. 首先要去緩存中獲取商品信息 $g = S("info"); // 2. 緩存有商品信息,直接返回. // 否則去數(shù)據(jù)庫(kù)查詢數(shù)據(jù)返回,并放入緩存中,設(shè)置緩存周期. if ( !empty($g) ) { return $g; } else { $g = "apple". time(); // 數(shù)據(jù)放入緩存 S("info", $g, 10); // 設(shè)置時(shí)間 // 返回?cái)?shù)據(jù) return $g; } }多語(yǔ)言設(shè)置
配置行為
在配置文件config.php中配置多語(yǔ)言參數(shù)
// 配置多語(yǔ)言參數(shù) "LANG_SWITCH_ON" => true, // 默認(rèn)關(guān)閉語(yǔ)言包功能 "LANG_AUTO_DETECT" => true, // 自動(dòng)偵測(cè)語(yǔ)言 開(kāi)啟多語(yǔ)言功能后有效 "LANG_LIST" => "zh-cn, zh-tw, en-us", // 允許切換的語(yǔ)言列表 用逗號(hào)分隔 "VAR_LANGUAGE" => "hl", // 默認(rèn)語(yǔ)言切換變量
設(shè)置tags.php執(zhí)行行為
array( "ReadHtmlCache", "CheckLang" // 讀取靜態(tài)緩存 , 檢測(cè)語(yǔ)言 ), ); ?>
定義語(yǔ)言文件
定義中文簡(jiǎn)體:../Lang/zh-us/admin/manager.php // 模塊名稱/控制器名稱
定義中文繁體:../Lang/zh-tw/admin/manager.php // 模塊名稱/控制器名稱
ThinkPHP中有在視圖可以讀取語(yǔ)言信息的變量$Think.language.username
Smarty中沒(méi)有讀取,需要通過(guò)控制器中的L()函數(shù)讀取,然后賦值設(shè)置。
// 讀取語(yǔ)言變量信息 // L(name); 讀取指定語(yǔ)言信息 // L(); 把全部語(yǔ)言信息以數(shù)組信息返回 $lang = L(); $this->assign("lang", $lang);自動(dòng)完成
收集表單信息,把數(shù)據(jù)存入數(shù)據(jù)庫(kù)中,可以使用自動(dòng)完成機(jī)制,對(duì)即將入庫(kù)的信息進(jìn)行二次加密.
自動(dòng)完成類似表單驗(yàn)證:表單驗(yàn)證在create()方法內(nèi)部觸發(fā)。 而自動(dòng)完成和自動(dòng)映射也都是通過(guò)create()觸發(fā)。
手冊(cè):自動(dòng)完成
自動(dòng)完成,自動(dòng)過(guò)濾,自動(dòng)驗(yàn)證,自動(dòng)映射,緩存,等操作都放入模型中操作(對(duì)于操作數(shù)據(jù))。
// 自動(dòng)完成 // 自動(dòng)完成定義 protected $_auto = array( // array("填充字段", "填充內(nèi)容", ["填充條件", "附加規(guī)則"]) array("password", "md5", 3, "function"), array("user_time", "time", 1, "function") );自動(dòng)映射
// 自動(dòng)映射, 把一個(gè) form表單中的name和 數(shù)據(jù)庫(kù)中的字段對(duì)應(yīng)起來(lái) protected $_map = array( "email" => "user_emial", "qq" => "user_qq" );
面向切面編程
程序開(kāi)發(fā),執(zhí)行不同的環(huán)節(jié),不同的功能利用不同的文件進(jìn)行處理。
把大塊的功能切割為小塊的功能執(zhí)行。
整體TP框架執(zhí)行,內(nèi)部不是一個(gè)文件從頭到尾,不同的功能由不同的文件分別執(zhí)行。
作用:
系統(tǒng)執(zhí)行由許多不同程序的執(zhí)行最終看到統(tǒng)一的效果。
有利于程序開(kāi)發(fā),維護(hù)。許多小功能文件分別開(kāi)發(fā)。
可以把系統(tǒng)功能開(kāi)發(fā)非常完善,有利于框架的整體協(xié)調(diào)工作。
系統(tǒng)升級(jí)也可以分為具體小功能模塊升級(jí)。
tag("app_begin"); function tag() 配置tags變量信息 B() function B() 實(shí)例化行為Behavior,調(diào)用run()方法 tags.php
快捷函數(shù)
U(分組/模塊/操作)根據(jù)參數(shù)獲得具體url地址
A(項(xiàng)目://分組/模塊)實(shí)例化模塊
R(項(xiàng)目://分組/模塊/操作)實(shí)例化模塊并調(diào)用相關(guān)方法
C(名稱)讀取配置變量信息
L(名稱)讀取指定語(yǔ)言變量信息
D(); D函數(shù)用于實(shí)例化Model 格式 項(xiàng)目://分組/模塊
RBAC (rol base access) 基于角色的權(quán)限控制
用戶權(quán)限分配:權(quán)限比較直觀,一項(xiàng)項(xiàng)分配。
缺點(diǎn):不利于權(quán)限管理。(分配繁瑣,管理混亂)
打包權(quán)限,分類管理。
利用角色對(duì)權(quán)限進(jìn)行打包。
3張數(shù)據(jù)表
權(quán)限數(shù)據(jù)表
角色數(shù)據(jù)表
系統(tǒng)用戶數(shù)據(jù)表
--用戶表 CREATE TABLE IF NOT EXISTS `sw_manager` ( `mg_id` int NOT NULL AUTO_INCREMENT, `mg_name` varchar(20) NOT NULL comment "名稱", `mg_pwd` varchar(32) NOT NULL comment "密碼", `mg_time` int unsigned NOT NULL comment "時(shí)間", `mg_role_id` tinyint(1) unsigned not null default 0 comment "角色id", PRIMARY KEY (`mg_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; --權(quán)限表 CREATE TABLE IF NOT EXISTS `sw_auth` ( `auth_id` smallint(6) unsigned NOT NULL AUTO_INCREMENT, `auth_name` varchar(20) NOT NULL comment "名稱", `auth_pid` smallint(6) unsigned NOT NULL comment "父id", `auth_c` varchar(32) not null default "" comment "模塊", `auth_a` varchar(32) not null default "" comment "操作方法", `auth_path` varchar(32) NOT NULL comment "全路徑", `auth_level` tinyint not null default 0 comment "權(quán)限級(jí)別012", PRIMARY KEY (`auth_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; --角色表 CREATE TABLE IF NOT EXISTS `sw_role` ( `role_id` smallint(6) unsigned NOT NULL AUTO_INCREMENT, `role_name` varchar(20) NOT NULL comment "角色名稱", `role_auth_ids` varchar(128) not null default "" comment "權(quán)限ids,1,2,5", `role_auth_ac` text comment "模塊-操作", PRIMARY KEY (`role_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
查詢用戶具體擁有的權(quán)限
// 用戶 -- 角色 -- 權(quán)限 // $_SESSION["mg_id"]; // manager role auth $model = M(); $sql = "select r.role_auth_ids from sw_manager as m join sw_role as r on m.mg_role_id = r.role_id where m.mg_id = " .$_SESSION["mg_id"]; $info = $model->query($sql); $auto_ids = $info[0]["role_auth_ids"]; // 查詢權(quán)限 // 查詢父權(quán)限 $sql = "select * from sw_auth where auth_id in ($auto_ids) and auth_level=0"; $p_auth_info = $model->query($sql); // 查詢子權(quán)限 $sql = "select * from sw_auth where auth_id in ($auto_ids) and auth_level=1"; $s_auth_info = $model->query($sql); $this->assign("p_auth", $p_auth_info); $this->assign("s_auth", $s_auth_info);
在普通的控制器新增父類,繼承當(dāng)前的父類,而非框架中的Action父類。
query($sql); $SqlAC = $SqlAC[0]["role_auth_ac"]; if (stripos($SqlAC, $AC) == false) { $this->error("沒(méi)有權(quán)限訪問(wèn)", U("Index/right")); exit("沒(méi)有權(quán)限訪問(wèn)"); } } } ?>
給角色分配權(quán)限
數(shù)據(jù)模擬權(quán)限控制
利用模擬數(shù)據(jù)進(jìn)行權(quán)限控制
為角色進(jìn)行具體權(quán)限分配(控制,view視圖模板,Model接收處理數(shù)據(jù)distributeAuth)
query($sql); $ac = ""; foreach($info as $v) { if ( !empty($v["auth_c"]) && !empty($v["auth_a"]) ){ $ac .= $v["auth_c"] . "-". $v["auth_a"] . ","; } } $ac = rtrim($ac, ","); // 拼湊SQL語(yǔ)句 $sql = "update sw_role set role_auth_ids="$ids", role_auth_ac="$ac" where role_id = " . $role_id; return $this->execute($sql); } } ?>
管理權(quán)限
添加權(quán)限
控制器:
order("auth_path")->select(); $this->assign("info", $info); $this->display(); } /** * 添加權(quán)限 */ public function add() { if ( !empty($_POST) ) { $auth = new AuthModel(); $rst = $auth->saveAuth($_POST); if ( $rst ) { $this->success("添加權(quán)限成功", U("Auth/showlist")); } } else { // 獲取全部權(quán)限 $info = D("Auth")->select(); $this->assign("info", $info); foreach( $info as $k => $v ) { if ($v["auth_level"] == 1) { $info[$k]["auth_name"] = "-/". $v["auth_name"]; } else if ( $v["auth_level"] == 2 ) { $info[$k]["auth_name"] = "-/-/" . $v["auth_name"]; } } // 組裝 array([]); $authinfo = array(); foreach($info as $v) { $authinfo[$v["auth_id"]] = $v["auth_name"]; } $this->assign("authinfo", $authinfo); $this->display(); } } } ?>
模型:
add($info); // 返回id 值 // auth_path // 全路徑 // 如果權(quán)限是頂級(jí)權(quán)限 auth_path === auth_id本身記錄id值; // 如果權(quán)限不是頂級(jí)權(quán)限 auth_path === 父級(jí)的auth_id - 本身id if ( $auth_pid == 0 ) { $auth_path = $auth_id; } else { // 獲得父級(jí)的auth_path $p_info = $this->find($auth_pid); $p_auth_path = $p_info["auth_path"]; $auth_path = $p_auth_path . "-" . $auth_id; } // 等級(jí) auth_level // 根據(jù)auth_level處理 10-11-35 查找"-"的個(gè)數(shù)就是auth_level的值 $auth_level = count(explode("-", $auth_path))-1; // update $data = array( "auth_id" => $auth_id, "auth_path" => $auth_path, "auth_level" => $auth_level ); return $this->save($data); } } ?>
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/22247.html
閱讀 2649·2021-09-30 09:48
閱讀 2641·2019-08-30 14:10
閱讀 2796·2019-08-29 11:22
閱讀 1896·2019-08-26 13:51
閱讀 2342·2019-08-26 12:02
閱讀 2484·2019-08-23 16:06
閱讀 3625·2019-08-23 14:06
閱讀 1151·2019-08-23 13:56