Namespaces
php 5.3最大的改動,毫無疑問就是Namespaces(先前有一篇相關的PHP Namespaces FAQ)。這給php開發人員帶來的好處不少,廣為人們所詬病的函數命名問題也得到了解決。
程式碼更清晰
5.3之前常見的程式碼,需要自訂前綴區分函數和類別名稱
PLAIN TEXT
CODE:
function MY_wrapper() {}
class MY_DB { }
define('MY_CONN_STR', '');
MY_wrapper();
new MY_DB();
MY_CONN_STR;
使用名稱空間之後,程式碼看起來更加clean。
PLAIN TEXT
CODE:
namespace MY;
function wrapper() {}
class DB { }
const CONN_STR = '';
use MY AS MY;
wrapper();
new DB();
CONN_STR;
在一個檔案中定義了多個namespace
如果在一個檔案中定義了多個namespace,應該怎麼處理?
PLAIN TEXT
CODE:
namespace LIB;
class MySQL {}
class SQLite {}
$b = new SQLite();
namespace LIB_EXTRA;
class MScrypt {}
$a = new MScrypt();
var_dump(
get_class($a),
get_class($b)
);
以上程式碼輸出為:
PLAIN TEXT
CODE:
string(18)"LIB_EXTRA::MScrypt"
string(11)"LIB::SQLite"
php是解釋執行的語言,以上結果合理。
namespace的優先權
namespace中定義的函數,類別和常數優先,其次才是全域的。
PLAIN TEXT
CODE:
namespace foo;
function strlen($foo) { return htmlentities($foo); }
echo strlen("test"); // test
echo ::strlen("test"); // 4
echo namespace::strlen("test"); // test
namespace和autoload的友誼
autoload會根據namespace名稱以及class名稱來解析類別檔案位置僅當namespace和全域範圍都沒找到class定義的情況下,autoload才會被觸發在namespace中定義的__autoload不會被自動調用
PLAIN TEXT
CODE:
function __autoload($var) { var_dump($var); } // LIB::foo
require "./ns.php"; /*
<?php
namespace LIB;
new foo();
*/
namespace一些輔料
PLAIN TEXT
CODE:
namespace really::long::pointlessly::verbose::ns;
__NAMESPACE__; // 新增的魔法常數,表示目前namespace名稱
class a{}
get_class(new a()); // really::long::pointlessly::verbose::ns::a
use really::long::pointlessly::verbose::ns::a AS b;// 從名稱空間引用一個類別註:這裡的內容節選自pdfIntroduction to PHP 5.3 Slides,後文不再複述。
性能提升
php 5.3的整體效能提升了5 - 15%
md5()快了10-15%
Better stack implementation in the engine
Constants移到read-only內存裡
exception處理過程改進(簡化,opcodes更少)
(require/include)_once改進,去掉重複open
Smaller binary size & startup size with gcc4
新語言特性__DIR__
在5.3以前,為了取得目前腳本的目錄,需要一次函數呼叫
PLAIN TEXT
CODE:
echo dirname(__FILE__); // < PHP 5.3
在5.3,只需要一個魔術常數__DIR__就解決了。
PLAIN TEXT
CODE:
echo __DIR__; // >= PHP 5.3
?:運算符便捷的?:運算符,可以從兩個值/表達式中快速取得非空值。
PLAIN TEXT
CODE:
$a = true ?: false; // true
$a = false ?: true; // true
$a = "" ?: 1; // 1
$a = 0 ?: 2; // 2
$a = array() ?: array(1); // array(1);
$a = strlen("") ?: strlen("a"); // 1
__callStatic()
新增了魔術方法__callStatic,功能和__call類似,但僅對static方法有效。
PLAIN TEXT
CODE:
class helper {
static function __callStatic($name, $args) {
echo $name.'('.implode(',', $args).')';
}
}
helper::test("foo","bar"); // test(foo,bar)
動態呼叫static方法動態的呼叫靜態方法?動靜結合。
PLAIN TEXT
CODE:
class helper {
static function foo() { echo __METHOD__; }
}
$a = "helper";
$b = "foo";
$a::$b(); // helper::foo
Late Static Binding
不知道怎麼譯,可能留個原文比較容易理解。靜態方法的事件處理時機有變化,以前是在編譯期處理,現在是執行期間處理。
在php 5.3之前,下面的程式碼會輸出一個A,但這不是咱們想要的,whoami方法已經在class B中重新定義,它本該輸出B才符合咱們想當然的思維。
PLAIN TEXT
CODE:
class A {
public static function whoami() {
echo __CLASS__;
}
public static function identity() {
self::whoami();
}
}
class B extends A {
public static function whoami() {
echo __CLASS__;
}
}
B::identity(); // A <-- PHP <5.3
在下面程式碼中使用了static::whoami()來呼叫靜態方法。 php 5.3之後,由於__CLASS__是在執行期間被處理,那麼這個例子中能順利抓到class B。
PLAIN TEXT
CODE:
class A {
public static function whoami() {
echo __CLASS__;
}
public static function identity() {
static::whoami();
}
}
class B extends A {
public static function whoami() {
echo __CLASS__;
}
}
B::identity(); // B <-->= PHP 5.3
mysqlnd
見mysqlnd成為php 5.3中的預設mysql驅動
但是PDO_MySQL暫時還不支援mysqlnd,目前只有mysql(i)擴充可以用到
之前介紹的php 5.3的新特性,都是方便開發人員的東東。下面介紹個很討虛擬主機提供者喜歡的功能。
增強的ini檔案支持
CGI/ FastCGI支援類似.htaccess的INI配置每個目錄下都可以有INI設置,ini的檔名取決於php.ini的配置,但是[PATH=/var/www/domain.com], [HOST=www .domain.com]段落的設定使用者不能修改。
增強的error handling
允許在ini檔案中定義變數和常數,可以在程式中直接呼叫。
附上一段ini檔案的範例
PLAIN TEXT
CODE:
#使用者自訂的php.ini檔案名稱(.htaccess). 預設是".user.ini"
user_ini.filename=".user.ini"
#如果要停用這個特性,設定為空值即可
user_ini.filename=
#使用者自訂的php.ini檔案TTL時長(time-to-live),單位為秒,我理解為快取過期時間。預設為300秒
user_ini.cache_ttl=300
[PATH=/var/www/domain.com]
variables_order = GPC
safe_mode =1
[my variables]
somevar = “1234”
anothervar = ${somevar}; anothervar == somevar
[ini arrays]
foo[bar]=1
foo[123]=2
foo[]=3