PHP 7使用新的Zend Engine 3.0將應用程序性能提高近兩倍,內存消耗比PHP 5.6高出50%。它允許服務更多的并發用戶,而不需要任何額外的硬件。PHP 7是考慮到今天的工作負載而設計和重構的。
## PHP新功能總結
* 改進的性能 - 將PHPNG代碼合并到PHP7中,速度是PHP 5的兩倍。
* 降低內存消耗 - 優化的PHP 7使用較少的資源。
* 標量類型聲明 - 現在可以強制執行參數和返回類型。
* 一致的64位支持 - 對64位體系結構機器的一致支持。
* 改進了異常層次 - 異常層次得到了改進
* 許多致命的錯誤轉換為例外 - 例外范圍增加,涵蓋許多致命的錯誤轉換為例外。
* 安全隨機數發生器 - 增加新的安全隨機數發生器API。
* 已棄用的SAPI和擴展已刪除 - 各種舊的和不受支持的SAPI和擴展從最新版本中刪除。
* 空合并運算符(?) - 添加了新的空合并運算符。
* 返回和標量類型聲明 - 支持所添加的返回類型和參數類型。
* 匿名類 - 支持匿名添加。
* 零成本斷言 - 支持零成本斷言增加。
### 標量類型聲明
在PHP 7中,引入了一個新的特性,即標量類型聲明。標量類型聲明有兩個選項
* 強制 - 強制是默認模式,不需要指定。
* 嚴格 - 嚴格的模式已經明確暗示。
功能參數的以下類型可以使用上述模式強制執行
* float
* int
* bool
* string
* interfaces
* array
* callable
#### 強制模式
```
<?php
// Coercive mode
function sum(int ...$ints) {
return array_sum($ints);
}
print(sum(2, '3', 4.1)); //9
?>
```
#### 嚴格模式
```
<?php
// Strict mode
declare(strict_types=1);
function sum(int ...$ints) {
return array_sum($ints);
}
print(sum(2, '3', 4.1)); //Fatal error: Uncaught TypeError: Argument 2 passed to sum() must be of the type integer, string given, ...
?>
```
#### 返回類型聲明
有效的返回類型
```
<?php
declare(strict_types = 1);
function returnIntValue(int $value): int {
return $value;
}
print(returnIntValue(5));
?>
```
#### 無效返回類型
```
<?php
declare(strict_types = 1);
function returnIntValue(int $value): int {
return $value + 1.0;
}
print(returnIntValue(5));//Fatal error: Uncaught TypeError: Return value of returnIntValue() must be of the type integer, float returned.
```
#### 空合并運算符
在PHP 7中,引入了一個新的特性,即空合并運算符(??)。它用來替代與isset()函數結合的三元操作。該空如果它存在,而不是空合并運算符返回第一個操作數; 否則返回第二個操作數。
```
<?php
// fetch the value of $_GET['user'] and returns 'not passed'
// if username is not passed
$username = $_GET['username'] ?? 'not passed';
print($username);
print("<br/>");
// Equivalent code using ternary operator
$username = isset($_GET['username']) ? $_GET['username'] : 'not passed';
print($username);
print("<br/>");
// Chaining ?? operation
$username = $_GET['username'] ?? $_POST['username'] ?? 'not passed';
print($username);
// output
//not passed
?>
```
#### 飛船運算符
它用來比較兩個表達式。當第一個表達式分別小于,等于或大于第二個表達式時,它返回-1,0或1。字符串比較ASCII
```
//integer comparison
print( 1 <=> 1);print("<br/>");
print( 1 <=> 2);print("<br/>");
print( 2 <=> 1);print("<br/>");
// output
0
-1
1
```
#### 常量數組
使用`define()`函數定義數組常量。在PHP 5.6中,只能使用`const`關鍵字來定義它們。
```
<?php
//define a array using define function
define('animals', [
'dog',
'cat',
'bird'
]);
print(animals[1]);
// output
cat
?>
```
#### 匿名類
現在可以使用新類來定義匿名類。匿名類可以用來代替完整的類定義。
```
<?php
interface Logger {
public function log(string $msg);
}
class Application {
private $logger;
public function getLogger(): Logger {
return $this->logger;
}
public function setLogger(Logger $logger) {
$this->logger = $logger;
}
}
$app = new Application;
$app->setLogger(new class implements Logger {
public function log(string $msg) {
print($msg);
}
});
$app->getLogger()->log("My first Log Message");
?>
//output
My first Log Message
```
#### Closure類
`Closure :: call()`方法被添加為一個簡短的方式來臨時綁定一個對象作用域到一個閉包并調用它。與PHP5的bindTo相比,它的性能要快得多。
**在PHP 7之前**
```
<?php
class A {
private $x = 1;
}
// Define a closure Pre PHP 7 code
$getValue = function() {
return $this->x;
};
// Bind a clousure
$value = $getValue->bindTo(new A, 'A');
print($value());
//output
1
?>
```
**PHP 7+**
```
<?php
class A {
private $x = 1;
}
// PHP 7+ code, Define
$value = function() {
return $this->x;
};
print($value->call(new A));
//output
1
?>
```
#### 過濾unserialize
PHP 7引入了過濾的`unserialize()`函數,以便在對不可信數據上的對象進行反序列化時提供更好的安全性。它可以防止可能的代碼注入,并使開發人員能夠對可以反序列化的類進行白名單。
```
<?php
class MyClass1 {
public $obj1prop;
}
class MyClass2 {
public $obj2prop;
}
$obj1 = new MyClass1();
$obj1->obj1prop = 1;
$obj2 = new MyClass2();
$obj2->obj2prop = 2;
$serializedObj1 = serialize($obj1);
$serializedObj2 = serialize($obj2);
// default behaviour that accepts all classes
// second argument can be ommited.
// if allowed_classes is passed as false, unserialize converts all objects into __PHP_Incomplete_Class object
$data = unserialize($serializedObj1 , ["allowed_classes" => true]);
// converts all objects into __PHP_Incomplete_Class object except those of MyClass1 and MyClass2
$data2 = unserialize($serializedObj2 , ["allowed_classes" => ["MyClass1", "MyClass2"]]);
print($data->obj1prop);
print("<br/>");
print($data2->obj2prop);
//output
1
2
?>
```
#### IntlChar
在PHP7中,增加了一個新的IntlChar類,它試圖揭示額外的ICU功能。這個類定義了一些靜態方法和常量,可以用來處理Unicode字符。在使用這個課程之前,你需要安裝Intl擴展。
```
<?php
printf('%x', IntlChar::CODEPOINT_MAX);
print (IntlChar::charName('@'));
print(IntlChar::ispunct('!'));
//output
10ffff
COMMERCIAL AT
true
?>
```
#### CSPRNG
在PHP 7中,引入了兩個新的函數來以跨平臺的方式生成密碼安全的整數和字符串。
* random_bytes() - 生成密碼安全的偽隨機字節。
* random_int() - 生成密碼安全的偽隨機整數。
```
<?php
$bytes = random_bytes(5);
print(bin2hex($bytes));
//output
54cc305593
print(random_int(100, 999));
print("");
print(random_int(-1000, 0));
//output
614
-882
?>
```
#### 使用聲明
從PHP7開始,可以使用單個`use`語句從相同的命名空間導入類,函數和常量,而不是使用多個`use`語句。
```
<?php
// Before PHP 7
use com\tutorialspoint\ClassA;
use com\tutorialspoint\ClassB;
use com\tutorialspoint\ClassC as C;
use function com\tutorialspoint\fn_a;
use function com\tutorialspoint\fn_b;
use function com\tutorialspoint\fn_c;
use const com\tutorialspoint\ConstA;
use const com\tutorialspoint\ConstB;
use const com\tutorialspoint\ConstC;
// PHP 7+ code
use com\tutorialspoint\{ClassA, ClassB, ClassC as C};
use function com\tutorialspoint\{fn_a, fn_b, fn_c};
use const com\tutorialspoint\{ConstA, ConstB, ConstC};
?>
```
#### 整數部分
PHP 7引入了一個新的函數`intdiv()`,它對它的操作數進行整數除法,并將除法運算返回為int。
```
<?php
$value = intdiv(10,3);
var_dump($value);
print(" ");
print($value);
//output
int(3)
3
?>
```
#### 會話選項
`session_start()`函數接受來自PHP7 + 的一系列選項來覆蓋php.ini中設置的會話配置指令。這些選項支持`session.lazy_write`,默認情況下,它會導致PHP在會話數據發生更改時覆蓋任何會話文件。
添加的另一個選項是`read_and_close`,它表示應該讀取會話數據,然后應該立即關閉會話。例如,將`session.cache_limiter`設置為`private`,并使用以下代碼片段將標志設置為在讀取完畢后立即關閉會話。
```
<?php
session_start([
'cache_limiter' => 'private',
'read_and_close' => true,
]);
?>
```
#### 棄用
PHP 4樣式構造函數是與它們定義的類具有相同名稱的方法,現在已被棄用,并且將來將被刪除。如果PHP 4的構造函數是類中定義的唯一構造函數,則PHP 7將發出`E_DEPRECATED`。實現`__construct()`方法的類不受影響。
```
<?php
class A {
function A() {
print('Style Constructor');
}
}
?>
```
對非靜態方法的靜態調用已被棄用,并可能在將來被刪除
```
<?php
class A {
function b() {
print('Non-static call');
}
}
A::b();
// Deprecated: Non-static method A::b() should not be called statically in...Non-static call
?>
```
`password_hash()`函數的salt選項已被棄用,所以開發人員不會生成自己的(通常是不安全的)鹽。當開發人員不提供鹽時,函數本身會生成密碼安全的鹽,因此不再需要定制鹽的生成。
該`capture_session_meta`SSL上下文選項已被棄用。SSL元數據現在通過`stream_get_meta_data()`函數使用。
#### 錯誤處理
從PHP 7開始,錯誤處理和報告已經改變。而不是通過PHP 5使用的傳統錯誤報告機制來報告錯誤,現在大多數錯誤都是通過拋出錯誤異常來處理的。與異常類似,這些錯誤異常會一直冒泡,直到它們到達第一個匹配的catch塊。如果沒有匹配的塊,則使用set_exception_handler()安裝的默認異常處理程序將被調用。如果沒有默認的異常處理程序,那么異常將被轉換為致命錯誤,并將像傳統的錯誤一樣處理。
由于錯誤層次結構不是從Exception擴展的,所以使用`catch(Exception $e){...}`塊來處理PHP 5中未捕獲的異常的代碼將不會處理這樣的錯誤。`catch(Error $e){...}`塊或`set_exception_handler()`處理程序是處理致命錯誤所必需的。
```
<?php
class MathOperations {
protected $n = 10;
// Try to get the Division by Zero error object and display as Exception
public function doOperation(): string {
try {
$value = $this->n % 0;
return $value;
} catch (DivisionByZeroError $e) {
return $e->getMessage();
}
}
}
$mathOperationsObj = new MathOperations();
print($mathOperationsObj->doOperation());
// output
Modulo by zero
?>
```
- 目錄
- 第1章 PHP基本架構
- 1.1 PHP簡介
- 1.2 PHP7的改進
- 1.3 FPM
- 1.4 PHP執行的幾個階段
- 第2章 變量
- 2.1 變量的內部實現
- 2.2 數組
- 2.3 靜態變量
- 2.4 全局變量
- 2.5 常量
- 3.1 PHP代碼的編譯
- 3.1.1 詞法解析、語法解析
- 3.1.2 抽象語法樹編譯流程
- 第3章 Zend虛擬機
- 3.2.1 內部函數
- 3.2.2 用戶函數的實現
- 3.3 Zend引擎執行流程
- 3.3.1 基本結構
- 3.2 函數實現
- 3.3.2 執行流程
- 3.3.3 函數的執行流程
- 3.3.4 全局execute_data和opline
- 3.4 面向對象實現
- 3.4.1 類
- 3.4.2 對象
- 3.4.3 繼承
- 3.4.4 動態屬性
- 3.4.5 魔術方法
- 3.4.6 類的自動加載
- 3.5 運行時緩存
- 3.6 Opcache
- 3.6.1 opcode緩存
- 3.6.2 opcode優化
- 3.6.3 JIT
- 第4章 PHP基礎語法實現
- 4.1 類型轉換
- 4.2 選擇結構
- 4.3 循環結構
- 4.4 中斷及跳轉
- 4.5 include/require
- 4.6 異常處理
- 第5章 內存管理
- 5.1 Zend內存池
- 5.2 垃圾回收
- 第6章 線程安全
- 6.2 線程安全資源管理器
- 第7章 擴展開發
- 7.1 概述
- 6.1 什么是線程安全
- 7.2 擴展的實現原理
- 7.3 擴展的構成及編譯
- 7.4 鉤子函數
- 7.5 運行時配置
- 7.6 函數
- 7.7 zval的操作
- 7.8 常量
- 7.9 面向對象
- 7.9.1 內部類注冊
- 7.9.2 定義成員屬性
- 7.9.3 定義成員方法
- 7.9.4 定義常量
- 7.9.5 類的實例化
- 7.10 資源類型
- 7.11 經典擴展解析
- 7.8.1 Yaf
- 7.8.2 Redis
- 第8章 命名空間
- 8.2 命名空間的定義
- 8.2.1 定義語法
- 8.2.2 內部實現
- 8.3 命名空間的使用
- 8.3.1 基本用法
- 8.3.2 use導入
- 8.3.3 動態用法
- 附錄
- 附錄1:break/continue按標簽中斷語法實現
- 附錄2:defer推遲函數調用語法的實現
- 8.1 概述