PHP新特性之命名空間、性狀和生成器

1.命名空間

命名空間是什麼?

1).命名空間在PHP 5.3中被引入,相似於文件夾的功能。例如Symfony框架中的Request和Response,位於Symfony的命名空間下。
2).命名空間始終應該在<?php標籤的下面一行。
3).PHP文件的命名空間和操做系統的物理文件系統不一樣,這是一個虛擬的概念,沒有必要和文件系統的目錄結構徹底對應。雖然如此,絕大多數PHP組件爲了兼容普遍使用的PSR4自動加載標準,會把子命名空間放到文件系統的子目錄中去。
4).命名空間只是PHP語言的一種記號,PHP解釋器會將這種記號做爲前綴添加到類、接口、函數和常量的名稱前面。php

爲何須要命名空間?

1).命名空間使得程序能夠像沙盒同樣運行,能夠和其餘開發者編寫的代碼一塊兒使用。確保了本身的代碼和項目能夠和項目的第三方依賴一塊兒使用。git

聲明命名空間

1).頂層命名空間常常用於設定頂層廠商名。
2).廠商的命名空間必須具備全局惟一性,子命名空間就沒有那麼重要,但有助於組織項目的代碼。github

導入和別名

1).從PHP5.3開始能夠導入PHP類、接口和其餘命名空間,併爲其建立別名。從PHP5.6開始能夠導入PHP函數和常量,併爲其建立別名。
2).使用use關鍵字導入代碼時無須在開頭加上符號,由於PHP假定導入的是徹底限定命名空間。use關鍵字必須出如今全局做用域中即不能出如今類或者函數中,由於這個關鍵字是在編譯的時候使用的,不過,use關鍵字能夠在命名空間聲明語句後使用,導入其餘命名空間的代碼。
從PHP5.6開始咱們能夠導入函數和常量。web

<?php
use func Namespace\functionName;

functionName();

也能夠導入常量,數組

use constant Namespace\CONS_NAME;
echo CONS_NAME;

函數和常量的別名與類名的建立方式同樣。框架

最佳實踐

1).PHP容許在一個PHP文件中定義多個命名空間。可是這麼作容易讓人困惑,違背了一個文件一個類的良好實踐。
2).在一個命名空間中引用全局的命名空間的代碼時,須要加上前綴,告訴PHP須要在全局中查找該類,例如PHP原生的異常類。模塊化

自動加載

1).命名空間爲PHP-FIG制定的PSR4自動加載器奠基了堅實的基礎。函數

2.使用接口

1).就像我能夠選擇開不同的車。由於他們都有方向盤、油門和剎車,而且燃料都是汽油。優化

3.性狀

1).形狀是類的部分實現(常量、屬性和方法),能夠混入一個或者多個現有的PHP類中,性狀有兩個做用,代表類能夠作什麼(相似接口),提供模塊化實踐(相似類)。
2).性狀使得兩個無關的類能夠使用相同屬性和方法。
3).PHP解釋器會把性狀複製粘貼到類的定義體中。spa

4.建立生成器

1)在普通函數中一次或者屢次使用yield關鍵字,不返回值,只生成值,這個函數就是一個生成器。例如:

<?php
function myGenerator() {
    yield 'value1';
    yield 'value2';
}

調用生成器函數的時候,PHP會返回一個屬於Generator類的對象,這個對象能夠使用foreach()函數迭代,每次迭代,PHP會要求這個對象的實例計算並提供下一個要迭代的值,生成器的優雅之處就是在每產出一個值以後,生成器內部狀態會一直停頓和恢復之間切換,直到抵達定義體的末尾或者遇到空的return;語句爲止,例如:

<?php
foreach (myGenerator() as $yieldedValue) {
    echo $yieldedValue, PHP_EOL;
}

以上例子會輸出

value1
value2

2).生成器是如何節約內存的?生成一個範圍內的數值(錯誤方式)

function makeRange($length) {
    $dataset = [];
    for ($i=0; $i < $length; $i++) {
      $dataset[] = $i;
    }
    return $dataset;
}

$customRange = makeRange(1000000);
foreach ($customeRange as $i) {
    echo $i, PHP_EOL;
}

預先建立了一個包含很大整數組成的數組,再看使用生成器的例子。

function makeRange($length) {
    for ($i = 0; $i < $length; $i++) {
        yield $i;
    }
}

foreach(makeRange(1000000) as $i) {
    echo $i, PHP_EOL;
}

在實際的例如迭代一個4GB大小的文件中功能中,迭代器大展身手。

function getRows($file) {
    $handle = fopen($file, 'rb');
    if ($handle === false) {
        throw new Exception();
    }
    //feof()函數檢測是否到達文件末尾
    while (feof($handle) === false) {
        //fgetcsv()一次讀取csv文件的一行
        yield fgetcsv($handle);
    }
    fclose($handle)
}

foreach (getRows('data.csv') as $row) {
    print_r($row);
}

3).生成器沒有爲PHP添加新功能,須要實如今數據集中執行快進、快退和查找,最好本身編寫類實現Iterator接口,或者使用PHP標準庫中的某個原生迭代器。
原生迭代器連接

專題系列

PHP專題系列目錄地址:https://github.com/xx19941215/webBlogPHP專題系列預計寫二十篇左右,主要總結咱們平常PHP開發中容易忽略的基礎知識和現代PHP開發中關於規範、部署、優化的一些實戰性建議,同時還有對Javascript語言特色的深刻研究。

相關文章
相關標籤/搜索