PHP進階知識總結

範長法@三月軟體發表於2015-03-10

週末梳理了下這段時間看書的一些知識點,進步的過程不僅要實踐,還要安排多看書、思考、總結。

只針對知識點進行了羅列和簡單說明,很多細節還未整理好,待後面再專門詳細寫。

 

基礎易忽略概念


 

PHP是一個支援物件導向開發的語言,而不是一個純物件導向的語言
PHP5中保留了對var的支援,但會將var自動轉換為public
型別檢查函式:
is_bool()
is_integer()
is_double()
is_string()
is_object()
is_array()
is_resource()
is_null()
 
PHP魔術方法:
__call()
__callStatic()     (必須是static屬性)
__set()
__get()
__isset()
__clone()
__toString()
字串"false"在比較操作時會解析為true,因為PHP在測試變數時會轉換一個非空字串值為bool值true
 
靜態方法是以類作用域的函式。靜態方法不能訪問這個類中的普通屬性,因為那些屬性屬於一個物件,但可以訪問靜態屬性(不能在靜態方法中使用偽變數$this)
 
常量屬性只包含基本資料型別的值,不能將一個物件指派給常量
抽象類(abstract class)不能被直接例項化,只定義(或部分實現)子類需要的方法
抽象類至少包含一個抽象方法
static類似於self,但它指的是被呼叫的類而不是包含類
return new static()
 
複製物件(設計模式中的原型模式):
$first = new ClassName();
$second = $first;
//在php5以後的版本中,$second 和 $fitst指向同一個物件
 
$third = clone $first;          //使用clone進行"值複製"
//在php5以後的版本中,$third和$first是兩個不同的物件
/*控制複製什麼:
          可以實現一個__clone()方法
          比如待複製的物件中有個$id=1,可我們希望此id唯一,不希望clone此id,可以在類中自己實現clone方法*/

 

回撥、匿名函式:
is_callable();
call_user_func($funcName,$param);     //單個引數
call_user_func_array($funcName,$arrParam);     //引數是陣列的形式 
 
名稱空間Namespace:
名稱空間是一個容器,在名稱空間之外,必須匯入或引用名稱空間才能訪問它所包含的項。
namespace com\name\test1;
class Debug{
    static function test();
}
namespace test2;
//呼叫test1名稱空間中的test方法
\com\name\test1\Debug::test();     //最前面必須加上 / 否則會在test2下尋找此名稱空間
 
use com\name\test1;
test1\Debug::test();   
 
解決類命名衝突:
use com\name\test1\Debug as uDebug;
class Debug{...}
uDebug::test();
 
__NAMESPACE__     //輸出當前的名稱空間

名稱空間加大括號形式:

namespace com\name\test1{
    class Debug1{...}
    class Debug2{...}
}

 

require()呼叫檔案發生錯誤時,將會停止整個程式,

呼叫include()時遇到相同的錯誤,會生成警告並停止執行包含檔案,跳出呼叫程式碼然後繼續執行。
 
require()和require_once()用於包含庫檔案時更加安全,include()和include_once()適用於載入模板等操作
相對require()函式,require_once()需要額外的開銷
 
自動載入autoload:
當PHP引擎遇到試圖例項化未知類的操作時,會呼叫__autoload()方法(需提前定義),並將類名當作字串引數傳遞
例如:
function __autoload($className){
    //將$className中的下劃線轉換為目錄分割
    $path = str_replace('_',DIRECTORY_SEPARATOR,$className);
    require_once("$path.php");
}

__autoload方法是一種根據類和檔案的結構,管理類庫檔案包含的有效方法。

 
類函式:
class_exists();
get_declared_classes();     //獲得指令碼程式中定義的所有類的陣列
get_class($obj);     //檢查物件的類,檢查物件所屬的類
$obj instalceof className;     //檢查物件
 
get_class_methods();     //獲取一個類中所有的方法列表
 
is_callable()、method_exists()     //檢查類方法是否存在且可被呼叫
#一個方法存在並不以為著可呼叫,對private、protected、public方法,method_exists()都返回true
 
get_class_vars($className);     //獲取類中定義的屬性
get_parent_class($classNa,e);     //獲取一個類的父類
is_subclass_of($className , 'classStrName');     //檢查類是否是另一個類的派生類
class_implements($className);      //返回一個由介面名組成的陣列 
 
反射API
根據到達地找到出發地和來源,反射指在PHP執行狀態中擴充套件分析PHP程式,匯出或提取出關於類、方法、屬性、引數等的詳細資訊,包括註釋。這種動態獲取資訊以及動態呼叫物件方法的功能稱為反射API
使用反射API可以對檔案裡的類進行掃描,逐個生成描述檔案
 
物件導向設計的五大原則:
  1. 單一職責原則
  2. 介面隔離原則
  3. 開放-封閉原則
  4. 替換原則
  5. 依賴-倒置原則
 
sql優化的10個原則:
  1. 不要在列上進行函式運算,導致索引失敗
  2. 使用JOIN時,應用小結果集驅動大結果集。把複雜的JOIN查詢拆分為多條sql
  3. 使用like模糊查詢時,避免%%,可替換為<= 、 >=
  4. select後僅列出需要的欄位,對速度不會有明顯影響,主要考慮節省記憶體
  5. 使用批量插入語句,比依次執行單個插入節省互動
  6. limit的技術比較大時考慮使用between
  7. 不要使用rand函式獲取多條隨機記錄
  8. 避免使用NULL
  9. 不要使用count(id),而是count(*)
  10. 儘可能在索引中完成排序
快取的三個要素:
  1. 命中率
  2. 快取更新策略
  3. 快取最大資料量
通常快取更新策略有:
  1. FIFO(先進先出)
  2. LRU(最近最少淘汰策略)
  3. LFU(最少使用淘汰策略)
MySQL 的 Query Cache使用的是FIFO策略
快取的最大資料量是在快取中能夠處理元素的最大數或所能使用的最大儲存空間
 
超過快取機制允許的最大資料量系統會進行相應的處理,一般處理方式有:
  1. 停止快取伺服器,清空所有快取資料
  2. 拒絕寫入,不再對快取資料進行更新
  3. 根據快取更新策略清除舊資料
  4. 基於3的方式,對淘汰的資料進行備份
Opcode快取:
    虛擬機器把PHP程式碼編譯成一種中間碼的結果快取起來,下次PHP執行此頁面時,只要直接解釋這些程式碼就行了。
eAccelerator工具能起到常駐記憶體的作用
 
客戶端快取、http快取(待記錄)
H5中的Application Cache:
用來處理離線應用中的問題,使用者不能聯網時依然能瀏覽整個站點
需要在html中指定頁面是否需要此快取:
<html manifest="cacheName.mf">
 
Memcached

使用Memcached:
  1. 對資料庫的高併發讀寫
  2. 對海量資料處理
Memcached是高效能的分散式記憶體快取伺服器,通過快取資料庫查詢結果,減少資料庫訪問次數。
Memcached特點:
  1. 協議簡單
  2. 基於libevent的事件處理
  3. 內建記憶體儲存方式
  4. 採用不互相通訊的分散式
  5. 守護程式方式執行與一個或多個伺服器中
  6. Memcached使用LRU演算法淘汰資料快取
  7. 不支援資料持久化
Memcached把資料儲存在記憶體中,所以重啟Memcached或者作業系統會導致資料全部消失
 
安裝memcached:
apt-get install memcached
啟動memcached:
memcached -d -m 128 -u root -p 11211
-d:守護程式方式執行
-m:設定Memcached可使用的記憶體大小,單位是MB
-l:設定監聽的IP地址,本機可預設不設定
-u:指定使用者
-p:設定監聽的埠,預設為11211
 
安裝PHP的memcached擴充套件:
 sudo apt-get install php5-memcache
 
memcached擴充套件的一些方法:
  • Memcache::connect(string $host [, int $port [ , int $timeout]]);     //連線mem伺服器
    $timeout為連線持續時間,預設為1秒。過長的時間會倒置失去所有快取的優勢
  • Memcache::addServer(string $host [ , $port [ , $bool $persistent [ , $weight [, int $timeout [, int $retry_interval [ , bool $status [ , callback $failure_callback]]]]]]]);     //向物件新增一個伺服器
  • Memcache::add(string $key,$mixed $var [, int $flag[ , int $expire]]);    //新增快取資料
    • key長度不能超過250位元組,
    • var 值最大為1MB
    • $flag 是否使用ZLib壓縮,設定為MEMACHE_COMPRESSED使用壓縮
    • $expire快取過期時間,0表示不過期。設定不能大於2592000(30天)
  • Memcache::replace(string $key, mixed $var [ , int $flag [, int $expire]]);    //替換一個已存在的key
  • Memcache::set(string $key ,mixed $vsar [ , $flag [ , $expire]])    //add和replace的集合體
  • Memcache::get(string $key [ , int &flags]);    //獲取key的快取內容
    • $flags 如果給定此引數(引用方式傳遞),該引數會被寫入一些與key對應的資訊
  • Memcache::delete(string $key [ , $timeout]);    //刪除key的快取
  • Memcache::flush(void);    //立即使所有已經存在的快取失效
    • 不真正釋放任何資源,僅標記為失效
  • Memcache::getServerStatus(string $host [ , $port]);    //獲取一個伺服器的線上/離線狀態
  • Memcache::getStats([ string $type [ , $slabid [ , int $limit = 100]]]);    //獲取伺服器的統計資訊
  • Memcache::close(void);    //關閉與Memcache伺服器的連線
Memcached使用多路複用I/O模型(如epoll、select),傳統阻塞IO中 系統可能會因為某個使用者連線還沒做好IO準備而一直等待,直到這個連線做好準備,如果此時遊其他使用者連線到伺服器,可能會因為系統阻塞而得不到相應。
多路複用I/O是一種訊息通知模式,使用者連線做好IO準備後,系統會通知這個連線可進行IO操作,這樣就不會阻塞在某個使用者連線。
Memcached使用Slab分配演算法儲存資料
Slab分配演算法的原理是,把固定大小(mem預設為1M)的記憶體劃分為n塊,每1M大小的記憶體塊稱為一個slab頁,每次向系統申請一個slab頁,然後通過分割演算法把這個slab頁分成若個小塊的chunk,然後把這些chunk分配給使用者使用。
Memcached多執行緒模型:
  • 主執行緒:接受客戶端連線,並把連線分配給工作執行緒處理
  • 工作執行緒:處理客戶端連線的請求
Memcached分散式佈置方案:
  • 普通Hash分佈
  • 一致性Hash分佈
Redis
Redis把整個資料庫全載入到記憶體中進行操作,通過非同步操作定期把資料庫資料flush到硬碟儲存
Reids特點:
  1. 支援豐富的資料型別:String、List、Sort、Sorted Set、Hash
  2. 支援資料持久化方式:記憶體快照、日誌追加
  3. 支援主從複製
安裝Redis:
安裝php擴充套件redis:
sudo apt-get install php5-redis
redis預設埠為:6379
 
redis配置檔案(待整理)
 
redis key相關命令:
exits key     //key是否存在,返回0/1
del key1 key2..     //刪除指定key,返回刪除key的數目,0表示key都不存在
type key     //返回給定key的value型別,none表示不存在key
types pattern     //返回匹配指定模式的所有key
expire key seconds     //設定指定key的過期時間
randomkey     //返回當前資料庫中隨機的一個key,如果資料庫為空,返回空字串
rename oldkey newkey     //重新命名key
renamenx oldkey newkey     //重新命名key,如果newkey存在返回失敗
ttl key     //返回設定過期時間key的剩餘秒數,-1表示key不存在或沒有設定過期時間
move key db-index     //將key從當前資料庫移動到指定的資料庫,返回1成功,0表示不存在或已在指定資料庫
 
未完待續……

相關文章