tp5的惟一可訪問目錄是public,即項目根目錄:php
http://localhost/tp5/public/html
開發規範:mysql
類庫、函數文件統一以.php爲後綴ajax
類(命名和路徑)和命名空間保持一致sql
類文件採用駝峯法命名,首字母大寫(類文件名 = 類名),其它文件用小寫+下劃線thinkphp
方法和屬性,採用駝峯法命名,首字母小寫數據庫
常量,大寫字母+下劃線json
配置參數,小寫字母+下劃線數組
應用類庫的根命名空間統一爲app,不建議更改緩存
若是你的應用下面只有一個模塊,那麼這個模塊的子目錄能夠省略,並設置參數:
'app_multi_module' => false,
控制器類比較靈活,能夠無需繼承任何基礎類庫
模型中,只有進行實際的數據庫查詢操做的時候,纔會進行數據庫的鏈接
能夠把模型層進行多層設計,分爲邏輯層/服務層/事件層
入口文件代碼:
// 定義項目路徑
define('APP_PATH', __DIR__ . '/../application/');
// 加載框架引導文件
require __DIR__ . '/../thinkphp/start.php';
start.php引導文件會執行:
加載系統常量定義;
加載環境變量定義文件;
註冊自動加載機制;
註冊錯誤和異常處理機制;
加載慣例配置文件;
執行應用;
統一使用return返回數據,而不是echo輸出,如非必要,請不要使用exit或者die中斷執行
URL是不區分大小寫的
http://localhost/index.php/Index/Blog/read
上面URL地址所有改成小寫,也是能夠的!
怎麼訪問有大小寫的控制器: 採用下劃線
http://localhost/index.php/Index/blog_test/read
2.若是但願區分大小寫: 修改配置
'url_convert' => false,
隱藏index.php:
一、httpd.conf: 加載mod_rewrite.so模塊
二、AllowOverride None 將None改成 All
三、在應用入口文件同級目錄添加.htaccess文件,內容以下:
<IfModule mod_rewrite.c>
Options +FollowSymlinks -Multiviews
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]
</IfModule>
common模塊是一個特殊的模塊, 默認是禁止直接訪問的, 通常用於放置一些公共的類庫用於其餘模塊的繼承
模塊的命名空間:
app\模塊名\controller\控制器名
例如, app\index\controller\Blog
修改app爲其它名稱: 修改配置
'app_namespace' => 'application',
若是隻有一個模塊(且只有一個控制器): 直接綁定
define('BIND_MODULE','index');//只有一個模塊index
define('BIND_MODULE','index/index');//且只有一個控制器index
訪問時, http://localhost/index.php/read 就能夠了
若是隻有一個模塊, 則能夠簡化目錄結構:
修改配置
'app_multi_module' => false,
調整目錄
同時, 訪問地址和命名空間均可以把模塊省略了
trait實現代碼複用:
在TP5中, 這麼用: (若是是php5.4以上的版本, load_trait能夠省略)
控制器輸出: 定義輸出的格式 'default_return_type'=>'json',
, 直接return(不用echo)
$data = ['name'=>'thinkphp','url'=>'thinkphp.cn'];
return ['data'=>$data,'code'=>1,'message'=>'操做完成'];
也能夠用函數 json、view、xml、jsonp 指定輸出的數據類型,
return json(['data'=>$data,'code'=>1,'message'=>'操做完成']);
修改配置文件所在目錄:
define('CONF_PATH', __DIR__.'/../config/');
擴展配置: 在應用或模塊配置目錄下面增長extra子目錄, 那麼這個目錄裏的全部配置參數會自動加載, 和其它配置進行合併。
自動讀取的配置文件都是二級配置參數, 一級配置名稱就是擴展配置的文件名。
好比, extra/aaa.php內容以下:
<?php
return [
'abc'=>'hello',
];
那麼應該這樣讀取:
echo Config::get("aaa.abc"); //輸出"hello"
配置參數名不區分大小寫, 建議所有使用小寫。
還能夠使用二維數組來配置更多的信息,
讀取-->
echo Config::get('user.type');
設置-->
Config::set([
'type' => 'file',
'prefix' => 'think'
],'cache');
修改配置格式: define('CONF_EXT', '.ini');
支持的又, .ini、.xml、.json 和 .php
例如,
手動導入配置:
Config::parse(APP_PATH.'my_config.xml','xml');//第二個參數能夠省略
或
$config = 'var1=val
var2=val';
Config::parse($config,'ini');//第二個參數不能省略
判斷是否存在某個配置:
Config::has('配置參數2');
或
config("?配置參數2");
動態配置參數:
config('配置參數','配置值');
或
config([
'配置參數1'=>'配置值',
'配置參數2'=>'配置值'
]);
配置參數做用域: 就比如命名空間, 這樣就能夠定義相同名稱的參數了
Config::set('user_type',1,'user'); //此參數歸入user做用域
環境變量配置:
在開發過程當中, 在應用根目錄下面的.env來模擬環境變量配置, 採用ini的格式, 例如
app_debug = true
app_trace = true
或(第二種是數組形式)
[database]
username = root
password = 123456
讀取環境變量-->
Env::get('database.username');//第二個參數表示: 默認值
能夠在應用配置中使用環境變量:
return [
'hostname' => Env::get('hostname','127.0.0.1'),
];
路由
+++++++++++++++++++++++++++++++++++++++++++++++++++
設置路由模式: 混合模式, 最好。
'url_route_on' => true,
'url_route_must'=> false,
對須要定義路由規則的訪問地址定義路由規則, 其它的仍然按照第一種普通模式的PATH_INFO模式訪問URL。
路由定義:
use think\Route;
Route::rule('new/:id','index/News/read');//第三個參數指定請求類型, 爲空表明任何類型。
請求類型包括: GET/POST/PUT/DELETE/*
簡化寫法: Route::get('new/:id','News/read');
多個請求類型: Route::rule('new/:id','News/read','GET|POST');
批量註冊路由規則:
Route::rule(['new/:id'=>'News/read','blog/:name'=>'Blog/detail']);
支持靜態地址: 'my' => 'Member/myinfo',
可選定義: 'blog/:year/[:month]'=>'Blog/archive',
徹底匹配: 在路由表達式最後使用$符號, 'new/:cate$'=> 'News/category',
全部路由都採用徹底匹配: 配置參數 'route_complete_match' => true,
支持額外參數: 'blog/:id'=>'blog/read?status=1&app_id=5',
批量註冊路由規則:
https://www.kancloud.cn/manual/thinkphp5/118031
給路由規則中的動態變量, 設置正則限制:
https://www.kancloud.cn/manual/thinkphp5/118033
路由規則中沒有固定的分隔符, 則使用組合變量:
https://www.kancloud.cn/manual/thinkphp5/131398
能夠設置一些路由匹配的條件: 用於驗證當前的路由規則是否有效
https://www.kancloud.cn/manual/thinkphp5/118034
路由到模塊/控制器、重定向地址、控制器、類、閉包函數:
https://www.kancloud.cn/manual/thinkphp5/118037
支持設置RESTFul請求的路由規則:
https://www.kancloud.cn/manual/thinkphp5/118035
爲了縮短URL地址, 使用路由別名:
https://www.kancloud.cn/manual/thinkphp5/163984
容許把相同前綴的路由定義進行合併分組:
https://www.kancloud.cn/manual/thinkphp5/118036
在沒有匹配到全部的路由規則後執行一條設定的路由, MISS路由:
https://www.kancloud.cn/manual/thinkphp5/151354
能夠使用閉包的方式定義一些特殊需求的路由, 而不須要執行控制器的操做方法了:
https://www.kancloud.cn/manual/thinkphp5/118038
使用路由綁定簡化URL或者路由規則的定義:
https://www.kancloud.cn/manual/thinkphp5/118040
路由規則和分組支持綁定模型數據:
https://www.kancloud.cn/manual/thinkphp5/208987
支持完整域名、子域名和IP部署的路由和綁定功能:
https://www.kancloud.cn/manual/thinkphp5/118039
當路由定義變化時, URL地址怎麼辦:
https://www.kancloud.cn/manual/thinkphp5/118041
控制器
+++++++++++++++++++++++++++++++++++++++++++++++++++
需繼承任何的基礎類, 命名空間默認以app爲根命名空間。
修改應用類庫命名空間:
'app_namespace' => 'application',
輸出轉換:
採用return時, 控制器會自動進行數據轉換處理。
在ajax請求時, 會自動轉換爲json。
'default_ajax_return' => 'html',//默認輸出類型
當設置輸出格式爲html時, 不會自動轉換。
若是你的控制器類繼承了\think\Controller類的話, 能夠定義控制器初始化方法_initialize
設置 beforeActionList屬性能夠指定某個方法爲其餘方法的前置操做: first、second、three、hello、data都是此類裏面的方法
protected $beforeActionList = [
'first',
'second' => ['except'=>'hello'],
'three' => ['only'=>'hello,data'],
];
使用redirect助手函數還能夠實現, 記住當前的URL後跳轉
redirect('News/category')->remember();
須要跳轉到上次記住的URL的時候使用:
redirect()->restore();
空操做:
public function _empty($name)
{
//把全部城市的操做解析到city方法
return $this->showCity($name);
}
空控制器:
<?php
namespace app\index\controller;
use think\Request;
class Error
{
public function index(Request $request)
{
//根據當前控制器名來判斷要執行那個城市的操做
$cityName = $request->controller();
return $this->city($cityName);
}
//注意 city方法 自己是 protected 方法
protected function city($name)
{
//和$name這個城市相關的處理
return '當前城市' . $name;
}
}
更改默認的空控制器名:
'empty_controller' => 'MyError',
多級控制器: 支持任意層次級別的控制器, 而且支持路由
namespace app\index\controller\one;
use think\Controller;
class Blog extends Controller
{
public function index()
{
return $this->fetch();
}
}
該控制器類的文件位置爲:
application/index/controller/one/Blog.php
分層控制器:
namespace app\index\event;
class Blog
{
public function update($id)
{
return 'update:'.$id;
}
}
//調用:
$event = controller('Blog', 'event');
echo $event->update(5);
//跨模塊:
$event = controller('Admin/Blog', 'event');
//直接調用分層控制器類的某個方法:
echo action('Blog/update', ['id' => 5], 'event');
自動定位控制器: 若是使用了多級控制器, 則開啓這個, 便於URL訪問
'controller_auto_search' => true,
>>https://www.kancloud.cn/manual/thinkphp5/156860
資源控制器: 輕鬆的建立RESTFul資源控制器
>>https://www.kancloud.cn/manual/thinkphp5/182949
請求
+++++++++++++++++++++++++++++++++++++++++++++++++++
請求信息: $request = Request::instance();
設置或獲取請求信息, 更詳細>>https://www.kancloud.cn/manual/thinkphp5/158834
檢查變量是否設置:
Request::instance()->has('id','get');
Request::instance()->has('name','post');
獲取param變量:
// 獲取當前請求的name變量
Request::instance()->param('name');
// 獲取當前請求的全部變量(通過過濾)
Request::instance()->param();
// 獲取當前請求的全部變量(原始數據)
Request::instance()->param(false);
// 獲取當前請求的全部變量(包含上傳文件)
Request::instance()->param(true);
獲取變量:
Request::instance()->get('id');
Request::instance()->get('id');
Request::instance()->put('name');
Request::instance()->request('id');
Request::instance()->server('PHP_SELF');
Request::instance()->session('user_id');
Request::instance()->cookie('user_id');
以上均可以用input助手函數來實現,
input('cookie.user_id');
變量過濾:
配置參數
'default_filter' => 'htmlspecialchars',
或設置過濾方法,
Request::instance()->filter(['strip_tags','htmlspecialchars']),
或添加過濾方法,
Request::instance()->param('username','','strip_tags,strtolower');
獲取部分變量:
// 只獲取GET請求的id和name變量, get參數能夠省略
Request::instance()->only(['id','name'],'get');
排除部分變量:
// 排除GET請求的id和name變量, get參數能夠省略
Request::instance()->except(['id','name'],'get');
變量修飾符:
input('post.name/s');
Request::instance()->get('id/d');
更改變量:
Request::instance()->get(['id'=>10]);
注意, 儘可能避免直接修改$_GET、$_POST數據, 也不能直接修改param變量。
請求類型: 取消了用於判斷請求類型的系統常量(如IS_GET, IS_POST等), 統一採用 think\Request類 處理請求類型
Request::instance()->isGet();
其它方法以下,
isPost,isPut,isDelete,isAjax,isPjax、isMobile、isHead、isPatch、isCli、isCgi
請求類型假裝:
1.在form表單裏提交_method變量
<input type="hidden" name="_method" value="PUT" >
2.配置參數: 表單請求類型假裝變量
'var_method' => '_m',
3.能夠對請求進行ajax假裝
http://localhost/index?_ajax=1
HTTP頭信息:
$info = Request::instance()->header();
echo $info['accept'];
或直接獲取,
$agent = Request::instance()->header('user-agent');
請求頭的名稱不區分大小寫。
僞靜態: 配置參數
'url_html_suffix' => 'html|shtml|xml',
方法注入:
1.注入
Request::hook('user','getUserInfo');
2.函數:
function getUserInfo(Request $request, $userId){
// 根據$userId獲取用戶信息
return $info;
}
3.在控制器中調用:
public function index(){
$info = Request::instance()->user($userId);
}
屬性注入:
1.注入
Request::instance()->user = new User;
2.獲取
Request::instance()->user;
參數綁定:
把URL地址(或者路由地址)中的變量做爲操做方法的參數直接傳入
假設定義了以下控制器,
namespace app\index\Controller;
class Blog {
public function archive($year='2016',$month='01'){
return 'year='.$year.'&month='.$month;
}
}
1.按名稱綁定
http://serverName/index.php/index/blog/archive/year/2016/month/06
//必須指定year、month參數的名稱, 順序隨意
2.按順序綁定
'url_param_type' => 1,//先修改配置參數爲1
而後,
http://serverName/index.php/index/blog/archive/2016/06
依賴注入: 針對訪問控制器進行依賴注入
1.架構方法注入
namespace app\index\controller;
use think\Request;
class Index{
protected $request;
public function __construct(Request $request) {
$this->request = $request;
}
public function hello() {
return 'Hello,' . $this->request->param('name') . '!';
}
}
2.操做方法注入
namespace app\index\controller;
use think\Request;
class Index{
public function hello(Request $request){
return 'Hello,' . $request->param('name') . '!';
}
}
請求緩存: 支持對請求地址設置緩存訪問, 並設置有效期(只針對GET有效)
1.路由
Route::get('new/:id','News/read',[
'cache' => [ 'cache_flag',3600]
]);
2.動態設置
Request::instance()->cache('blog/:id',3600);
Request::instance()->cache('__URL__',600);//以當期URL地址做爲緩存標識
Request::instance()->cache('[html]',600);//對html後綴的請求進行緩存
3.自動判斷緩存: 配置參數
'request_cache' => true,
'request_cache_expire' => 3600,
'request_cache_except' => [ //設置排除規則
'/blog/index',
'/user/member'
],
數據庫
+++++++++++++++++++++++++++++++++++++++++++++++++++
鏈接數據庫:
1.配置參數: database.php
return [
'type' => 'mysql',
'dsn' => '',
'hostname' => '127.0.0.1',
'database' => 'thinkphp',
'username' => 'root',
'password' => '',
'hostport' => '',
'params' => [],
'charset' => 'utf8',
'prefix' => 'think_',
'debug' => false,
// 數據庫部署方式:0 集中式(單一服務器),1 分佈式(主從服務器)
'deploy' => 0,
// 數據庫讀寫是否分離 主從式有效
'rw_separate' => false,
// 讀寫分離後 主服務器數量
'master_num' => 1,
// 指定從服務器序號
'slave_no' => '',
// 是否嚴格檢查字段是否存在
'fields_strict' => true,
];
2.每一個模塊能夠單獨配置: 相同參數無需重複配置
return [
'hostname' => '192.168.1.100',
'database' => 'admin',
];
3.配置參數: 斷線重連
'break_reconnect' => true,
4.在方法中動態定義鏈接信息
Db::connect('mysql://root:1234@127.0.0.1:3306/thinkphp#utf8');
或,
Db::connect('db_config1');//db_config1是配置參數
5.在模型中定義鏈接信息
namespace app\index\model;
use think\Model;
class User extends Model{
protected $connection = 'mysql://root:1234@127.0.0.1:3306/thinkphp#utf8';
//或
//protected $connection = 'db_config1';
}
基本使用:
Db::query('select * from think_user where id=?',[8]);
Db::execute('insert into think_user (id, name) values (?, ?)',[8,'thinkphp']);
Db::query('select * from think_user where id=:id',['id'=>8]);
Db::connect($config)->query('select * from think_user where id=:id',['id'=>8]);
CURD操做事件:
僅支持find、select、insert、update和delete方法。
Query::event('after_insert','callback');
或,
Query::event('before_select',function($options,$query){
return $result;
});
事務操做:
Db::transaction(function(){
Db::table('think_user')->find(1);
Db::table('think_user')->delete(1);
});
或手動控制事務,
// 啓動事務
Db::startTrans();
try{
Db::table('think_user')->find(1);
Db::table('think_user')->delete(1);
// 提交事務
Db::commit();
} catch (\Exception $e) {
// 回滾事務
Db::rollback();
}
監聽SQL:
Db::listen(function($sql, $time, $explain){
// 記錄SQL
echo $sql. ' ['.$time.'s]';
// 查看性能分析結果
dump($explain);
});
調用存儲過程:
$result = Db::query('call sp_query(?)',[8]);
數據集:
1.使用
$users = Db::name('user')->select();
if($users->isEmpty()){ //不能用empty判斷
echo '數據集爲空';
}
2. 返回的數據集對象是think\Collection, 包含這些方法
分佈式數據庫:
https://www.kancloud.cn/manual/thinkphp5/118061
查詢構造器(鏈式操做):
https://www.kancloud.cn/manual/thinkphp5/135175
查詢數據:
1.value: 返回某個字段的值
Db::table('think_user')->where('id',1)->value('name');
2.column: 返回某一列的值
Db::table('think_user')->where('status',1)->column('name','id');
3.分批處理數據集
Db::table('think_user')->chunk(100, function($users) {
foreach ($users as $user) {
//..
}
});
4.查詢json字段
Db::table('think_user')->where('info$.email','tp@qq.com')->find();
添加數據:
1.添加一條
$data = ['foo' => 'bar', 'bar' => 'foo'];
Db::name('user')->insert($data);
2.返回自增主鍵
$userId = Db::name('user')->getLastInsID();
或,
Db::name('user')->insertGetId($data);
3.添加多條
$data = [
['foo' => 'bar', 'bar' => 'foo'],
['foo' => 'bar1', 'bar' => 'foo1'],
['foo' => 'bar2', 'bar' => 'foo2']
];
Db::name('user')->insertAll($data);//返回添加成功的條數
更新數據:
1.有主鍵時
Db::table('think_user')
->update(['name' => 'thinkphp','id'=>1]);
2.延遲更新: 第三個參數
Db::table('think_user')->where('id', 1)->setInc('score', 1, 10);
3. 要更新的數據須要使用SQL函數或者其它字段
Db::table('think_user')
->where('id', 1)
->update([
'login_time' => ['exp','now()'],
'login_times' => ['exp','login_times+1'],
]);
刪除數據:
1.根據主鍵
Db::table('think_user')->delete(1);
或
Db::table('think_user')->delete([1,2,3]);
2.條件刪除
Db::table('think_user')->where('id','<',10)->delete();
查詢方法:
1.AND條件
Db::table('think_user')
->where('name','like','%thinkphp')
->where('status',1)
->find();
2.OR條件
Db::table('think_user')
->where('name','like','%thinkphp')
->whereOr('title','like','%thinkphp')
->find();
3.獲取表信息
Db::getTableInfo('think_user', 'fields');
//fields 全部字段、type 全部字段的類型、pk 表主鍵
//也可省略第二個參數, 表示獲取表的全部信息
查詢表達式:
統計查詢:
時間查詢:
https://www.kancloud.cn/manual/thinkphp5/165789
只返回sql語句:
1. fetchSql
$subQuery = Db::table('think_user')
->field('id,name')
->where('id','>',10)
->fetchSql(true)
->select();
2. buildSql
$subQuery = Db::table('think_user')
->field('id,name')
->where('id','>',10)
->buildSql();
3. select(false)
$subQuery = Db::table('think_user')
->field('id,name')
->where('id','>',10)
->select(false);
子查詢:
1. 在上面代碼的基礎上...
Db::table($subQuery.' a')
->where('a.name','like','thinkphp')
->order('id','desc')
->select();
生成的SQL語句爲:
SELECT * FROM ( SELECT `id`,`name` FROM `think_user` WHERE `id` > 10 ) a WHERE a.name LIKE 'thinkphp' ORDER BY `id` desc
2. 使用閉包...
Db::table('think_user')
->where('id','IN',function($query){
$query->table('think_profile')->where('status',1)->field('id');
})
->select();
原生操做: 最好使用參數綁定, 安全!
Db::query("select * from think_user where id=? AND status=?",[8,1]);
Db::execute("update think_user set name=:name where
status=:status",['name'=>'thinkphp','status'=>1]);
模型
+++++++++++++++++++++++++++++++++++++++++++++++++++
;