PHP7新特性(上)
PHP7出来也很久了,都说PHP7的性能有了很大的提高,现在介绍下PHP7的新特性
Group use declarations
从同一 namespace 导入的类、函数和常量现在可以通过单个 use 语句 一次性导入了
1 | //PHP7之前 |
支持延迟静态绑定
static关键字来引用当前类,即实现了延迟静态绑定
1 | class A { |
输出结果:B
支持goto语句
多数计算机程序设计语言中都支持无条件转向语句goto,当程序执行到goto语句时,即转向由goto语句中的标号指出的程序位置继续执行。尽管goto语句有可能会导致程序流程不清晰,可读性减弱,但在某些情况下具有其独特的方便之处,例如中断深度嵌套的循环和 if 语句。
1 | goto a; |
支持闭包、Lambda/Anonymous函数
1、闭包(Closure)函数和Lambda函数的概念来自于函数编程领域。例如JavaScript 是支持闭包和 lambda 函数的最常见语言之一
2、在PHP中,我们也可以通过create_function()在代码运行时创建函数。但有一个问题:创建的函数仅在运行时才被编译,而不与其它代码同时被编译成执行码,因此我们无法使用类似APC这样的执行码缓存来提高代码执行效率
3、在PHP5.3中,我们可以使用Lambda/匿名函数来定义一些临时使用(即用即弃型)的函数,以作为array_map()/array_walk()等函数的回调函数
1 | echo preg_replace_callback('~-([a-z])~', function ($match) { |
魔术方法callStatic()和invoke()
PHP中原本有一个魔术方法call(),当代码调用对象的某个不存在的方法时该魔术方法会被自动调用。新增的callStatic()方法则只用于静态类方法。当尝试调用类中不存在的静态方法时,__callStatic()魔术方法将被自动调用。
1 | class MethodTest { |
以上代码执行后输出如下:
调用对象方法’runTest’ –- 通过对象调用调用静态方法’runTest’ –- 静态调用
以函数形式来调用对象时,__invoke()方法将被自动调用。
1 | class MethodTest { |
Nowdoc语法
用法和Heredoc类似,但使用单引号。Heredoc则需要通过使用双引号来声明。
Nowdoc中不会做任何变量解析,非常适合于传递一段PHP代码。
1 | // Nowdoc 单引号 PHP 5.3之后支持 |
支持通过Heredoc来初始化静态变量、类成员和类常量。
1 | // 静态变量 |
在类外也可使用const来定义常量
1 | //PHP中定义常量通常是用这种方式 |
三元运算符增加了一个快捷书写方式
原本格式为是(expr1) ? (expr2) : (expr3)
如果expr1结果为True,则返回expr2的结果。
新增一种书写方式,可以省略中间部分,书写为expr1 ?: expr3
如果expr1结果为True,则返回expr1的结果
1 | expr1=1; |
输出结果:
1
1
空合并运算符(??)
简化判断
1 | param = $_GET['param'] ?? 1; |
相当于:
1 | $param = isset($_GET['param']) ? $_GET['param'] : 1; |
Json更懂中文(JSON_UNESCAPED_UNICODE)
1 | echo json_encode("中文", JSON_UNESCAPED_UNICODE); |
二进制
1 | $bin = 0b1101; |
Unicode codepoint 转译语法
这接受一个以16进制形式的 Unicode codepoint,并打印出一个双引号或heredoc包围的 UTF-8 编码格式的字符串。 可以接受任何有效的 codepoint,并且开头的 0 是可以省略的。
1 | echo "\u{9876}" |
使用 ** 进行幂运算
加入右连接运算符 来进行幂运算。 同时还支持简写的 = 运算符,表示进行幂运算并赋值。
1 | printf("2 ** 3 == %d\n", 2 ** 3); |
输出
2 ** 3 == 8
2 3 2 == 512
a == 8
太空船操作符(组合比较符)
太空船操作符用于比较两个表达式。当 b 时它分别返回 -1 、 0 或 1 。 比较的原则是沿用 PHP 的常规比较规则进行的。
1 | // Integers |
Traits
Traits提供了一种灵活的代码重用机制,即不像interface一样只能定义方法但不能实现,又不能像class一样只能单继承。至于在实践中怎样使用,还需要深入思考。
魔术常量为TRAIT
1 | 官网的一个例子: |
array 数组简写语法
1 | $arr = [1,'james', 'james@fwso.cn']; |
array 数组中某个索引值简写
1 | function myfunc() { |
非变量array和string也能支持下标获取了
1 | echo array(1, 2, 3)[0]; |
支持为负的字符串偏移量
现在所有接偏移量的内置的基于字符串的函数都支持接受负数作为偏移量,包括数组解引用操作符([]).
1 | var_dump("abcdef"[-2]); |
以上例程会输出
1 | string (1) "e" |
常量引用
“常量引用”意味着数组可以直接操作字符串和数组字面值。举两个例子:
1 | function randomHexString($length) { |
常量增强
允许常量计算,允许使用包含数字、字符串字面值和常量的标量表达式
1 | const A = 2; |
允许常量作为函数参数默认
1 | function test($arg = C::STR2) |
类常量可见性
现在起支持设置类常量的可见性。
1 | class ConstDemo |
通过define()定义常量数组
1 | define('ANIMALS', ['dog', 'cat', 'bird']); |
函数变量类型声明
两种模式 : 强制 ( 默认 ) 和 严格模式
类型:array,object(对象),string、int、float和 bool1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24class bar {
function foo(bar $foo) {
}
//其中函数foo中的参数规定了传入的参数必须为bar类的实例,否则系统会判断出错。同样对于数组来说,也可以进行判断,比如:
function foo(array $foo) {
}
}
foo(array(1, 2, 3)); // 正确,因为传入的是数组
foo(123); // 不正确,传入的不是数组
function add(int $a)
{
return 1+$a;
}
var_dump(add(2));
function foo(int $i) { ... }
foo(1); // $i = 1
foo(1.0); // $i = 1
foo("1"); // $i = 1
foo("1abc"); // not yet clear, maybe $i = 1 with notice
foo(1.5); // not yet clear, maybe $i = 1 with notice
foo([]); // error
foo("abc"); // error
可变函数参数
代替 func_get_args()
1 | function add(...$args) |
可为空(Nullable)类型
类型现在允许为空,当启用这个特性时,传入的参数或者函数返回的结果要么是给定的类型,要么是 null 。可以通过在类型前面加上一个问号来使之成为可为空的。
1 | function test(?string $name) |
以上例程会输出:
1 | string(5) "tpunt" |
Void 函数
在PHP 7 中引入的其他返回值类型的基础上,一个新的返回值类型void被引入。 返回值声明为 void 类型的方法要么干脆省去 return 语句,要么使用一个空的 return 语句。 对于 void 函数来说,null 不是一个合法的返回值。
1 | function swap(&$left, &$right) : void |
以上例程会输出:
null
int(2)
int(1)
试图去获取一个 void 方法的返回值会得到 null ,并且不会产生任何警告。这么做的原因是不想影响更高层次的方法。
实例化类
1 | class test{ |
支持 Class::{expr}() 语法
1 | foreach ([new Human("Gonzalo"), new Human("Peter")] as $human) { |
Getter 和 Setter
如果你从不喜欢写这些getXYZ()和setXYZ($value)方法,那么这应该是你最受欢迎的改变。提议添加一个新的语法来定义一个属性的设置/读取:
1 | class TimePeriod { |