天天看點

PHP>5.3版本部分新功能

【php5.3的新增、改進】匿名函數

也叫閉包(closures), 經常被用來臨時性地建立一個無名函數,用于回調函數等用途。

PHP>5.3版本部分新功能

$func = function ($arg) {  

    print $arg;  

};  

$func("hello world");  

 匿名函數還可以用 use 關鍵字來捕捉外部變量:

PHP>5.3版本部分新功能

function arrayplus($array, $num)  

{  

    array_walk($array, function (&$v) use ($num) {  

        $v += $num;  

    });  

}  

上面的代碼定義了一個 arrayplus() 函數(這不是匿名函數), 它會将一個數組($array)中的每一項,加上一個指定的數字($num).在 arrayplus() 的實作中,我們使用了 array_walk() 函數,它會為一個數組的每一項執行一個回調函數,即我們定義的匿名函數。在匿名函數的參數清單後,我們用 use 關鍵字将匿名函數外的 $num 捕捉到了函數内,以便知道到底應該加上多少。

後期靜态綁定php的繼承模型中有一個存在已久的問題,那就是在父類中引用擴充類的最終狀态比較困難。

PHP>5.3版本部分新功能

<?php  

class parentbase  

    static $property = 'parent value';  

    public static function render()  

    {  

        return self::$property;  

    }  

class descendant extends parentbase  

    static $property = 'descendant value';  

//output: parent value  

echo descendant::render();  

在這個例子中,render()方法中使用了self關鍵字,這是指parentbase類而不是指descendant類。在 parentbase::render()方法中沒法通路$property的最終值。為了解決這個問題,需要在子類中重寫render()方法。通過引入延遲靜态綁定功能,可以使用static作用域關鍵字通路類的屬性或者方法的最終值

PHP>5.3版本部分新功能

        return static::$property;  

    public static function status()  

        static::getstatus();  

    protected static function getstatus()  

        echo "person is alive";  

//output: descendant value  

php的面向對象體系中,提供了若幹“魔術方法”,用于實作類似其他語言中的“重載”,如在通路不存在的屬性、方法時觸發某個魔術方法。

__call($funcname, $arguments)

__callstatic($funcname, $arguments)

參數說明:

$funcname string 調用的不存在的方法名稱。

$arguments array 調用方法時所帶的參數。

 __invoke魔術方法會在将一個對象作為函數調用時被調用:

PHP>5.3版本部分新功能

class a  

    public function __invoke($args)  

        print "a::__invoke(): {$args}";  

$a = new a;  

//output: a::__invoke(): hello world  

$a("hello world");  

 __callstatic則會在調用一個不存在的靜态方法時被調用,有了__callstatic,可以省不少代碼了。而且這個方法支援在子類中調用,配合上get_called_class,子類也一起魔術了

PHP>5.3版本部分新功能

class activerecordbase  

    /**  as of php 5.3.0  */  

    public static function __callstatic($func, $arguments)  

        if ($func == 'getbyid') {  

            $id = $arguments[0];  

            return get_called_class() . '(' . $id . ')';  

        }  

        throw new exception('invalid method : ' . $name);  

class person extends activerecordbase  

// output: person(123)  

echo person::getbyid(123);  

__call 當要調用的方法不存在或權限不足時,會自動調用__call 方法。

PHP>5.3版本部分新功能

