最近更新: 2012-03-02

PHP 5.4 新功能

Traits

多年前,我在《PHP 實踐 mix-in 概念之可行性》中嘗試著用 PHP 實現「Mix-in (混成)」能力。現在,PHP 5.4 終於提供了這個功能,它稱為「Traits」。

PHP Traits 嚴格說來僅及 Ruby Mix-in 一半的功力。例如我當年在《PHP 實踐 mix-in 概念 part 2 - MixableClass》實作的 MixableClass 所具有的動態增刪方法的能力,Traits 便做不到。Traits 目前僅提供靜態的混成。儘管如此,對大多數的程式人員而言,Traits 仍然是相當強大的語言能力,可以讓我們更有效地組織演算法,又避免多重繼承的陷阱。

先以《PHP 實踐 mix-in 概念之可行性》的範例程式來看,現在用 Traits 的寫法將如下所示:

<?php
trait sayBar {
    function bar() {
        echo 'bar: ', $this->name, "\n";
    }
}

class O {
    use sayBar; // using a trait!

    private $name;
    public function __construct($name) {
        $this->name = $name;
    }
}

$o = new O('abc');
$o->bar();

?>

更多關於 Traits 的內容,請詳閱《PHP 手冊:Traits》。

內建 Web 伺服器

哇,這真是令人興奮的新功能。雖然目前還只建議用於開發測試階段,但仍比以往還要自己裝 Apache 方便了。對於習慣在 Windows 平台上撰寫 PHP 程式後再上傳的程式人員來說,這個新功能免去了在 Windows 上安裝 Apache 的負擔。測試時也更方便了,只要在專案的工作目錄執行 PHP 內建 Web 伺服器,就可以進行專案的功能測試。不用放在 Apache 的公開網頁路徑下。

對了,PHP 內建 Web 伺服器還提供了 router 功能。我可以指定一個 PHP 程式負責安排 URL 的路徑。這個 router 實際上就是一些 PHP framework 的 index.php 。例如我自己寫的 CommonGateway 框架,就可以做為 PHP 內建 Web 伺服器的 router ,簡直是絕配啊。真是太妙了。

請詳閱《PHP 手冊:Built-in web server》。

其他

除了以上兩個特別顯著的功能外,PHP 5.4 還增加了一些新的語法。 新增語法讓一些程式碼變得更簡潔易讀,或是讓本來不能寫成一行的語法變成可以一行寫完。

以下列出我以往曾經抱怨 PHP 語法不支援,但這次新增的語法項目:

  • 陣列縮寫語法:
    我終於可以少打「a, r, r, a, y」這5個英文字母了。現在可以用 [ ] 來定義一個陣列。傳統寫法: array(1 => 'abc');新縮寫法: [1 => 'abc']
  • 二進位數字表示法:
    可用 0b 為前綴,表達一個二進位數字,例如 0b001010
  • 調用類別方法時,方法名稱支援以變數表達。例如 MyClass::$method()
  • 允許類別實體化後直接存取其成員。以前要寫兩行的動作: $tmp = new foo; $tmp->bar();;現在可以寫成一行: (new foo)->bar();

完整異動內容,請詳閱《Change Log》。

這些新語法與原有語法沒有任何衝突。至於 PHP 5.4 移除掉的語法,我個人很久以前就沒在用了,完全沒影響,就不列出了。

樂多舊網址: http://blog.roodo.com/rocksaying/archives/19048648.html

樂多舊回應
未留名 (#comment-22332624)
Fri, 02 Mar 2012 18:01:39 +0800
其實號稱performance提昇兩倍才是最讓人在意的..
HACGIS@gmail.com(tokimeki) (#comment-22425496)
Sun, 22 Apr 2012 00:56:18 +0800
在我看來,Traits 比較像是有實作內容的 Interface

話說我最近在用 C# 在寫一些應用,感覺不管是 P3P 也好,C#也罷,都提供了不透過繼承來擴充物件能力的方式。

有個問題想請教,我記得之前你曾提過 Ruby 跟 Python 有自識的能力,以區別 PHP 的反射。
那所謂的自識的能力有什麼特點呢?

C# 裡面所有的物件都繼承 Object,而 Object 具有一個 GetType() 的 public 成員,這可以說 C# 有自識的能力嗎?
未留名 (#comment-22426264)
Mon, 23 Apr 2012 10:34:17 +0800
在程式語言中,interface通常僅指外部可見的宣告敘述,不包含實作內容。
包含了實作內容在內的項目,通常叫模組、樣板、巨集或演算法。
所以稱 Traits 為模組或演算法集合較佳。

我的說法是「Reflection 一般譯為反射,但我稱為自識」。
See: http://blog.roodo.com/rocksaying/archives/2728221.html

也就是說,反射能力就是自識能力。但我用認知途徑來區分能力高下。

有些程式語言採用要個體先拿一面鏡子(反射體、reflector),才能看到自己樣貌的認知途徑,例如Java、C#。一般說來,這種途徑的程式語言,個體的自識能力都比較低下、使用比較不方便。

C# 當然有提供自識能力,但主要採反射途徑。GetType 只能說是自識能力中最基本的項目,甚至還不會列入能力標準之中。

PHP 兩種途徑都支援。舉例如下:

class A {
var $title = 'abc';
}

$a = new A();

/* 直接的自我認知 */
foreach ($a as $prop => $value) {
echo $prop, ': ', $value, "\n";
}

/* 拿鏡子看自己 */
$ref_a = new ReflectionObject($a);
foreach ($ref_a->getProperties() as $prop_reflector) {
$prop = $prop_reflector->name;
$vavlue = $a->$prop; //$value = $prop_reflector->getValue($a);
echo $prop, ': ', $value, "\n";
}
HACGIS@gmail.com(tokimeki) (#comment-22426910)
Mon, 23 Apr 2012 23:18:30 +0800
我會說有實作內容的 Interface 這句話是因為最近在寫 C# 的緣故。
C# 可以透過 Attribute 去指定某個 Class 為某個 Interface 的預設實作

你舉了一小段程式碼來說明直接的自我認知,這個就讓我很清楚來判斷認知途徑的方式了~
agrozyme@gmail.com(tokimeki) (#comment-25329628)
Mon, 27 Jul 2015 14:54:22 +0800
最近一年,因為新版的 Drupal 快要 Release 了,所以工作上終於可以用 PHP 5.4+ 的語法了~
回來找找文章溫故知新一下~