MODULE_NAME
CONTROLLER_NAME
ACTION_NAME
目錄名: 所有小寫+下劃線 文件名: 類文件採用首字母大寫的駝峯命名法定義 其餘文件爲小寫+下劃線命名 類名: 和類文件名保持一致(採用首字母大寫駝峯命名法) 5以前有UserController這樣的Controller、model等後綴 函數名、屬性: 首字母小寫的駝峯命名法 常量: 大寫和下劃線 配置名: 小寫+下劃線 數據庫 表和字段命名: 必須小寫+下劃線 類庫函數文件以.php結尾而5以前是.class.php 類的文件名以命名空間定義。且命名空間和類文件所在的路徑一致
須要大寫的 類文件名:類文件採用駝峯法命名(首字母大寫) 類名:類名和類文件名保持一致,統一採用駝峯法命名(首字母大寫) 類方法:命名使用駝峯法(首字母小寫),例如 getUserName; 類屬性:命名使用駝峯法(首字母小寫),例如 tableName 常量:以大寫字母和下劃線命名,例如 APP_PATH 函數:小寫+下劃線 目錄:目錄使用小寫+下劃線 文件:除類文件其餘均以小寫+下劃線
模板提替換php
tp5.0-:(包含5.0)css
'view_replace_str' => [
'__PUBLIC__'=>'xxx',
],
注意:5.0.24可直接使用以下模板替換變量:只針對根目錄爲public時沒有問題(__STATIC__ 的值爲 /static ,若是更目錄改爲與tp3默認的同樣的話就少一個public了)html
__ROOT__ :項目目錄正則表達式
__STATIC__ :項目目錄下的static目錄sql
__JS__ :項目目錄下的static/js目錄thinkphp
__CSS__:項目目錄下的static/css目錄數據庫
tp5.1+(5.1及以上)json
'tpl_replace_string' => [
'__PUBLIC__' => 'xxx',
],
安全api
異常封裝:數組
開發單獨開啓sql日誌
在index.php定義:
\think\Log::init([ 'type'=>'File', 'path'=>APP_PATH.'/sql_log', 'level'=>['sql'] ]);
tp5數據庫操做:
原生:
use think\Db; Db:query('select * from user where id=?',[$id])
構造器:前面的方法是不會真正的執行sql的只有select或者find以後才能調用
除了find、select以外還有update(更新)、delete(刪除)、insert(刪除)
還有聚合查詢(count、max、min、avg、sum),。。。等等
use think\Db; $result=Db::table('banner_item')->where('banner_id','=',$id)->select();
除了上面的執行語句的方法還有許多輔助的方法、他們也被成爲鏈式操做方法
table、where、alias、field、strict、limit、page、order、group、having、join、union、distinct、lock、cache、comment、fethSql、force、partition、failException、sequence
帶*表示能夠屢次調用
連貫操做 | 做用 | 支持的參數類型 |
---|---|---|
where* | 用於AND查詢 | 字符串、數組和對象 |
whereOr* | 用於OR查詢 | 字符串、數組和對象 |
wheretime* | 用於時間日期的快捷查詢 | 字符串 |
table | 用於定義要操做的數據表名稱 | 字符串和數組 |
alias | 用於給當前數據表定義別名 | 字符串 |
field* | 用於定義要查詢的字段(支持字段排除) | 字符串和數組 |
order* | 用於對結果排序 | 字符串和數組 |
limit | 用於限制查詢結果數量 | 字符串和數字 |
page | 用於查詢分頁(內部會轉換成limit) | 字符串和數字 |
group | 用於對查詢的group支持 | 字符串 |
having | 用於對查詢的having支持 | 字符串 |
join* | 用於對查詢的join支持 | 字符串和數組 |
union* | 用於對查詢的union支持 | 字符串、數組和對象 |
view* | 用於視圖查詢 | 字符串、數組 |
distinct | 用於查詢的distinct支持 | 布爾值 |
lock | 用於數據庫的鎖機制 | 布爾值 |
cache | 用於查詢緩存 | 支持多個參數 |
relation* | 用於關聯查詢 | 字符串 |
with* | 用於關聯預載入 | 字符串、數組 |
bind* | 用於數據綁定操做 | 數組或多個參數 |
comment | 用於SQL註釋 | 字符串 |
force | 用於數據集的強制索引 | 字符串 |
master | 用於設置主服務器讀取數據 | 布爾值 |
strict | 用於設置是否嚴格檢測字段名是否存在 | 布爾值 |
sequence | 用於設置Pgsql的自增序列名 | 字符串 |
failException | 用於設置沒有查詢到數據是否拋出異常 | 布爾值 |
partition | 用於設置分表信息 | 數組 字符串 |
import 語法:
boolen import(class, baseUrl, ext)
參數 | 說明 |
---|---|
class | 必須,表示要導入的類庫,採用命名空間的方式。 |
baseUrl | 可選,表示導入的基礎路徑,省略的話系統採用默認的規則,具體見下文。 |
ext | 可選,表示導入的類庫後綴,默認是 .class.php 。 |
這個方法默認會以ThinkPHP\Library爲相對起始目錄 (這個目錄包含了'Think','Org','Behavior','Com','Vendor'系統基類)
import("ORG.Util.Page"); // 導入 ThinkPHP系統目錄/Lib/ORG/Util/Page.class.php 文件
若是是當前項目(),能夠簡化爲:import("@.Action.UserAction");
邏輯:若是import截取第一個參數以@開頭表明是當前項目那麼他的起始目錄爲 APP_PATH.MODULE_NAME.'/' 即application/Home/
若是截取的第一個參數是'Think','Org','Behavior','Com','Vendor'中的其中一個那麼他的起始目錄爲ThinkPHP/Library
若是以上兩個都不是那麼它的起始目錄爲APP_PATH 即 application/
因此:import('Home.Test.Alipay');和import('@.Test.Alipay');都能定位到aplication/Home/Test/Alipay.class.php
要想放在ThinkPHP/Library 那麼Test文件夾必須放到library下的'Think','Org','Behavior','Com','Vendor’這幾個目錄裏咱們用import調用時能夠
import("ORG.Test.Alipay");import("Behavior.Test.Alipay");等等
非Composer安裝的第三方庫通常在extends目錄 須要定義命名空間,不然不會自動加載
//該文件那麼實際的類文件位置應該是: 1.extend/first/second/Foo.php namespace first\second; class Foo { } //使用first.second.Foo類的時候,直接實例化便可使用,例如: $foo = new \first\second\Foo(); //或者: use first\second\Foo; $foo = new Foo(); //無命名空間則用: Loader::import('first.second.Foo'); $foo = new \Foo();
vendor('alipaycustom.AopEncrypt'); //vendor/alipaycustom/AopEncrypt.php
vendor('alipaycustom.alipaycustom#function'); //vendor/alipaycustom/alipaycustom.function.php
配置:
改變配置文件的放置目錄
publuc/index.php文件定義 define("CONF_PATH",__DIR__."/../conf/"); 配置文件就從默認的 application/config.php 變成了 application/conf/config.php
擴展配置:
將配置文件放入extra目錄:如aplipay.php
獲取:config(文件名.配置的鍵名) 如 config("aplipay.public_key")
場景配置: 好比 家裏和公司
在公司環境中,咱們在應用配置文件中配置: 'app_status'=>'office' 那麼就會自動加載該狀態對應的配置文件(默認位於
application/office.php
)
場景配置文件和應用配置文件config.php
是同樣的定義。
若是咱們回家後,咱們修改定義爲:'app_status'=>'home' 那麼就會自動加載該狀態對應的配置文件(位於
application/home.php
)。
thinkphp 架構URL訪問中有這麼一句 RewriteRule ^(.*)$ index.php/$1
url生成
thinkphp5- U()
thinkphp5+ url('模塊/控制器/方法','參數')
注意多級控制器的狀況下url的寫法
application/admin/Controller/user/AdminUser.php controller下多了一個目錄 正確的寫法 <a href="{:url('admin/user.adminuser/getuser')}">aaaaaaaaaa</a> 錯誤的寫法 <a href="{:url('admin/user/adminuser/getuser')}">bbbbb</a>
同理:路由也是按上面的方式獲取:Route::("hello/:id","admin/user.adminuser/getuser");
路由:
參數配置:
// 是否開啓路由
'url_route_on' => true,
// 路由配置文件(支持配置多個)
'route_config_file' => ['route'],
// 路由使用完整匹配
'route_complete_match' => false,
// 是否強制使用路由 爲true的話必需要爲每一個url配置路由才能訪問哦 因此纔開發階段能夠false 這樣原url和路由url均可以訪問到
'url_route_must' => false,
路由配置:
application/route.php
return [ //'news/:id' => '控制器/模塊/方法' 'news/:id' => 'index/index/info', ]; //配置之後訪問localhost/index.php/index/index/info/id/5.html就訪問不到了 //必須訪問localhost/index.php/news/5.html //怎麼獲取路由後的url呢? //thinkphp5 的url函數如今能夠自動生成路由的路徑啦! //可是以前的版本必須本身寫代碼實現
獲取php全局變量
thinkphp5- :
I()
thinkphp5+ :
input()
獲取全部:input("param.");
獲取全部post:input("post.");
獲取get:input("get.");
模板輸出:
thinkphp5-:
$this->display()
thinkphp5+:
return $this->fetch()
模板使用函數
{$data.name|md5} <?php echo (md5($data['name'])); ?> {$name|md5|strtoupper|substr=0,3} {:substr(strtoupper(md5($name)),0,3)} <?php echo (substr(strtoupper(md5($name)),0,3)); ?> 多個參數: {$create_time|date="y-m-d",###} <?php echo (date("y-m-d",$create_time)); ?> {$data.name|substr=0,3} {$data.name|substr=###,0,3} <?php echo (substr($data['name'],0,3)); ?>
自動驗證
格式:
array(
①驗證字段1,
② 驗證規則,
③錯誤提示,
④驗證條件(0:存在字段就驗證(默認);1:必須驗證;2:值不爲空就驗證),
⑤附加規則,
⑥驗證時間(1:新增 2:更新 3:新增和更新(默認)),
⑦額外參數 數組形式 這個數組的每一個值都是函數的一個參數(爲callbck和function的時候)
),
額外參數試例
$create_data['identifier']=$identifier; $extraArr=array( 'ext'=>array('1','2','3','4'), 'size'=>array(100,200,300), 88 ) $rules=array( array('identifier','checkedIdentifier','格式不正確',1,'function',3,),$extraArr), ); function checkedIdentifier($param,$val1,$val2,$val3){ dump($param);//$create_data['identifier']的值 dump($val1);//第七個參數數組的第一個鍵值ext'=>array('1','2','3','4') dump($val2);//'size'=>array(100,200,300) dump($val3);//88 }
靜態驗證:在model裏定義$_validate屬性;定義好驗證規則後,就能夠在使用create方法建立數據對象的時候自動調用:
namespace Home\Model; use Think\Model; class UserModel extends Model{ protected $_validate = array( array('verify','require','驗證碼必須!'), //默認狀況下用正則進行驗證 array('name','','賬號名稱已經存在!',0,'unique',1), // 在新增的時候驗證name字段是否惟一 array('value',array(1,2,3),'值的範圍不正確!',2,'in'), // 當值不爲空的時候判斷是否在一個範圍內 array('repassword','password','確認密碼不正確',0,'confirm'), // 驗證確認密碼是否和密碼一致 array('password','checkPwd','密碼格式不正確',0,'function'), // 自定義函數驗證密碼格式
array('password','md5','密碼格式不正確',0,'function'), // 自定義函數驗證密碼格式
array('img','checkImg','圖片格式不正確',1,'callback',3,array('ext'=>array('jpg','jpeg','png','gif'))), ); /** * 自定義圖片後綴驗證 */ public function checkImg($param,$value){ $exts=''; foreach($value as $val){ $exts.="[".$val."]{1}|"; } $exts=substr($exts,0,-1);; $str=$param; $preg="/^[\S]+[.]?(".$exts.")$/"; if( preg_match($preg ,$str)){ return true; }else{ return false; } } }
動態驗證:動態驗證不依賴模型類的定義,因此一般用M函數實例化模型就能夠
$rules = array( array('verify','require','驗證碼必須!'), //默認狀況下用正則進行驗證 array('name','','賬號名稱已經存在!',0,'unique',1), // 在新增的時候驗證name字段是否惟一 array('value',array(1,2,3),'值的範圍不正確!',2,'in'), // 當值不爲空的時候判斷是否在一個範圍內 array('repassword','password','確認密碼不正確',0,'confirm'), // 驗證確認密碼是否和密碼一致 array('password','checkPwd','密碼格式不正確',0,'function'), // 自定義函數驗證密碼格式
array('tel','/^1[34578]\d{9}$/','手機號碼不對..1!',0,'regex',3),// 必填
); $User = M("User"); // 實例化User對象 if (!$User->validate($rules)->create()){ // 若是建立失敗 表示驗證沒有經過 輸出錯誤提示信息 exit($User->getError()); }else{ // 驗證經過 能夠進行其餘數據操做 }
tp3驗證規則:系統內置或自定義的規則
//內置驗證require不能爲空 array('require','require','數據不能爲空!',1), //內置驗證email,驗證郵箱格式 array('email','email','郵箱格式不正確',1), //內置驗證url,驗證網址 array('url','url','URL地址不正確',1), //內置驗證currency,驗證貨幣 array('currency','currency','貨幣格式不正確',1), //內置驗證zip,驗證郵編 array('zip','zip','郵政編碼不正確',1), //內置驗證number,驗證是否是正整數 array('number','number','不是正整數',1), //內置驗證integer,驗證是否是整數 array('integer','integer','不是整數',1), //內置驗證double,驗證是否是浮點數,正負都可 array('double','double','不是浮點數',1), //內置驗證english,驗證是否是純英文 array('english','english','不是純英文',1),
tp3附加規則:配合驗證規則使用
規則 | 說明 |
---|---|
regex | 正則驗證,定義的驗證規則是一個正則表達式(默認) array('tel','/^1[34578]\d{9}$/','手機號碼不對!',0,'regex',3),// 必填 array('name','/^[A-Za-z0-9\x{4e00}-\x{9fa5}]{2,20}$/u','不是漢字字母數字組成',1,'regex',3), |
function | 函數驗證,定義的驗證規則是一個函數名 array('password','checkPwd','密碼格式不正確',0,'function'), // 自定義函數驗證密碼格式 |
callback | 方法驗證,定義的驗證規則是當前模型類的一個方法 array('user', 'checkLength', '用戶名必須在 3-5 位', 0, 'callback', 3,array(3,5)), |
confirm | 驗證表單中的兩個字段是否相同,定義的驗證規則是一個字段名 array('user', 'name', '兩個用戶名對比不一樣!',0,'confirm'),
|
equal | 驗證是否等於某個值,該值由前面的驗證規則定義 array('user', '李炎恢', '值不對等', 0, 'equal'),
|
notequal | 驗證是否不等於某個值,該值由前面的驗證規則定義(3.1.2版本新增) array('user', '李炎恢', '值不能相等', 0, 'notequal'),
|
in | 驗證是否在某個範圍內,定義的驗證規則能夠是一個數組或者逗號分割的字符串 array('user', array(1,2,3), '不在指定範圍', 0, 'in'), |
notin | 驗證是否不在某個範圍內,定義的驗證規則能夠是一個數組或者逗號分割的字符串(3.1.2版本新增) array('user', array(1,2,3), '不得在指定範圍', 0, 'notin'), |
length | 驗證長度,定義的驗證規則能夠是一個數字(表示固定長度)或者數字範圍(例如3,12 表示長度從3到12的範圍) array('user', '3,5', '不得小於 3 位,不得大於 5 位', 0, 'length'),
|
between | 驗證範圍,定義的驗證規則表示範圍,可使用字符串或者數組,例如1,31或者array(1,31) array('user', array(3,5), '必須是 3-5 之間的數字', 0, 'between'), array('user', '3,5', '必須是 3-5 之間的數字', 0, 'between'), |
notbetween | 驗證不在某個範圍,定義的驗證規則表示範圍,可使用字符串或者數組(3.1.2版本新增) array('user', array(3,5), '必須不是 3-5 之間的數字', 0, 'notbetween'), array('user', '3,5', '必須不是 3-5 之間的數字', 0, 'notbetween'), |
expire | 驗證是否在有效期,定義的驗證規則表示時間範圍,能夠到時間,例如可使用 2012-1-15,2013-1-15 表示當前提交有效期在2012-1-15到2013-1-15之間,也可使用時間戳定義
array('user', '2014-1-10,2015-10-10', '時間已過時', 0, 'expire'),
|
ip_allow | 驗證IP是否容許,定義的驗證規則表示容許的IP地址列表,用逗號分隔,例如201.12.2.5,201.12.2.6 array('user', '127.0.0.1', '當前 IP 沒有被容許', 0, 'ip_allow'),
|
ip_deny | 驗證IP是否禁止,定義的驗證規則表示禁止的ip地址列表,用逗號分隔,例如201.12.2.5,201.12.2.6 array('user', '127.0.0.1', '當前 IP 被禁止', 0, 'ip_deny'),
|
unique | 驗證是否惟一,系統會根據字段目前的值查詢數據庫來判斷是否存在相同的值,當表單數據中包含主鍵字段時unique不可用於判斷主鍵字段自己
array('name','','賬號名稱已經存在!',0,'unique',1), // 在新增的時候驗證name字段是否惟一 |
thinkphp5+:
對某個字段屢次驗證
namespace app\index\validate; use think\Validate; class Comments extends Validate { protected $regex = [ 'zip' => '/^1[3|4|5|8][0-9]{9}$/']; protected $rule = [ 'name' => 'require', 'phone' => "require|regex:zip", 'phone_time' => 'require', ]; protected $message = [ 'name.require' => '姓名不能爲空', 'phone.require' => '聯繫方式不能爲空', 'phone.regex' => '聯繫方式格式不正確', 'phone_time.require' => '接聽時段不能爲空', ]; }
自動完成
protected $_auto=array( array('create_time','time',self::MODEL_INSERT,'function'), // 對create_time字段在新增的時候寫入當前時間戳 array('update_time','time',self::MODEL_UPDATE,'function'), // 對update_time字段在更新的時候寫入當前時間戳 array('pwd','md5',3,'function') , // 對password字段在新增和編輯的時候使md5函數處理 );
字段映射
/** * 字段映射 * @var array */ protected $_map=array( 'member'=>'name', 'password'=>'pwd', );
參數綁定:
手動綁定:
$Model = M('User'); $where['id'] = ':id'; $where['name'] = ':name'; $bind[':id'] = array(I('id'),\PDO::PARAM_INT); $bind[':name'] = array(I('name'),\PDO::PARAM_STR); $list = $Model->where($where)->bind($bind)->select();
自動綁定:
自動綁定不支持參數類型等額外設置,若是有必要請使用上面的手動綁定方式。
'DB_BIND_PARAM' => true //須要開啓這個配置 而後 以下: $Model = M('User'); $Model->name = 'thinkphp'; $Model->email = 'thinkphp@qq.com'; $Model->add(); 等效於: $Model = M('User'); $Model->name = ':name'; $Model->email = ':email'; $bind[':name'] = 'thinkphp'; $bind[':email'] = 'thinkphp@qq.com'; $Model->bind($bind)->add();
關聯模型:
HSA_ONE:一對一,一個員工只有一個檔案表(BELONGS_TO 也可用做一對一 能夠理解他是son BELONGS_TO它的parent)
支持:
屬性 | 描述 |
---|---|
class_name | 要關聯的模型類名 |
mapping_name | 關聯的映射名稱,用於獲取數據用 該名稱不要和當前模型的字段有重複,不然會致使關聯數據獲取的衝突。 |
foreign_key | 關聯的外鍵名稱 |
mapping_fields | 關聯要查詢的字段 |
condition | 關聯條件 |
as_fields | 直接把關聯的字段值映射成數據對象中的某個字段 |
mapping_type | 關聯類型 |
BELONGS_TO:多對一,一個員工只屬於一個部門,可是部門裏有多個員工
屬性 | 描述 |
---|---|
class_name | 要關聯的模型類名 |
mapping_name | 關聯的映射名稱,用於獲取數據用 該名稱不要和當前模型的字段有重複,不然會致使關聯數據獲取的衝突。 |
foreign_key | 關聯的外鍵名稱 |
mapping_fields | 關聯要查詢的字段 |
condition | 關聯條件 |
parent_key | 自引用關聯的關聯字段 默認爲parent_id 自引用關聯是一種比較特殊的關聯,也就是關聯表就是當前表。 |
as_fields | 直接把關聯的字段值映射成數據對象中的某個字段 |
mapping_type | 關聯類型 |
HAS_MANY:一對多,一個員工有多張銀行卡,可是一張銀行卡只屬於一個員工
屬性 | 描述 |
---|---|
class_name | 要關聯的模型類名 |
mapping_name | 關聯的映射名稱,用於獲取數據用 該名稱不要和當前模型的字段有重複,不然會致使關聯數據獲取的衝突。 |
foreign_key | 關聯的外鍵名稱 |
parent_key | 自引用關聯的關聯字段 默認爲parent_id |
condition | 關聯條件 關聯查詢的時候會自動帶上外鍵的值,若是有額外的查詢條件,能夠經過定義關聯的condition屬性。 |
mapping_fields | 關聯要查詢的字段 默認狀況下,關聯查詢的關聯數據是關聯表的所有字段,若是隻是須要查詢個別字段,能夠定義關聯的mapping_fields屬性。 |
mapping_limit | 關聯要返回的記錄數目 |
mapping_order | 關聯查詢的排序 |
MANY_TO_MANY:多對多,一個員工能夠屬於多個組,每一個組能夠有多個員工
屬性 | 描述 |
---|---|
class_name | 要關聯的模型類名 |
mapping_name | 關聯的映射名稱,用於獲取數據用 該名稱不要和當前模型的字段有重複,不然會致使關聯數據獲取的衝突。 |
foreign_key | 關聯的外鍵名稱 外鍵的默認規則是當前數據對象名稱_id |
relation_foreign_key | 關聯表的外鍵名稱 默認的關聯表的外鍵名稱是表名_id |
mapping_limit | 關聯要返回的記錄數目 |
mapping_order | 關聯查詢的排序 |
relation_table | 多對多的中間關聯表名稱 |
thinkphp5+
查詢:
//原生 $result=Db::query('select * from banner_item where img_id=?',[3]); //var_dump($result); $result=Db::table('banner_item')->where('banner_id','=',$id)->select();
一對一:
一對多:
多對多:
banner(記錄有個項目有多少個輪播) banner_item(每一個輪播的輪換個數) image(圖片)
id id banner_id img_id id
1 1 4 4
2 1 5 5
3 1 6 6
banner:banneritem 一對多 (hasMany)
banner_item:img 一對一 (belongsTo,它也是多對一) 這裏用hasOne會報錯 由於外鍵在banner_item
注意:
一對一關係,存在主從關係(主表和從表 ),主表不包含外鍵,從表包含外鍵。
hasOne 和 belongsTo 都是一對一關係,區別:
在主表(不包含外鍵)的模型中創建關聯關係,用 hasOne
在從表(包含外鍵)模型中創建關聯關係,用 belongsTo
model/Banner.php
namespace app\api\model; use think\Model; use think\Db; class Banner extends Model{ public function items(){ //banner關聯 Banner_item表 return $this->hasMany('BannerItem','banner_id','id'); } }
model/BannerItem.php
<?php namespace app\api\model; use think\Model; class BannerItem extends Model{ public function img(){ //bannner_item 關聯image表 //return $this->belongsTo('Image','img_id','id'); return $this->hasOne('Image','img_id','id'); } }
model/Image.php
<?php namespace app\api\model; use think\Model; class Image extends Model{ }
在控制器方法中調用:
需引入 use app\api\Model\Banner as BannerModel;//這裏的Banner和Model的Banner重名
//$banner=BannerModel::with('items')->find($id);//單表關聯 $banner=BannerModel::with(['items','items.img'])->find($id);//多表關聯(參數是定義的方法名 )
參數代表Banner類裏有一個封裝關聯關係items方法 items.img 表示items方法裏關聯的表模型又關聯了一個封裝關聯關係的img方法
改造:將關聯查詢封裝到Banner.php中
model/Banner.php
<?php namespace app\api\model; use think\Model; use think\Db; class Banner extends Model{ public function items(){ return $this->hasMany('BannerItem','banner_id','id'); } public static function getBannerById($id){ //TODO:根據bannerid號獲取banner信息 $result=self::with(['items','items.img'])->find($id); return $result; } }
控制器方法裏這麼調用:
<?php namespace app\api\controller\v1; use think\Controller; use app\api\Model\Banner as BannerModel;//這裏的Banner和Model的Banner重名 class Banner extends controller{ public function getBanner($id){ $banner=BannerModel::getBannerById($id); //$banner->toArray();//拿到$data查出來的對象轉數組 還有toJson() //unsetc($data['delete_time']);//隱藏數據中的delete_time,不推薦 $banner->hidden(['delete_time','update_time']);//隱藏數據中的某些數據 $banner->visiable(['id','name']);//只顯示數據中的某些值 return $banner;
return json($banner);
} }
圖片路徑不全,咱們怎麼和查詢出來的數據進行拼接
tp5能夠用讀取器(獲取器)來解決
如image表的url字段有個數據爲/woman.jpg 而且咱們將圖片存到public/images目錄下的
application/setting.php 定義
return [ 'img_prefix'=>'http://www.tp5.lichihua.com/images' ];
獲取能夠
$img_prefix=config('setting.img_prefix');
組裝:我麼能夠在model/Image.php中定義一個讀取器的方法格式爲 get+當前模型的某個字段名+Attr
<?php namespace app\api\model; use think\Model; class Image extends Model{ protected $hidden=['id','from','delete_time','update_time']; /** * url讀取器 組裝以後用model查詢出來的url就是完整的路徑了 * from字段爲1表示本站圖片 2爲網絡資源即帶有http:完整url路徑 * @param max $value 自動獲取的image表中url字段的值 * @param max $data image的全部字段數據 * @return string 返回組裝好圖片的url地址 */ public function getUrlAttr($value,$data){ $finalUrl=$value; if ($data['from']==1) { $finalUrl = config('setting.img_prefix').$value; } return $finalUrl; } }
讀取器觸發的方式,模型調用字段屬性的時候自動調用
以下面的代碼也能調用getUrlAttr讀取器方法:上面的getBannerById方法在 return $banner;時因爲關聯模型會關聯到Image框架會自動的調用Image模型的每個模型屬性沒有顯示的調用!
$img=new Image(); $img->url;
可是其餘的模型字段也有相似的需求呢?咱們就須要新建一個基類集成mode而後其餘的model集成這個基類而後將讀取器放到基類裏,
可是有個弊端當繼承基類的模型可能隱式的調用有奪取器的字段時,他會自動調用讀取器的,這不是咱們所指望的,因此咱們須要改造一下!
<?php namespace app\api\model; use think\Model; class BaseModel extends Model { public function prefixImgUrl($value,$data){ $finalUrl=$value; if ($data['from']==1) { $finalUrl = config('setting.img_prefix').$value; } return $finalUrl; } } <?php namespace app\api\model; use app\api\model\BaseModel; class Image extends BaseModel{ protected $hidden=['id','from','delete_time','update_time']; public function getUrlAttr($value,$data){ return $this->prefixImgUrl($value,$data); } }
版本控制:
能夠在route.php中這樣定義:
Route::get("api/:version/banner/:id","api/:version.Banner/getBanner");
而後:
http://www.tp5.lichihua.com/index.php/api/v2/Banner/1
http://www.tp5.lichihua.com/index.php/api/v1/Banner/1
session、cookie
/* SESSION設置 */ 'SESSION_AUTO_START' => true, // 是否自動開啓Session 'SESSION_OPTIONS' => array(), // session 配置數組 支持type name id path expire domain 等參數 'SESSION_TYPE' => '', // session hander類型 默認無需設置 除非擴展了session hander驅動 'SESSION_PREFIX' => '', // session 前綴 //'VAR_SESSION_ID' => 'session_id', //sessionID的提交變量
/** * session管理函數 * @param string|array $name session名稱 若是爲數組則表示進行session設置 * @param mixed $value session值 * @return mixed */ function session($name='',$value='') { $prefix = C('SESSION_PREFIX');//配置文件的session前綴 if(is_array($name)) { // session初始化 在session_start 以前調用
// 第一個參數維數組且存在prefix鍵 則將此值賦值給配置的SESION_PREFIX if(isset($name['prefix'])) C('SESSION_PREFIX',$name['prefix']);
//若是配置文件從新定義的session_id 且$_COOKIE、$_POST、$_GET存在該值 則設置sessionid 若是傳入的數組存在id則設置sesionid(相似祕鑰) if(C('VAR_SESSION_ID') && isset($_REQUEST[C('VAR_SESSION_ID')])){ session_id($_REQUEST[C('VAR_SESSION_ID')]); }elseif(isset($name['id'])) { session_id($name['id']); } if('common' == APP_MODE){ // 其它模式可能不支持 ini_set('session.auto_start', 0); } if(isset($name['name'])) session_name($name['name']); if(isset($name['path'])) session_save_path($name['path']); if(isset($name['domain'])) ini_set('session.cookie_domain', $name['domain']); if(isset($name['expire'])) { ini_set('session.gc_maxlifetime', $name['expire']); ini_set('session.cookie_lifetime', $name['expire']); } if(isset($name['use_trans_sid'])) ini_set('session.use_trans_sid', $name['use_trans_sid']?1:0); if(isset($name['use_cookies'])) ini_set('session.use_cookies', $name['use_cookies']?1:0); if(isset($name['cache_limiter'])) session_cache_limiter($name['cache_limiter']); if(isset($name['cache_expire'])) session_cache_expire($name['cache_expire']); if(isset($name['type'])) C('SESSION_TYPE',$name['type']); if(C('SESSION_TYPE')) { // 讀取session驅動 $type = C('SESSION_TYPE'); $class = strpos($type,'\\')? $type : 'Think\\Session\\Driver\\'. ucwords(strtolower($type)); $hander = new $class(); session_set_save_handler( array(&$hander,"open"), array(&$hander,"close"), array(&$hander,"read"), array(&$hander,"write"), array(&$hander,"destroy"), array(&$hander,"gc")); } // 啓動session if(C('SESSION_AUTO_START')) session_start(); }elseif('' === $value){ if(''===$name){ // 獲取所有的session return $prefix ? $_SESSION[$prefix] : $_SESSION; }elseif(0===strpos($name,'[')) { // session 操做 if('[pause]'==$name){ // 暫停session session_write_close(); }elseif('[start]'==$name){ // 啓動session session_start(); }elseif('[destroy]'==$name){ // 銷燬session $_SESSION = array(); session_unset(); session_destroy(); }elseif('[regenerate]'==$name){ // 從新生成id session_regenerate_id(); } }elseif(0===strpos($name,'?')){ // 檢查session $name = substr($name,1); if(strpos($name,'.')){ // 支持數組 list($name1,$name2) = explode('.',$name); return $prefix?isset($_SESSION[$prefix][$name1][$name2]):isset($_SESSION[$name1][$name2]); }else{ return $prefix?isset($_SESSION[$prefix][$name]):isset($_SESSION[$name]); } }elseif(is_null($name)){ // 清空session if($prefix) { unset($_SESSION[$prefix]); }else{ $_SESSION = array(); } }elseif($prefix){ // 獲取session if(strpos($name,'.')){ list($name1,$name2) = explode('.',$name); return isset($_SESSION[$prefix][$name1][$name2])?$_SESSION[$prefix][$name1][$name2]:null; }else{ return isset($_SESSION[$prefix][$name])?$_SESSION[$prefix][$name]:null; } }else{ if(strpos($name,'.')){ list($name1,$name2) = explode('.',$name); return isset($_SESSION[$name1][$name2])?$_SESSION[$name1][$name2]:null; }else{ return isset($_SESSION[$name])?$_SESSION[$name]:null; } } }elseif(is_null($value)){ // 刪除session if(strpos($name,'.')){ list($name1,$name2) = explode('.',$name); if($prefix){ unset($_SESSION[$prefix][$name1][$name2]); }else{ unset($_SESSION[$name1][$name2]); } }else{ if($prefix){ unset($_SESSION[$prefix][$name]); }else{ unset($_SESSION[$name]); } } }else{ // 設置session if(strpos($name,'.')){ list($name1,$name2) = explode('.',$name); if($prefix){ $_SESSION[$prefix][$name1][$name2] = $value; }else{ $_SESSION[$name1][$name2] = $value; } }else{ if($prefix){ $_SESSION[$prefix][$name] = $value; }else{ $_SESSION[$name] = $value; } } } return null; }
sesion初始化及設置
//初始化 sesion(array('name'=>'replacePHPSESSID'),'expire'=>3600,'id'=>'9h1bano5p1lvt6tac5nvbboac7'); //設置session session('loginSign',1)
//進行付款處理 事務實現付款 $user=M('User'); $user->startTrans(); // $new_user_money=$user_money-$order_total_money; //用戶的積分增長 $user_score= $user_info[0]['user_score']+$order_total_money; $user_status=$user->where(array('user_id'=>$user_id))->save(array('user_score'=>$user_score)); // $order_status=M("Order")->where(array('order_id'=>$order_id))->save(array('order_state'=>'已付款')); //判斷兩個是否都執行成功 if($order_status&&$user_status){ $user->commit(); //付款成功就顯示到頁面上 //把信息寫到用戶消費表 $user_payment['user_payment_money']="-".$order_total_money; $user_payment['user_payment_why']="在線購買"; $user_payment['user_payment_time']=time(); $user_payment['user_id']=$user_id; M('UserPayment')->add($user_payment); //刪除session中保存的order_id信息 session(C("USER_ORDER_ID"),null); //顯示信息到前臺去 $this->order_no=$order_info[0]['order_no']; $this->order_total_money=$order_info[0]['order_total_money']; }else{ //執行失敗就回滾 $user->rollback(); $this->error('付款失敗'); exit; }
多表的回滾:
$m=D('YourModel');//或者是M(); $m2=D('YouModel2'); $m->startTrans();//在第一個模型裏啓用就能夠了,或者第二個也行 $result=$m->where('刪除條件')->delete(); $result2=m2->where('刪除條件')->delete(); if($result && $result2){ $m->commit();//成功則提交 }else{ $m->rollback();//不成功,則回滾 }
common 沒法經過 域名/common/index/index 這種方式訪問
咱們須要在某個模塊下定義一個commom方法 而後實例化並調用他 如:aplication/index/controller/index.php
//application/index/controller/Index.php <?php namespace app\index\controller; use app\common\controller\Index as commonIndex; class Index{ public function index(){} public function common(){ $common = new commomIndex(); return $common->index(); } } //aplication/common/controller/Index.php <?php namespace app\common\controller; class Index { public function index(){ } }
//application/index/controller/User.php <?php namespace app\index\controller; use app\common\controller\User as commonUser; class User extends commonUser{ public function demo(){ return $this->showName('zhangsan'); } } //aplication/common/controller/User.php <?php namespace app\common\controller; class User { public function showName($name=' '){ return "my name is {$name}"; } }
Controller:
屬性:
$view : \think\View 視圖類實例 賦值__construct $request : \think\Request Request 實例 賦值__construct $failException: bool 驗證失敗是否拋出異常 $batchValidate:bool 是否批量驗證 $beforeActionList:array 前置操做方法列表
方法:
_initialize:初始化操做 beforeAction($method, $options = []):前置操做 fetch($template = '', $vars = [], $replace = [], $config = []):加載模板輸出 display($content = '', $vars = [], $replace = [], $config = []):渲染內容輸出 assign($name, $value = ''):模板變量賦值 engine($engine):初始化模板引擎 validateFailException($fail = true):設置驗證失敗後是否拋出異常 validate($data, $validate, $message = [], $batch = false, $callback = null):驗證數據
model: