PHP 5.3新版特性淺析
從php4到php5,從個人框架到開源框架的發展,見證著php從山寨走上正規大軍的發展。php6還在醞釀中,相信php5會作為php6小試牛刀的場地。php5.3是php5的一個里程碑,加入了大量新特性。
我個人總感覺php功能是越來越多了,但是php的語法卻越來越丑陋了,有時加入了新功能,而新功能帶來了問題,為了修復問題,又要加入新的語法來修復,郁悶。估計php用語法修復問題是為了更好的解析。
一、mysql驅動mysqlnd
一直以來,php都是通過mysql客戶端連接mysql,而現在mysql官方已經推出php版的mysql客戶端,而這個mysqlnd有效降低內存的使用以及提高性能。具體可以看:
http://dev.mysql.com/downloads/connector/php-mysqlnd/
http://forge.mysql.com/wiki/PHP_MYSQLND
從圖中可以看出,使用mysqlnd少了從mysql驅動中復制數據到php擴展這一步。mysqlnd使用copy-on-write,也就是寫時復制,讀引用。
mysqlnd已經內置在php5.3的源碼中,編譯的時候使用--with-mysql=mysqlnd、--with-mysqli=mysqlnd 和 --with-pdo-mysql=mysqlnd 安裝mysqlnd驅動。
mysqlnd的優點
編譯php更方便了,不需要libmysql,已經內置在源碼中
- 編譯php更方便了,不需要libmysql,已經內置在源碼中
- 使用php許可,避免版權問題
- 使用php的內存管理,支持php內存限制(memory_limit)
- 所有數據在內存只有一份,之前的libmysql有兩份,參考上圖
- 提供性能統計功能,幫助分析瓶頸
- mysqli支持長連接(persistent connections)
- 性能絕對比libmysql要快
- 在驅動層增加緩存機制
看了這么多特點,有點矛盾,作為數據庫抽象層的PDO能把不同后端的特點發揮出來嗎?如果使用mysql作為數據庫的話mysqli是不是更好的選擇?我總覺得mysqli只是個過度產品,PDO才是未來的。
二、性能提高
- md5()大概提高了10%-15%的性能
- Better stack implementation in the engine,沒明白
- 常量保存在ROM里(Constants moved to read-only memory),這里沒明白意思
- 改進異常處理,操作碼(opcode)更簡潔
- 解決了include(require)_once重復打開的問題,之前once我都是用靜態變量實現的,終于解決這個問題了
- 用gcc4編譯的二進制文件將更小
- 整體性能提高了5%-15%
很多人覺得web的瓶頸在db,所以app應用的性能毫不在乎,我認為主要是因為app擴展比db擴展要容易得多,所以才會產生db瓶頸,但這并不意味著可以不顧慮app的性能,畢竟最終還是要在app里解決各種問題的,作為一名程序員編寫高質量的代碼是最基本的要求。程序的內存使用量少點和執行速度快點,在高并發下是有很效果的,有些時候你改動下實現方法,能提高幾十倍也很正常,當然如果付出要很多收獲很少的時候就不要太執著了,我覺得一定要有編寫高質量代碼的意識。
三、?:操作符
其實就是js里的||,返回的結果不是邏輯類型,而是返回本來變量的值,例如 false ?: 123返回123,而不是true。語法就是有點怪怪! #p#
四、名字空間(namespace)
這是個很好的功能,沒加入之前都是用前綴來解決命名污染的,方法有點山寨,呵呵。
五、延遲靜態綁定(Late Static Binding)
我估計php的靜態是在預編譯時就固定好的,所以在繼承的時候,父類里的self指的是父類,而不是子類。而php5.3加入了新的語法static,可以在運行時候捕捉當前類。
比較典型的例子就是單件模式了:
class ParentClass { |
如果繼承這個父類,那子類的單件必須再重寫覆蓋父類的getInstance。5.3支持用static來延遲綁定,但是很遺憾,即使有static關鍵字卻不能使用new static來實例化,不過有變通的方法
class ParentClass { |
這個新特性當前可能會有問題存在,暫時不建議使用。
六、新的魔法函數__callStatic
其實就是__call的靜態版,調用的靜態方法不存在會調用這個魔法函數,但是低效
七、通過變量調用靜態(Variable Static Calls)
以前可以通過變量調用對象的方法,例如$instance->$method();,而靜態方法不支持,5.3后就支持了可以通過$someClass::$method()調用了,但是低效。
八、日期函數date_create_from_format
把字符串轉換成時間戳,如果使用strtotime的話,日期格式是php解析的,而5.3的date_create_from_format可以設置字符串的日期格式,
$date = strtotime("08-01-07 00:00:00");//php 認為格式 是年-月-日 |
九、匿名函數(Lambda functions)和閉包(closures)
js有個很爽的地方就是支持函數式編程,php很不爽的地方就是函數太過正規了,不過5.3后php更自由了。
定義匿名函數的語法
$lambda = function () { echo "Hello World!\n"; }; |
function replace_spaces ($text) { |
function replace_spaces ($text) { |
產生閉包的語法
function (normal parameters) use ($var1, $var2, &$refvar) {} |
引入了use語法,并且支持引用變量
十、新魔法常量__DIR__
以前只有__FILE__,為了得到當前文件所在的路徑,都是用dirname(__FILE__)來得到的,現在可以用__DIR__代替了
十一、NOWDOC
php定義字符串有一種格式叫定界符.
$foo = << |
這種方式稱為HEREDOC,php會解析里面的變量,而有時候我們不需要解析變量,5.3加入了NOWDOC,其實就是定界符的單引號版
$bar = <<<'TWO' this is $fubar TWO; |
這樣,php只把它當作字符串,變量不會解析
十二、GC
因為php本身工作機制的原因,所以php的GC機制只要高效就夠了,允許少量內存泄漏,畢竟程序執行完畢就會釋放所有申請的內存,根本不會有內存泄漏的問題,但這只是對于短暫運行的程序而言,如果用php編寫持久執行就要考慮內存泄漏問題了。
php的GC機制采用引用計數機制,引用計數是很簡單高效的GC機制,不過缺點也很明顯,不能完全回收所有已無效的變量,例如變量相互引用了,就無法回收了,5.3里加入的GC函數,其實就是起到增強GC機制的作用。
gc_enable(); // 激活GC,增強GC機制,回收循環引用的無效變量 |
【編輯推薦】