前面的話
ThinkPHP是一個免費開源的,快速、簡單的面向對象的輕量級PHP開發框架,是為了敏捷WEB應用開發和簡化企業應用開發而誕生的。ThinkPHP從誕生以來一直秉承簡潔實用的設計原則,在保持出色的性能和至簡的代碼的同時,也注重易用性。遵循Apache2
開源許可協議發布,意味著可以免費使用ThinkPHP,甚至允許把基于ThinkPHP開發的應用開源或商業產品發布/銷售。ThinkPHP5.0版本是一個顛覆和重構版本,采用全新的架構思想,引入了更多的PHP新特性,優化了核心,減少了依賴,實現了真正的惰性加載,支持composer,并針對API開發做了大量的優化,包括路由、日志、異常、模型、數據庫、模板引擎和驗證等模塊都已經重構,不適合原有3.2項目的升級,但絕對是新項目的首選
目錄結構
thinkphp5安裝完成后,初始目錄結構如下所示
www WEB部署目錄(或者子目錄) ├─application 應用目錄 │ ├─common 公共模塊目錄(可以更改) │ ├─module_name 模塊目錄 │ │ ├─config.php 模塊配置文件 │ │ ├─common.php 模塊函數文件 │ │ ├─controller 控制器目錄 │ │ ├─model 模型目錄 │ │ ├─view 視圖目錄 │ │ └─ ... 更多類庫目錄 │ │ │ ├─command.php 命令行工具配置文件 │ ├─common.php 公共函數文件 │ ├─config.php 公共配置文件 │ ├─route.php 路由配置文件 │ ├─tags.php 應用行為擴展定義文件 │ └─database.php 數據庫配置文件 │ ├─public WEB目錄(對外訪問目錄) │ ├─index.php 入口文件 │ ├─router.php 快速測試文件 │ └─.htaccess 用于apache的重寫 │ ├─thinkphp 框架系統目錄 │ ├─lang 語言文件目錄 │ ├─library 框架類庫目錄 │ │ ├─think Think類庫包目錄 │ │ └─traits 系統Trait目錄 │ │ │ ├─tpl 系統模板目錄 │ ├─base.php 基礎定義文件 │ ├─console.php 控制臺入口文件 │ ├─convention.php 框架慣例配置文件 │ ├─helper.php 助手函數文件 │ ├─phpunit.xml phpunit配置文件 │ └─start.php 框架入口文件 │ ├─extend 擴展類庫目錄 ├─runtime 應用的運行時目錄(可寫,可定制) ├─vendor 第三方類庫目錄(Composer依賴庫) ├─build.php 自動生成定義文件(參考) ├─composer.json composer 定義文件 ├─LICENSE.txt 授權說明文件 ├─README.md README 文件 ├─think 命令行入口文件
開發規范
【目錄和文件】
1、目錄不強制規范,駝峰和小寫+下劃線模式均支持
2、類庫、函數文件統一以.php
為后綴
3、類的文件名均以命名空間定義,并且命名空間的路徑和類庫文件所在路徑一致
4、類名和類文件名保持一致,統一采用駝峰法命名(首字母大寫)
【函數和類、屬性命名】
1、類的命名采用駝峰法,并且首字母大寫,例如 User
、UserType
,默認不需要添加后綴,例如UserController
應該直接命名為User
2、函數的命名使用小寫字母和下劃線(小寫字母開頭)的方式,例如 get_client_ip
3、方法的命名使用駝峰法,并且首字母小寫,例如 getUserName
4、屬性的命名使用駝峰法,并且首字母小寫,例如 tableName
、instance
5、以雙下劃線“__”打頭的函數或方法作為魔法方法,例如 __call
和 __autoload
【常量和配置】
1、常量以大寫字母和下劃線命名,例如 APP_PATH
和 THINK_PATH
2、配置參數以小寫字母和下劃線命名,例如 url_route_on
和url_convert
【數據表和字段】
1、數據表和字段采用小寫加下劃線方式命名,并注意字段名不要以下劃線開頭,例如 think_user
表和 user_name
字段,不建議使用駝峰和中文作為數據表字段命名
常見概念
ThinkPHP5.0
應用基于MVC
(模型-視圖-控制器)的方式來組織。下面是一些常見概念
【入口文件】
用戶請求的PHP文件,負責處理一個請求(注意,不一定是URL請求)的生命周期,最常見的入口文件就是index.php
,有時候也會為了某些特殊的需求而增加新的入口文件,例如給后臺模塊單獨設置的一個入口文件admin.php
或者一個控制器程序入口think
都屬于入口文件
【應用】
應用在ThinkPHP
中是一個管理系統架構及生命周期的對象,由系統的 \think\App
類完成,應用通常在入口文件中被調用和執行,具有相同的應用目錄(APP_PATH
)的應用我們認為是同一個應用,但一個應用可能存在多個入口文件。應用具有自己獨立的配置文件、公共(函數)文件
【模塊】
一個典型的應用是由多個模塊組成的,這些模塊通常都是應用目錄下面的一個子目錄,每個模塊都有自己獨立的配置文件、公共文件和類庫文件
【控制器】
每個模塊擁有獨立的MVC
類庫及配置文件,一個模塊下面有多個控制器負責響應請求,而每個控制器其實就是一個獨立的控制器類。
控制器主要負責請求的接收,并調用相關的模型處理,并最終通過視圖輸出。嚴格來說,控制器不應該過多的介入業務邏輯處理
一個典型的Index
控制器類如下:
namespace app\index\controller; class Index { public function index() { return 'hello,thinkphp!'; } }
【操作】
一個控制器包含多個操作(方法),操作方法是一個URL訪問的最小單元。
下面是一個典型的Index
控制器的操作方法定義,包含了兩個操作方法:
namespace app\index\controller; class Index { public function index() { return 'index'; } public function hello($name) { return 'Hello,'.$name; } }
操作方法可以不使用任何參數,如果定義了一個非可選參數,則該參數必須通過用戶請求傳入,如果是URL請求,則通常是$_GET
或者$_POST
方式傳入
【模型】
模型類通常完成實際的業務邏輯和數據封裝,并返回和格式無關的數據
【視圖】
控制器調用模型類后返回的數據通過視圖組裝成不同格式的輸出。視圖根據不同的需求,來決定調用模板引擎進行內容解析后輸出還是直接輸出。
視圖通常會有一系列的模板文件對應不同的控制器和操作方法,并且支持動態設置模板目錄
【驅動】
系統很多的組件都采用驅動式設計,從而可以更靈活的擴展,驅動類的位置默認是放入核心類庫目錄下面,也可以重新定義驅動類庫的命名空間而改變驅動的文件位置
【行為】
行為(Behavior)是在預先定義好的一個應用位置執行的一些操作。類似于AOP
編程中的“切面”的概念,給某一個切面綁定相關行為就成了一種類AOP
編程的思想。所以,行為通常是和某個位置相關,行為的執行時間依賴于綁定到了哪個位置上。
要執行行為,首先要在應用程序中進行行為偵聽,例如:
// 在app_init位置偵聽行為 \think\Hook::listen('app_init');
然后對某個位置進行行為綁定:
// 綁定行為到app_init位置 \think\Hook::add('app_init','\app\index\behavior\Test');
一個位置上如果綁定了多個行為的,按照綁定的順序依次執行,除非遇到中斷
【命名空間】
ThinkPHP5
采用了PHP
的命名空間進行類庫文件的設計和規劃,并且符合PSR-4
的自動加載規范、
入口文件
ThinkPHP5.0
版本的默認自帶的入口文件位于public/index.php
(實際部署的時候public
目錄為應用對外訪問目錄),入口文件內容如下:
// 定義應用目錄 define('APP_PATH', __DIR__ . '/../application/'); // 加載框架引導文件 require __DIR__ . '/../thinkphp/start.php';
這段代碼的作用就是定義應用目錄APP_PATH
和加載ThinkPHP
框架的入口文件,這是所有基于ThinkPHP
開發應用的第一步
官方提供的默認應用的實際目錄結構和說明如下:
├─application 應用目錄(可設置)
│ ├─index 模塊目錄(可更改)
│ │ ├─config.php 模塊配置文件
│ │ ├─common.php 模塊公共文件
│ │ ├─controller 控制器目錄
│ │ ├─model 模型目錄
│ │ └─view 視圖目錄
│ │
│ ├─command.php 命令行工具配置文件
│ ├─common.php 應用公共文件
│ ├─config.php 應用配置文件
│ ├─tags.php 應用行為擴展定義文件
│ ├─database.php 數據庫配置文件
│ └─route.php 路由配置文件
5.0
版本采用模塊化的設計架構,默認的應用目錄下面只有一個index
模塊目錄,如果要添加新的模塊可以使用控制臺命令來生成。
切換到命令行模式下,進入到應用根目錄并執行如下指令:
php think build --module demo
就會生成一個默認的demo模塊,包括如下目錄結構:
├─demo
│ ├─controller 控制器目錄
│ ├─model 模型目錄
│ ├─view 視圖目錄
│ ├─config.php 模塊配置文件
│ └─common.php 模塊公共文件
同時也會生成一個默認的Index
控制器文件
資源訪問
網站的資源文件訪問不會影響正常的操作訪問,只有當訪問的資源文件不存在的時候才會解析到入口文件,一般就會提示模塊不存在的錯誤。
網站的資源文件一般放入public
目錄的子目錄下面,例如下面是一個建議規范:
public ├─index.php 應用入口文件 ├─static 靜態資源目錄 │ ├─css 樣式目錄 │ ├─js 腳本目錄 │ └─img 圖像目錄
訪問資源文件的URL路徑是:
http://tp5.com/static/css/style.css http://tp5.com/static/js/common.js http://tp5.com/static/img/picture.jpg
如果沒有設置域名綁定,而是使用子目錄方式訪問的話,那么可能的資源訪問地址是:
http://localhost/public/static/css/style.css http://localhost/public/static/js/common.js http://localhost/public/static/img/picture.jpg
調試模式
ThinkPHP
支持調試模式,默認情況下是開啟狀態(5.0.10+
版本開始,默認關閉調試模式,需要自己開啟)。調試模式以除錯方便優先,而且在異常的時候可以顯示盡可能多的信息,所以對性能有一定的影響。
強烈建議開發者在使用ThinkPHP
開發的過程中使用調試模式,5.0
默認情況下可以捕獲到任何細微的錯誤并拋出異常,這樣可以更好的獲取錯誤提示和避免一些問題和隱患,不要畏懼錯誤,要勇敢面對,并消除隱患。
開發完成后,實際進行項目部署的時候,修改應用配置文件(application/config.php
)中的app_debug
配置參數:
// 關閉調試模式 'app_debug' => false,
控制器
找到index
模塊的Index
控制器(文件位于application/index/controller/Index.php
注意大小寫),把Index
控制器類的index
方法修改為Hello,World!
<?php namespace app\index\controller; class Index { public function index() { return 'Hello,World!'; } }
訪問URL地址時,就會看到Hello,World!
的輸出結果
如果要訪問一個駝峰命名的控制器,例如我們把上面的例子改成一個HelloWorld
控制器
<?php namespace app\index\controller; class HelloWorld { public function index($name = 'World') { return 'Hello,' . $name . '!'; } }
默認情況下正確的方法是使用下面的URL進行訪問
http://tp5.com/index.php/index/hello_world
下面的訪問地址是錯誤的
http://tp5.com/index.php/index/HelloWorld
因為默認的URL訪問是不區分大小寫的,全部都會轉換為小寫的控制器名,除非在應用配置文件中,設置了關閉url自動轉換如下:
'url_convert' => false,
那么就可以正常訪問
http://tp5.com/index.php/index/HelloWorld
如果要繼承一個公共的控制器類,可以使用:
<?php namespace app\index\controller; use app\index\controller\Base; class Index extends Base { public function index() { return 'Hello,World!'; } }
可以為操作方法定義參數,例如:
<?php namespace app\index\controller; class Index { public function index($name = 'World') { return 'Hello,' . $name . '!'; } }
當帶name
參數訪問入口文件地址(例如 http://tp5.com?name=ThinkPHP
)的時候,在瀏覽器中可以看到如下輸出:
Hello,ThinkPHP!
控制器類可以包括多個操作方法,但如果操作方法是protected
或者private
類型的話,是無法直接通過URL訪問到該操作的,也就是說只有public
類型的操作方法才是可以通過URL訪問的。
下面來驗證下,把Index
控制器類的方法修改為:
<?php namespace app\index\controller; class Index { public function hello() { return 'hello,thinkphp!'; } public function test() { return '這是一個測試方法!'; } protected function hello2() { return '只是protected方法!'; } private function hello3() { return '這是private方法!'; } }
當我們訪問如下URL地址的時候,前面兩個是正常訪問,后面兩個則會顯示異常
http://tp5.com/index.php/index/index/hello http://tp5.com/index.php/index/index/test http://tp5.com/index.php/index/index/hello2 http://tp5.com/index.php/index/index/hello3
視圖
現在我們在給控制器添加視圖文件功能,我們在application/index
目錄下面創建一個view
目錄,然后添加模板文件view/index/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 think\Controller;
就必須使用class Index extends \think\Controller
Index
控制器類繼承了 think\Controller
類之后,我們可以直接使用封裝好的assign
和fetch
方法進行模板變量賦值和渲染輸出。
fetch
方法中我們沒有指定任何模板,所以按照系統默認的規則(視圖目錄/控制器/操作方法)輸出了view/index/hello.html
模板文件。
接下來,我們在瀏覽器訪問
http://tp5.com/index.php/index/index/hello
輸出:
hello,thinkphp!
讀取數據
在開始之前,我們首先在數據庫demo
中創建一個think_data
數據表(這里以mysql
數據庫為例):
CREATE TABLE IF NOT EXISTS `think_data`( `id` int(8) unsigned NOT NULL AUTO_INCREMENT, `data` varchar(255) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ; INSERT INTO `think_data`(`id`,`data`) VALUES (1,'thinkphp'), (2,'php'), (3,'framework');
首先我們需要在應用的數據庫配置文件application/database.php
中添加數據庫的連接信息如下:
return [ // 數據庫類型 'type' => 'mysql', // 服務器地址 'hostname' => '127.0.0.1', // 數據庫名 'database' => 'demo', // 數據庫用戶名 'username' => 'root', // 數據庫密碼 'password' => '', // 數據庫連接端口 'hostport' => '', // 數據庫連接參數 'params' => [], // 數據庫編碼默認采用utf8 'charset' => 'utf8', // 數據庫表前綴 'prefix' => 'think_', // 數據庫調試模式 'debug' => true, ];
接下來,我們修改下控制器方法,添加讀取數據的代碼:
<?php namespace app\index\controller; use think\Controller; use think\Db; class Index extends Controller { public function index() { $data = Db::name('data')->find(); $this->assign('result', $data); return $this->fetch(); } }
定義好控制器后,我們修改模板文件,添加數據輸出標簽如下:
<html> <head> <title></title> </head> <body> {$result.id}--{$result.data} </body> </html>
模板標簽的用法和Smarty
類似,就是用于輸出數據的字段,這里就表示輸出think_data
表的id
和data
字段的值。
我們訪問會輸出:
1--thinkphp
文章列表