在前面的章節中,我們接觸到了很多類似于這樣的方法`類名::方法名()`。比如:我們使用`Db::name()`來獲取某個數據表模型,使用`Resquest::instance()`來獲取請求模型使用了`::get()`來獲取單條數據模型,使用`::select()`來獲取多條數據模型,使用`::destroy`來銷毀數據。
ThinkPHP5大量的使用了這種可以直接使用`::`調用的方法,它們有一個很響亮的名字:靜態方法。靜態方法的引用,大幅提升了程序的運行效率,降低了資源的占用。在實際項目開發中,由于靜態方法的優越性,我們還會大量使用。雖然本教程的前面也簡單的對靜態方法進行過講解,但距離『理解』這個程度還不夠。
爭取通過本章的學習,能夠讓靜態方法在我們心中留下更深的印象。
# 靜態方法
為什么要有靜態方法?
1. 可以降低內存的占用。
2. 提高程序的執行效率。
什么時候用靜態方法?
當這個方法與具體的對象無關時。
* * * * *
##對象、類:
人是一個類,而周潤發就是一個對象。
對象,我們認為是存在于現實社會的。而類呢?是存在于我們大腦中的。我們說自行車、汽車、小貓、電腦、筆記本電腦,這些其實都是描述一類具體事件的一些概念。這些概念存在我們大家的大腦中,我們把這個概念性的東西,就叫做類。
我們說『人』是一個類,是由于它代表的是一類事物。類的特點是,當我們進行交流的時候,我們想到的具體事物可能不是一個。比如,今天的任務是:找一個美女(帥哥)搭訕,那么每個人找的美女(帥哥)都會不一樣。要求大家每人今天摘一片樹葉回來,那么大家摘的樹葉也不會一樣。原因是因為,美女是指的一類人,樹葉,是指的一類事物。美女:我們想像的;樹葉:我們想像的。
我們說女人是一個類,因為女人這個概念存在于我們的大腦中,而孫燕姿、賈玲就是一個個對象。

當然了,我們男孩也是一個類。

我們說王寶強拍的電影是個類,而王寶強拍的『天下無賊』是一個對象;我們說夢云智團隊是一個類,而團隊中的每個成員都是對象;我們說筆記本是個類,而你正在使用的這臺筆記本則是個對象。
總結:
> 類是存在于大腦中的概念,是對具體事物的抽象,并不是實體(實際存在的物體);而對象是一個實體,它具有唯一性,是具體的事物。
* * * * *
##靜態方法
對于每一個河北工業大學的學生來講,不管問我們誰:學校建校有100年了嗎?
答案都是:有。
其實河北工業大學有沒有100年,和問我們誰沒有關系。只要是一個河北工業大的學生,就能準確的回答這個問題。
即:你只要問“河北工業大學的學生”這類人,那么答案可以確定,對于這個方法 ,我們就**可以**聲明為靜態方法。
而對于,”你的生日是哪天“?這些方法,由于不同的河北工業大學的學生回答的答案可能不同,那么就不能聲明為靜態方法。
總結(比較抽象):
> 雖然我們把方法都寫在了一個類中,但是卻有所區別。
> 靜態方法:有類,就可以被調用,與類相關聯。
> 非靜態方法:只有存在對象的時候,這個方法才可以被調用,與對象相關聯。
簡單總結:
> 如果這個方法中沒有用到$this(即沒有使用到這個類中的內部變量),就應該聲明為靜態方法,以提升執行效率。
上面這句話還有另一層含義是:你完全可以不聲明為靜態方法,絕對不會報錯,只是會影響一些執行效率罷了。
### 原來如此
我們重復下上面的問題:
我們把河北工業大學的學生,定義為一類人,這類人,我們起名叫Hebuter,它們的共同屬性除了是人,還是大學生,還是一所大學的學生。
比如我現在有一個問題:河北工業大學,建校有100年了嗎?
我們想:這個問題凡是這個學校的學生,就會知道正確的答案。
我還有一個問題:你的身份證號是多少?
我們想,每個學生的答案都是唯一的,是有區別的。
那么,針對上面兩個問題。在程序中,我們可以這樣寫:
> 我們將測試代碼寫到```public```文件夾下的```test.php```中。
~~~
public function test()
{
$Hebuter = new Hebuter;
$xiaohong = $Hebuter::get('xiaohong'); // 小紅
$xiaoming = $Hebuter::get('xiaoming'); // 小明
// 小紅與小明回答學校是否建校100年,答案一致
var_dump($xiaohong->isSchoolMoreThan100());
var_dump($xiaoming->isSchoolMoreThan100());
// 小紅和小明回答自己的身份證號碼,答案不一致
var_dump($xiaohong->whatIsYouId());
var_dump($xiaoming->whatIsYouId());
}
~~~
我們將一些和具體的對象無關、而與具體的類有關的方法,往往定義為靜態方法。
比如是否建校100年,只要是Hebuter給出的答案就是一致的。
在調用靜態方法時,由于并不需要確定是哪個對象,所以可以不必實例化。
而與具體的對象相關,比如這里問你的身份證是多少,那么就不能定義成靜態方法。
所以上述代碼可以修改為:
~~~
public function test()
{
// 只要是我們學校的學生,回答學校是否建校100年,答案都是一個。
var_dump(Hebuter::isSchoolMoreThan100());
$Hebuter = new Hebuter;
$xiaohong = $Hebuter::get('xiaohong'); // 小紅
$xiaoming = $Hebuter::get('xiaoming'); // 小明
// 小紅和小明回答自己的身份證號碼,答案不一致
var_dump($xiaohong->whatIsYouId());
var_dump($xiaoming->whatIsYouId());
}
~~~
以后我們還會接觸越來越多的靜態方法,用的多了,自然就理解了,在這里,有個概念就可以了。
完整代碼如下:
~~~
<?php
class Test
{
public function test()
{
// 只要是我們學校的學生,回答學校是否建校100年,答案都是一個。
var_dump(Hebuter::isSchoolMoreThan100());
$Hebuter = new Hebuter;
$xiaohong = $Hebuter::get('xiaohong'); // 小紅
$xiaoming = $Hebuter::get('xiaoming'); // 小明
// 小紅和小明回答自己的身份證號碼,答案不一致。
var_dump($xiaohong->whatIsYouId());
var_dump($xiaoming->whatIsYouId());
}
}
class Hebuter
{
private $name; // 姓名
// 設置姓名
public function setName($name)
{
$this->name = $name;
}
// 學校是否有百年歷史
static public function isSchoolMoreThan100()
{
return true;
}
// 獲取ID信息
public function whatIsYouId()
{
if ($this->name === 'xiaohong')
{
return '1234567';
}
if ($this->name === 'xiaoming')
{
return '7654321';
}
return '88888888';
}
// 根據名字獲取Hebuter對象
static public function get($name)
{
$Hebuter = new Hebuter;
$Hebuter->setName($name);
return $Hebuter;
}
}
// 以下是測試代碼
$Test = new Test; // 實例化
$Test->test(); // 調用對象中的方法
~~~
訪問如下地址進行測試:

