前言
相信有一定開發經驗的PHP程式設計師都有快取的使用經驗,包括但不限於redis快取,模板快取,路由快取,配置快取,資料庫快取,還有opcache(真的很有用),但是今天我不準備炒冷飯了,我要講點你不知道的快取。
文件連結
- php原始碼
- php擴充套件電子書
-
分析
首先為了說明問題,我貼出公司的一段程式碼,我相信你肯定寫過,非常簡單,就像下面這樣。
$year = date('Y', time()); $month = date('m', time());
初看起來,好像沒有什麼問題,對頭,你說的沒錯,程式碼是沒有問題的,那麼問題出在哪裡呢?要解釋這個問題,我要先給大家講解下有關知識點,聽好咯。
PHP函式
php自帶的函式,是怎麼執行的呢?很簡單,php自帶的函式都對應底層的一個C語言函式(關於PHP擴充套件以後會講到),就以當前的time函式為例。
所有的PHP對應的底層函式,都是這麼定義的,PHP_FUNCTION是C語言的一個巨集定義,我們看看這個函式,它呼叫了函式php_time,那麼php_time又是啥呢?
這裡它呼叫了系統呼叫time,什麼是系統呼叫?簡單來說,系統呼叫就是作業系統提供給使用者程式訪問計算機資源的介面,更要命的是,系統呼叫極其耗時,說到這裡你應該明白了,當你在php指令碼里面每一次呼叫time(),php程式就會系統呼叫一次。
優化
剛才以time()函式作為例子分析了弊端,那麼我們怎麼來優化呢?其實很簡單,對於時間要求不是那麼嚴格的情況下,我們可以把時間快取起來,就像下面這樣。
class TimeWrapper
{
private static $now_time = 0;
/**
* @param bool $force_refresh 是否強制重新整理
* @return int
*/
public static function getTime($force_refresh = false)
{
if ($force_refresh) {
self::$now_time = time();
} else {
if (!self::$now_time) {
self::$now_time = time();
}
}
return self::$now_time;
}
}
定義一個類,然後定義一個靜態欄位,就完事兒了。
疑惑
你可能會說,我的程式不在乎這麼點兒時間。但是php自帶的很多函式都會呼叫系統呼叫,結果不用我說,你應該也明白了。