一革骨、基礎
- 1整吆、官網(wǎng)安裝TP5 http://www.thinkphp.cn/down/framework.html 還可以通過Composer和GIT安裝
- 2叶组、目錄結(jié)構(gòu)
project 應用部署目錄
├─application 應用目錄(可設置)
│ ├─common 公共模塊目錄(可更改)
│ ├─index 模塊目錄(可更改)
│ │ ├─config.php 模塊配置文件
│ │ ├─common.php 模塊函數(shù)文件
│ │ ├─controller 控制器目錄
│ │ ├─model 模型目錄
│ │ ├─view 視圖目錄
│ │ └─ ... 更多類庫目錄
│ ├─command.php 命令行工具配置文件
│ ├─common.php 應用公共(函數(shù))文件
│ ├─config.php 應用(公共)配置文件
│ ├─database.php 數(shù)據(jù)庫配置文件
│ ├─tags.php 應用行為擴展定義文件
│ └─route.php 路由配置文件
├─extend 擴展類庫目錄(可定義)
├─public WEB 部署目錄(對外訪問目錄)
│ ├─static 靜態(tài)資源存放目錄(css,js,image)
│ ├─index.php 應用入口文件
│ ├─router.php 快速測試文件
│ └─.htaccess 用于 apache 的重寫
├─runtime 應用的運行時目錄(可寫壳繁,可設置)
├─vendor 第三方類庫目錄(Composer)
├─thinkphp 框架系統(tǒng)目錄
│ ├─lang 語言包目錄
│ ├─library 框架核心類庫目錄
│ │ ├─think Think 類庫包目錄
│ │ └─traits 系統(tǒng) Traits 目錄
│ ├─tpl 系統(tǒng)模板目錄
│ ├─.htaccess 用于 apache 的重寫
│ ├─.travis.yml CI 定義文件
│ ├─base.php 基礎定義文件
│ ├─composer.json composer 定義文件
│ ├─console.php 控制臺入口文件
│ ├─convention.php 慣例配置文件
│ ├─helper.php 助手函數(shù)文件(可選)
│ ├─LICENSE.txt 授權說明文件
│ ├─phpunit.xml 單元測試配置文件
│ ├─README.md README 文件
│ └─start.php 框架引導文件
├─build.php 自動生成定義文件(參考)
├─composer.json composer 定義文件
├─LICENSE.txt 授權說明文件
├─README.md README 文件
├─think 命令行入口文件
- 3坟募、入口文件
默認自帶的入口文件位于public/index.php
// 定義應用目錄
define('APP_PATH', __DIR__ . '/../application/');
// 加載框架引導文件
require __DIR__ . '/../thinkphp/start.php';
- 4缆毁、資源訪問
訪問資源問件是不會影響正常的操作訪問番川,只有當資源不存在時才會解析到入口問件,一般提示模塊不存在脊框。
資源文件一般放在public目錄的子目錄下,不要在public目錄外的任何位置放置資源文件颁督。
public
├─index.php 應用入口文件
├─static 靜態(tài)資源目錄
│ ├─css 樣式目錄
│ ├─js 腳本目錄
│ └─img 圖像目錄
- 5、控制器
當訪問一個駝峰命名的控制器時浇雹,在url中輸入大寫的控制器名稱會報錯沉御,因為默認的URL訪問是不區(qū)分大小寫的,全部都會轉(zhuǎn)換為小寫的控制器名昭灵。
<?php
namespace app\index\controller;
class HelloWorld
{
public function index($name = 'World')
{
return 'Hello,' . $name . '吠裆!';
}
}
//直接用http://http://localhost/public/index/HelloWorld訪問會報錯,控制器不存在
//應該用http://http://localhost/public/index/hello_world訪問
//除非在配置文件中設置了關閉url自動轉(zhuǎn)換'url_convert' => false
//通過在url中添加參數(shù)來為控制器中的操作方法傳遞參數(shù)http://http://localhost/public/?name=php
如果控制器命名方式是駝峰的烂完,在進行訪問時必須改為小寫试疙;如果控制器中的操作方法是private和protect類型時,無法直接通過url訪問到該操作抠蚣。
- 6祝旷、視圖
在給控制器添加視圖文件功能時,首先在該模塊下創(chuàng)建view目錄嘶窄,然后添加模板文件view/inde/hello.html
<html>
<head>
<title>hello {$name}</title>
</head>
<body>
hello, {$name}!
</body>
</html>
在控制器方法中進行模板渲染輸出操作
<?php
namespace app\index\controller;
use think\Controller;
class Index extends Controller
{
public function hello($name = 'thinkphp')
{
$this->assign('name', $name);
return $this->fetch();
}
}
用use導入類庫怀跛,Index可以直接繼承,并直接使用封裝好的assign和fetch方法進行模板變量賦值和渲染輸出柄冲。
二吻谋、URL和路由
- 1、參數(shù)傳入
以hello方法為例羊初,可以直接在url中添加參數(shù)
http://tp5.com/index.php/index/index/hello/name/thinkphp
當需要傳入兩個參數(shù)時滨溉,繼續(xù)在url中添加參數(shù)什湘,可以有兩種方式
http://tp5.com/index.php/index/index/hello/name/thinkphp/city/shanghai
http://tp5.com/index.php/index/index/hello?city=shanghai&name=thinkphp
還可以進一步對URL地址做簡化,前提就是我們必須明確參數(shù)的順序代表的變量晦攒,我們更改下URL參數(shù)的獲取方式闽撤,把應用配置文件中的“url_param_type=>1”,此時必須嚴格按照參數(shù)的順序進行添加脯颜。
- 2哟旗、定義路由
在application/route.php定義路由,可以通過直接返回一個數(shù)組形式定義路由栋操,也可以通過think的Route類來動態(tài)定義路由規(guī)則闸餐,兩者可以混用。一旦定義路由規(guī)則矾芙,以前的url將會失效舍沙。
return [
// 路由參數(shù)name為可選,[]表示參數(shù)為可選
'hello/[:name]' => 'index/hello',
];
- 3剔宪、完美匹配
上面定義的路由只要是以hello開頭的都可以進行匹配拂铡,在路由規(guī)則后加上$符號,表示完美匹配葱绒,只匹配次個hello方法感帅。
return [
// 路由參數(shù)name為可選
'hello/[:name]$' => 'index/hello',
];
//http://tp5.com/hello // 正確匹配
//http://tp5.com/hello/thinkphp // 正確匹配
//http://tp5.com/hello/thinkphp/val/value // 不會匹配
- 4、閉包定義
定義一些特殊需求的路由地淀,不用執(zhí)行控制器里的方法失球。
return [
// 定義閉包
'hello/[:name]' => function ($name) {
return 'Hello,' . $name . '!';
},
];
- 5、路由參數(shù)
return [
// 定義路由的請求類型和后綴
'hello/[:name]' => ['index/hello', ['method' => 'get', 'ext' => 'html']],
];
//http://tp5.com/hello // 無效
//http://tp5.com/hello.html // 有效
//http://tp5.com/hello/thinkphp // 無效
//http://tp5.com/hello/thinkphp.html // 有效
- 6帮毁、變量規(guī)則
用正則的方式指定變量規(guī)則实苞,彌補了動態(tài)變量無法限制具體的類型問題。
<?php
namespace app\index\controller;
class Blog
{
public function get($id)
{
return '查看id=' . $id . '的內(nèi)容';
}
public function read($name)
{
return '查看name=' . $name . '的內(nèi)容';
}
public function archive($year, $month)
{
return '查看' . $year . '/' . $month . '的歸檔內(nèi)容';
}
}
路由規(guī)則
return [
'blog/:year/:month' => ['blog/archive', ['method' => 'get'], ['year' => '\d{4}', 'month' => '\d{2}']],
'blog/:id' => ['blog/get', ['method' => 'get'], ['id' => '\d+']],
'blog/:name' => ['blog/read', ['method' => 'get'], ['name' => '\w+']],
];
- 7烈疚、路由分組
如上路由擁有相同的前綴硬梁,可以將其進行分組,路由分組一定程度上可以提高路由檢測的效率胞得。
return [
'[blog]' => [
':year/:month' => ['blog/archive', ['method' => 'get'], ['year' => '\d{4}', 'month' => '\d{2}']],
':id' => ['blog/get', ['method' => 'get'], ['id' => '\d+']],
':name' => ['blog/read', ['method' => 'get'], ['name' => '\w+']],
],
];
三、請求與相應
- 1屹电、請求對象
Request對象的作用是與客戶端交互阶剑,收集客戶端的Form、Cookies危号、超鏈接牧愁,或者收集服務器端的環(huán)境變量。獲取url:
傳統(tǒng)方法:
public function hello($name = 'World')
{
$request = Request::instance();
// 獲取當前URL地址 不含域名
echo 'url: ' . $request->url() . '<br/>';
return 'Hello,' . $name . '外莲!';
}
繼承think\Controller:
class Index extends Controller
{
public function hello($name = 'World')
{
// 獲取當前URL地址 不含域名
echo 'url: ' . $this->request->url() . '<br/>';
return 'Hello,' . $name . '猪半!';
}
}
自動注入請求對象:
public function hello(Request $request, $name = 'World')
{
// 獲取當前URL地址 不含域名
echo 'url: ' . $request->url() . '<br/>';
return 'Hello,' . $name . '兔朦!';
}
- 2、動態(tài)綁定屬性
通過給Request請求對象綁定屬性磨确,方便全局調(diào)用沽甥,首先定義一個新建一個控制器,給Request請求對象綁定屬性乏奥,以后的控制器可以通過繼承該控制器直接調(diào)用其屬性摆舟。
class Base extends Controller
{
public function _initialize()
{
$user = User::get(Session::get('user_id'));
Request::instance()->bind('user',$user);
}
}
class Index extends Base
{
public function index(Request $request)
{
echo $request->user->id;
echo $request->user->name;
}
}
- 3、助手函數(shù)
如果既沒有繼承think\Controller也不想給操作方法添加額外的Request對象參數(shù)邓了,那么也可以使用系統(tǒng)提供的助手
class Index
{
public function hello($name = 'World')
{
// 獲取當前URL地址 不含域名
echo 'url: ' . request()->url() . '<br/>';
return 'Hello,' . $name . '恨诱!';
}
}
- 4、獲取請求參數(shù)
使用param方法統(tǒng)一獲取當前請求變量骗炉,該方法最大的優(yōu)勢是讓你不需要區(qū)分當前請求類型而使用不同的全局變量或者方法照宝,并且可以滿足大部分的參數(shù)需求。
class Index
{
public function hello(Request $request)
{
echo '請求參數(shù):';
dump($request->param());
echo 'name:'.$request->param('name');
}
}
通過input助手函數(shù)簡化Request對象的param方法句葵。
class Index
{
public function hello()
{
echo '請求參數(shù):';
dump(input());
echo 'name:'.input('name');
}
}
param方法獲取參數(shù)會自動判斷當前請求厕鹃,參數(shù)優(yōu)先級為:路由變量 > 當前請求變量(_GET變量。除了param方法外笼呆,還可以通過get熊响、post、cookie诗赌、file方法獲取參數(shù)汗茄。
獲取參數(shù)信息:
class Index
{
public function hello(Request $request)
{
echo '請求方法:' . $request->method() . '<br/>';
echo '資源類型:' . $request->type() . '<br/>';
echo '訪問IP:' . $request->ip() . '<br/>';
echo '是否AJax請求:' . var_export($request->isAjax(), true) . '<br/>';
echo '請求參數(shù):';
dump($request->param());
echo '請求參數(shù):僅包含name';
dump($request->only(['name']));
echo '請求參數(shù):排除name';
dump($request->except(['name']));
}
}
獲取URL信息:
class Index
{
public function hello(Request $request,$name = 'World')
{
// 獲取當前域名
echo 'domain: ' . $request->domain() . '<br/>';
// 獲取當前入口文件
echo 'file: ' . $request->baseFile() . '<br/>';
// 獲取當前URL地址 不含域名
echo 'url: ' . $request->url() . '<br/>';
// 獲取包含域名的完整URL地址
echo 'url with domain: ' . $request->url(true) . '<br/>';
// 獲取當前URL地址 不含QUERY_STRING
echo 'url without query: ' . $request->baseUrl() . '<br/>';
// 獲取URL訪問的ROOT地址
echo 'root:' . $request->root() . '<br/>';
// 獲取URL訪問的ROOT地址
echo 'root with domain: ' . $request->root(true) . '<br/>';
// 獲取URL地址中的PATH_INFO信息
echo 'pathinfo: ' . $request->pathinfo() . '<br/>';
// 獲取URL地址中的PATH_INFO信息 不含后綴
echo 'pathinfo: ' . $request->path() . '<br/>';
// 獲取URL地址中的后綴信息
echo 'ext: ' . $request->ext() . '<br/>';
return 'Hello,' . $name . '!';
}
}
獲取當前模塊/控制器/操作信息:
public function hello(Request $request, $name = 'World')
{
echo '模塊:'.$request->module();
echo '<br/>控制器:'.$request->controller();
echo '<br/>操作:'.$request->action();
}
- 5铭若、響應對象——自動輸出
一般情況下洪碳,不需要關注Response對象本身,只需要在控制器的操作方法中返回數(shù)據(jù)即可叼屠,系統(tǒng)會自動判斷是否為Ajax請求瞳腌,是的話自動輸出default_ajax_return配置的輸出類型,否則自動輸出default_return_type匹配的輸出類型镜雨。
<?php
namespace app\index\controller;
class Index
{
public function hello()
{
$data = ['name' => 'thinkphp', 'status' => '1'];
//通過手動添加參數(shù)的控制嫂侍,來輸出不同格式的參數(shù),無需更改配置文件
//return json($data);
return $data;
}
}
默認情況下輸出是html輸出荚坞。因此上述代碼會報錯挑宠,只有更改配置文件后,才能正常輸出颓影。
// 默認輸出類型
'default_return_type' => 'json',
輸出類型 快捷方法
渲染模板輸出 view
JSON輸出 json
JSONP輸出 jsonp
XML輸出 xml
頁面重定向 redirect
- 6各淀、頁面跳轉(zhuǎn)
namespace app\index\controller;
class Index
{
use \traits\controller\Jump;
public function index($name='')
{
if ('thinkphp' == $name) {
$this->success('歡迎使用ThinkPHP
5.0','hello');
} else {
$this->error('錯誤的name','guest');
}
}
public function hello()
{
return 'Hello,ThinkPHP!';
}
public function guest()
{
return 'Hello,Guest!';
}
}
- 7、頁面重定向
namespace app\index\controller;
class Index
{
use \traits\controller\Jump;
public function index($name='')
{
if ('thinkphp' == $name) {
$this->redirect('http://thinkphp.cn');
} else {
$this->success('歡迎使用ThinkPHP','hello');
}
}
public function hello()
{
return 'Hello,ThinkPHP!';
}
}
在沒有引入Jump trait的情況下诡挂,可以使用助手函數(shù)redirect函數(shù)進行重定向碎浇。
namespace app\index\controller;
class Index
{
public function index($name='')
{
if ('thinkphp' == $name) {
return redirect('http://thinkphp.cn');
} else {
return 'Hello,ThinkPHP!';
}
}
}