好像還有一點點亂對吧,沒關系,如果還亂,多找一些關于類與對象的學習資料再看看吧,這個的確是個長久的學習過程。
- 序言
- 第一章 準備知識
- 第一節:XAMPP
- 第二節:NAVICAT
- 第三節:GIT
- 第二章 HelloWorld
- 第一節:下載THINPHP5.0
- 第二節:啟動xampp
- 第三節:hello thinkphp
- 第四節:Hello world
- 第五節:MCA
- 第六節:單引號與雙引號
- 第三章 教師管理
- 第一節:新建數據庫
- 第二節:CURD之R 讀數據
- 3.2.1 時序圖
- 3.2.2 連接數據庫
- 3.2.3 直接讀取數據
- 3.2.4 間接讀取數據
- 3.2.5 使用V層顯示數據
- 3.2.6 引入bootstrap
- 3.2.7 加入bootstrap樣式
- 第三節:CURD之 C 增加數據
- 3.3.1 插入數據
- 3.3.2 表單傳值
- 3.3.3 存儲表單數據
- 3.3.4 自動時間戳
- 3.3.5 增加驗證
- 第四節:CURD之 D 刪除數據
- 3.4.1 什么是關鍵字
- 3.4.2 刪除數據
- 3.4.3 定制刪除鏈接
- 3.4.4 完善刪除
- 第五節:CURD之 U 更新數據
- 3.5.1 讀取數據
- 3.5.2 展示數據
- 3.5.3 修改數據
- 3.5.4 傳遞數據
- 3.5.5 接收數據
- 3.5.6 更新數據 方法一
- 3.5.7 更新數據 方法二
- 第六節:銜接各個action & 重構代碼
- 3.6.1 index action
- 3.6.2 add action
- 3.6.3 insert action
- 3.6.4 delete action
- 3.6.5 edit action
- 3.6.6 update action
- 第七節:分頁
- 3.7.1 調用內置分頁
- 3.7.2 select與paginate(選學)
- 3.7.3 分頁原理(選學)
- 3.7.4 調用page(選學)
- 第八節:模糊查詢
- 3.8.1 增加查詢
- 3.8.2 完善查詢
- 第四章 登錄與注銷
- 第一節:cookie 與 session
- 第二節:靜態方法
- 第三節:規劃URL跳轉
- 第四節:登錄
- 4.4.1 登錄流程
- 4.4.2 index action
- 4.4.3 login action
- 4.4.4 引入M層
- 4.4.5 異常Exception
- 第五節:注銷
- 第六節:驗證
- 4.6.1 action增加驗證
- 4.6.2 使用構造函數驗證
- 4.6.3 使用繼承驗證
- 第五章 E-R圖與數據字典
- 第一節:第一張E-R圖
- 第二節:實體間的關系
- 第三節:開發規范
- 第六章 班級管理
- 第一節:建立數據表
- 第二節:數據列表index
- 第三節:增加數據add
- 第四節:編輯數據edit
- 第五節:刪除數據delete
- 第七章 學生管理
- 第一節:建立數據表
- 第二節:數據列表
- 7.2.1 顯示性別
- 7.2.2 顯示創建時間
- 7.2.3 顯示班級名稱
- 7.2.4 顯示輔導員姓名
- 第三節:編輯數據
- 第四節:魔法函數
- 第五節:源碼分析
- 第八章 課程管理
- 第一節:建立數據表
- 第二節:新增課程
- 第三節:編輯課程
- 8.3.1 edit
- 8.3.2 update
- 第九章 代碼重構
- 第一節:add 與 edit
- 第二節:insert 與 update
- 第三節:模板繼承
- 9.3.1 index.html
- 9.3.2 edit.html
- 9.3.3 小結
- 第十章 UML圖
- 第一節:E-R圖回顧
- 第二節:UML圖
- 第十一章 菜單與路由
- 第一節:添加菜單
- 第二節:虛擬主機
- 第三節:定制路由
- 第十二章 開發調試
- 第一節:開啟trace
- 第二節:查看日志
- 第十三章:總結