PHP7要發佈了,你連5.X的特性都還不知道麼?今天我們就整理了一些屬於5.3之後版本PHP的特性。由於PHP版本依舊在不斷的更新中,其中不乏一些實用的新特性可以大大簡化編程中遇到的問題,這裏介紹一些實用的特性
PHP 5.3中的新特性
1. 支持命名空間 (Namespace)
衆測的模塊日益複雜,在各個模塊中容易出現類名或變量名的衝突。因而,命名空間可能是PHP5.3所帶來的重要的特性。、
在PHP5.3之前,慣例的劃分Package的辦法是通過目錄名來分隔代碼文件,代碼中的類名則用下劃線_來表示目錄。例如主站的模塊就可以命名爲crowdtest_models_user
這樣的命名方式常見於Zend Framework和各種PHP項目。雖然該方法有效避免了類名的衝突,但在編碼過程中顯得十分笨拙和麻煩。
在PHP5.3中,則只需要指定不同的命名空間即可,命名空間的分隔符爲反斜杆\。
<?php
namespace crowdtest\models;
class User {}
這樣即使其它命名空間下存在名爲User的類,程序在調用時也不會產生衝突。代碼的可讀性也有所增加。
調用方法:
$user = new crowdtest\models\User();
2. 支持goto語句
很多語言中都支持無條件轉向語句goto,儘管goto語句降低了代碼可讀性,使理解代碼變得困難,然而在某些情況下具有其獨特的方便之處,例如中斷深度嵌套的循環和 if 語句。
goto a;
echo'CROWDTEST';
a:
echo'zhongce';
3. 支持閉包、Lambda/Anonymous函數
閉包(Closure)函數和Lambda函數的概念來自於函數編程領域。比如JavaScript的一大特點就是支持閉包和 lambda 函數。
在PHP5.3中,我們同樣可以使用Lambda匿名函數來定義一些臨時使用(即用即棄型)的函數,以作爲array_map()/array_walk()等函數的回調函數。
echo preg_replace_callback('~-([a-z])~', function ($match) {
return strtoupper($match[1]);
},'hello-zhongce);
//輸出 helloZhongce
$test = function($name)
{
echo$name;
};
$test('zhongce');
4. 新增Nowdoc語法
用法近似於Heredoc,但使用單引號,而Heredoc則需要通過使用雙引號來聲明。
Nowdoc中類似於單引號處理字符串,不會做任何變量解析,非常適合於傳遞一段PHP代碼。
//Nowdoc 單引號 PHP 5.3之後支持
$name= 'crowdtest';
echo<<<'EOT'
Here is "$name".
EOT;
//上面代碼輸出 Here is "$name". ((其中變量不被解析)
//Heredoc不加引號
echo<<<FOOBAR
Hello crowdtest!
FOOBAR;
//或者 雙引號 PHP 5.3之後支持
echo<<<"FOOBAR"
Hellocrowdtest!
FOOBAR;
5. 在類外也可使用const來定義常量
並且新增了一種常量定義方式:
<?php
const CONSTANT = ' Hello crowdtest ';
6. 三元運算符增加了一個快捷書寫方式
原本格式爲是(expr1) ? (expr2) : (expr3),此時如果expr1結果爲True,則返回expr2的結果。
PHP5.3中增加了一種書寫方式,可以省略中間部分,寫成這種 expr1 ?: expr3。此時如果expr1結果爲True,則返回expr1的結果。不過此方法感覺並不直觀,使用起來對不熟悉語法的小夥伴是不小的挑戰
7. 支持動態調用靜態方法
class user{
public static function login()
{
echo"login!";
}
}
$class = 'user';
$action = 'login ';
$class::$action(); //輸出 " login!"
PHP 5.4中的新特性
1. 內置了一個簡單的Web服務器
把當前目錄作爲Root Document,只需要這條命令即可:
# php -S localhost:8888
也可以指定其它路徑:
# php -S localhost:8888 -t /home/work
還可以指定路由:
# php -S localhost:8888 router.php
2. Traits
Traits提供了一種靈活的代碼重用機制,其實際的目的,是爲了有的場合想用多繼承,但PHP又沒多繼承,於是就發明了這樣的一個東西。
假如我們有個類爲client,有一個變量爲address,在兌換禮品的業務中存在order類的,需要訪問同樣的地址屬性,那怎麼辦呢?order類是沒辦法繼承client類的,因爲這個不符合OOP的原則。
trait Address{
private $address;
public getAddress() {
return $this->address;
}
public setAddress($address) {
$this->address = $address;
}
}
class Order{
use Address;
//這裏可以使用address屬性
}
3. 數組簡短語法
$arr = [1,'crowdtest', 'test.baidu.com'];
$array = [
"test"=> "bar",
"crowd"=> "foo"
];
4. Array dereferencing 數組值
function myArray() {
return [1,'crowdtest', 'test.baidu.com'];
}
在PHP5.4中這樣就行了:
echo myArray()[1];
5. Upload progress上傳進度支持
如果用戶需要上傳一個大文件,和可能需要一個進度條來告知其狀態,5.4版本的Session提供了上傳進度支持,通過$_SESSION["upload_progress_name"]就可以獲得當前文件上傳的進度信息,結合Ajax就能很容易實現上傳進度條了。
6. 函數類型提示的增強
由於php是弱類型的語言,所以在php 5.0後,引入了函數類型提示的功能,其含義爲對於傳入函數中的參數都進行類型檢查,舉個例子,有如下的類:
class user {
function login(user $user) {
}
其中函數login中的參數規定了傳入的參數必須爲user類的實例,否則系統會判斷出錯。同樣對於數組來說,也可以進行判斷,比如:
function user (array $ user) {}
user(array(1, 2, 3)); // 正確,因爲傳入的是數組
user(123); // 不正確,傳入的不是數組
7. 二進制直接量
$val= 0b1101;
echo $val;//13
另外值得一提的是多字節支持已經默認啓用了,
default_charset從ISO-8859-1已經變爲UTF-8.
默認發送“Content-Type: text/html; charset=utf-8”,
你再也不需要在HTML裏寫meta tag,也無需爲UTF-8兼容而傳送額外的header了。
PHP5.5中的新特性
1. 新增函數和類
boolval()
由於PHP已經出現了strval、intval和floatval這些類型檢查的函數。爲了滿足強迫症添加了boolval函數。它完全可以作爲一個布爾值計算,也可以作爲一個回調函數。
hash_pbkdf2()
PBKDF2是“Password-Based Key Derivation Function 2”的簡寫,正如它的名字一樣,是一種從密碼派生出加密密鑰的算法。
2. 一個簡單的密碼散列API
$password = "crowdtest";
//生成hash
$hash= password_hash($password, PASSWORD_BCRYPT);
//驗證hash
if(password_verify($password, $hash)) {}
3. 調用empty()函數(和其他表達式)一起工作
目前,empty()語言構造只能用在變量,而不能在其他表達式。
在特定的代碼像empty($this->getFriends())將會拋出一個錯誤。作爲PHP5.5這將成爲有效的代碼
4. 參數跳躍
如果你有一個函數接受多個可選的參數,目前沒有辦法只改變最後一個參數,而讓其他所有參數爲默認值。
RFC上的例子,如果你有一個函數如下:
function create_query($where, $order_by, $join_type='',
$execut e= false, $report_errors = true) { ... }
那麼有沒有辦法設置$report_errors=false,而其他兩個爲默認值。爲了解決這個跳躍參數的問題而提出:
create_query("deleted=0","name", default, default, false);
5. Getter 和 Setter
如果你非常討厭寫getXYZ()和setXYZ($value)方法,那麼這一特性應該會幫助到你。5.5版本添加一個新的語法來定義一個屬性的設置/讀取:
class Time {
public $seconds;
public $hours {
get { return $this->seconds / 3600;}
set { $this->seconds = $value *3600; }
}
}
6. 生成器
目前,很少使用自定義迭代器,因爲它們的實現需要相當多的樣板代碼。生成器解決這個問題,並提供了一種簡單的樣板代碼來創建迭代器。
例如,你可以定義一個範圍函數作爲迭代器:
function *range($start, $end) {
for ($i = $start; $i < $end; $i ++) {
yield $i;
}
}
foreach(range (10, 20) as $i) {
// ...
}
上述range函數具有與內建函數相同的行爲,但有一點區別:不是返回一個數組的所有值,而是返回一個迭代器動態生成的值。
7. finally關鍵字
使用類似於java中的finally,經典的try... catch ... finally 三段式異常處理。
PHP 5.6中的新特性
1. 改進可變參數函數的語法
可變參數函數允許傳入任意數量的參數。當你提供給他一些參數,你通常不得不調用 func_get_args 來進行後續操作,這有點不切實際。在這裏有這樣的例子,在5.5中語法是這樣的:
class MySQL implements DB {
protected $pdo;
public function query($query) {
$stmt = $this->pdo->prepare($query);
$stmt->execute(array_slice(func_get_args(),1));
return $stmt;
}<em>
}
$userData= $db->query('SELECT * FROM users WHERE id = ?', $userID)->fetch();</em>
現在語法將變成這樣:
class MySQL implements DB {
public function query($query, ... $params){
$stmt = $this->pdo->prepare($query);
$stmt->execute($params);
return $stmt;
}
}
使用... $params 語法將會使函數接受第一個參數,將其他的全都放到$params數組當中。同時這個新的語法還允許對額外的參數使用引用傳遞。給...$params 加一個&符前綴,就像這樣&...$params,這是 func_get_args難以企及的。
2. 參數解包
在改善可變參數函數之後,參數解包也得到了支持。
到目前爲止,通過參數的方式,調用一個方法的時候傳入任意多個數量的參數的爲止方式是使用 call_user_func_array 。字面意思就是“調用一個用戶函數並使用一個array作爲參數”。這很笨拙和不方便,而且不支持構造函數,速度慢,需要一個字符串形式的回調函數,這意味着大多數的IDE都不能跟蹤和支持這個函數。
解包功能將消除上面的所有的缺點,而且自然的補充了上面看到的任意數量參數的支持。解包看起來像這樣:
$args = [1, 3, 5, 7, 9];
MyClass::someMethod(...$args);
這樣的方式就像是這樣:
MyClass::someMethod(1,3, 5, 7, 9);
通過這一個又一個的參數,使他可以工作在任何的場景下,從類的初始化到各種回調。
PHP7已經公佈,在未來我們還將看到更多實用的特性出現在我們面前