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 概述