class db  

    private $sql = array(  

        "field" => "",  

        "where" => "",  

        "order" => "",  

        "limit" => "",  

        "group" => "",  

        "having" => "",  

    );  

    // 連貫操作調用field() where() order() limit() group() having()方法,組合sql語句  

    function __call($methodname, $args)  

        // 将第一個參數(代表不存在方法的方法名稱),全部轉成小寫方式,擷取方法名稱  

        $methodname = strtolower($methodname);  

        // 如果調用的方法名和成員屬性數組$sql下标對應上,則将第二個參數給數組中下标對應的元素  

        if (array_key_exists($methodname, $this->sql)) {  

            $this->sql[$methodname] = $args[0];  

        } else {  

            echo '調用類' . get_class($this) . '中的方法' . $methodname . '()不存在';  

        // 傳回自己對象,則可以繼續調用本對象中的方法,形成連貫操作  

        return $this;  

    // 輸出連貫操作後組合的一個sql語句,是連貫操作最後的一個方法  

    function select()  

        echo "select {$this->sql['field']} from  user {$this->sql['where']} {$this->sql['order']} {$this->sql['limit']} {$this->sql['group']}  

                {$this->sql['having']}";  

$db = new db();  

// 連貫操作  

$db->field('sex, count(sex)')  

    ->where('where sex in ("男","女")')  

    ->group('group by sex')  

    ->having('having avg(age) > 25')  

    ->select();  

?>  

命名空間一個最明确的目的就是解決重名問題,php中不允許兩個函數或者類出現相同的名字,否則會産生一個緻命的錯誤。這種情況下隻要避免命名重複就可以解決,最常見的一種做法是約定一個字首。

PHP>5.3版本部分新功能

//建立空間blog  

namespace blog;  

class comment  

//非限定名稱,表示目前blog空間  

//這個調用将被解析成 blog\comment();  

$blog_comment = new comment();  

//限定名稱,表示相對于blog空間  

//這個調用将被解析成 blog\article\comment();  

$article_comment = new article\comment(); //類前面沒有反斜杆\  

//完全限定名稱,表示絕對于blog空間  

$article_comment = new \blog\comment(); //類前面有反斜杆\  

$article_comment = new \blog\article\comment(); //類前面有反斜杆\  

//建立blog的子空間article  

namespace blog\article;  

别名和導入可以看作是調用命名空間元素的一種快捷方式。php并不支援導入函數或常量。 它們都是通過使用use操作符來實作:

PHP>5.3版本部分新功能

//建立一個bbs空間(我有打算開個論壇)  

namespace bbs;  

//導入一個命名空間  

use blog\article;  

//導入命名空間後可使用限定名稱調用元素  

$article_comment = new article\comment();  

//為命名空間使用别名  

use blog\article as arte;  

//使用别名代替空間名  

$article_comment = new arte\comment();  

//導入一個類  

use blog\article\comment;  

//導入類後可使用非限定名稱調用元素  

$article_comment = new comment();  

//為類使用别名  

use blog\article\comment as comt;  

$article_comment = new comt();  

 php5.4

數組簡寫形式

PHP>5.3版本部分新功能

//原來的數組寫法  

$arr = array("key" => "value", "key2" => "value2");  

// 簡寫形式  

$arr = ["key" => "value", "key2" => "value2"];  

traits

所謂traits就是“構件”,是用來替代繼承的一種機制。trait和類相似,但不能被執行個體化php中無法進行多重繼承,但一個類可以包含多個traits.

PHP>5.3版本部分新功能

trait sayworld  

    public $var = 'test';  

    public function sayhello()  

        echo 'world!';  

class myhelloworld  

    // 将sayworld中的成員包含進來  

    use sayworld;  

$xxoo = new myhelloworld();  

// sayhello()函數是來自sayworld構件的 $xxoo->var  

$xxoo->sayhello();  

traits還有很多神奇的功能,比如包含多個traits, 解決沖突,修改通路權限,為函數設定别名等等。

新增在執行個體化時通路類成員的特征:

PHP>5.3版本部分新功能

(new myclass)->xxoo();  

 新增支援對函數傳回數組的成員通路解析

PHP>5.3版本部分新功能

print [1, 2, 3][0];  

 php5.5

yield的一個功能就是能有效的降低疊代的記憶體開銷,yield關鍵字用于當函數需要傳回一個疊代器的時候, 逐個傳回值.也就是說, 每當産生一個數組元素, 就通過yield關鍵字傳回成一個, 并且函數執行暫停, 當傳回的疊代器的next方法被調用的時候, 會恢複剛才函數的執行, 從上一次被yield暫停的位置開始繼續執行, 到下一次遇到yield的時候, 再次傳回.

PHP>5.3版本部分新功能

function generators()  

    for ($i = 1; $i <= 10; $i += 1) {  

        yield $i;  

foreach (generators() as $v) {  

    echo $v;  

 可以用 list() 在 foreach 中解析嵌套的數組:

PHP>5.3版本部分新功能

$array = [  

    [1, 2, 3],  

    [4, 5, 6],  

];  

foreach ($array as list($a, $b, $c))  

    echo "{$a} {$b} {$c}\n";  

 aaa