|
|
|
|
7.0 |
1、标量参数类型声明 |
标量类型声明 有两种模式: 强制 (默认) 和 严格模式。?
现在可以使用下列类型参数(无论用强制模式还是严格模式):?
字符串(string),?
整数 (int),?
浮点数 (float),?
以及布尔值 (bool)。
它们扩充了PHP5中引入的其他类型:类名,接口,数组和 回调类型。
|
//?Coercive?mode
function?sumOfInts(int?...$ints)
{
????return?array_sum($ints);
}
var_dump(sumOfInts(2,?‘3‘,?4.1));
|
|
2、返回值类型声明 |
返回类型声明指明了函数返回值的类型。可用的类型与参数声明中可用的类型相同。 |
function?arraysSum(array?...$arrays):?array
{
????return?array_map(function(array?$array):?int?{
????????return?array_sum($array);
????},?$arrays);
}
print_r(arraysSum([1,2,3],?[4,5,6],?[7,8,9]));
|
|
3、null合并运算符 |
如果变量存在且值不为NULL, 它就会返回自身的值,否则返回它的第二个操作数。 |
//?Fetches?the?value?of?$_GET[‘user‘]?and?returns?‘nobody‘
//?if?it?does?not?exist.
$username?=?$_GET[‘user‘]????‘nobody‘;
//?This?is?equivalent?to:
$username?=?isset($_GET[‘user‘])???$_GET[‘user‘]?:?‘nobody‘;
//?Coalesces?can?be?chained:?this?will?return?the?first
//?defined?value?out?of?$_GET[‘user‘],?$_POST[‘user‘],?and
//?‘nobody‘.
$username?=?$_GET[‘user‘]????$_POST[‘user‘]????‘nobody‘;
?>
|
|
4、太空船操作符(组合比较符) |
用于比较两个表达式。当$a小于、等于或大于$b时它分别返回-1、0或1 |
//?整数
echo?1??1;?//?0
echo?1??2;?//?-1
echo?2??1;?//?1
//?浮点数
echo?1.5??1.5;?//?0
echo?1.5??2.5;?//?-1
echo?2.5??1.5;?//?1
?
//?字符串
echo?"a"??"a";?//?0
echo?"a"??"b";?//?-1
echo?"b"??"a";?//?1
|
|
5、通过 define() 定义常量数组 |
在 PHP5.6 中仅能通过 const 定义。 |
define(‘ANIMALS‘,?[
????‘dog‘,
????‘cat‘,
????‘bird‘
]);
echo?ANIMALS[1];?//?输出?"cat"
|
|
6、匿名类 |
|
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)?{
????????echo?$msg;
????}
});
var_dump($app->getLogger());
|
|
7、Unicode codepoint 转译语法 |
接受一个以16进制形式的 Unicode codepoint,并打印出一个双引号或heredoc包围的 UTF-8 编码格式的字符串 |
echo "\u{aa}";
echo "\u{0000aa}";
echo "\u{9999}";
|
|
8、Closure::call() |
简短干练的暂时绑定一个方法到对象上闭包并调用它。 |
class?A?{private?$x?=?1;}
//?PHP?7?之前版本的代码
$getXCB?=?function()?{return?$this->x;};
$getX?=?$getXCB->bindTo(new?A,?‘A‘);?//?中间层闭包
echo?$getX();
//?PHP?7+?及更高版本的代码
$getX?=?function()?{return?$this->x;};
echo?$getX->call(new?A);
|
|
9、为unserialize()提供过滤 |
通过白名单的方式来防止潜在的代码注入。 |
//?将所有的对象都转换为?__PHP_Incomplete_Class?对象
$data?=?unserialize($foo,?["allowed_classes"?=>?false]);
//?将除?MyClass?和?MyClass2?之外的所有对象都转换为?__PHP_Incomplete_Class?对象
$data?=?unserialize($foo,?["allowed_classes"?=>?["MyClass",?"MyClass2"]);
//?默认情况下所有的类都是可接受的,等同于省略第二个参数
$data?=?unserialize($foo,?["allowed_classes"?=>?true]);
|
|
10、断言 |
assert()现在是一个语言结构,它允许第一个参数是一个表达式,而不仅仅是一个待计算的 string或一个待测试的boolean。 |
ini_set(‘assert.exception‘,?1);
class?CustomError?extends?AssertionError?{}
assert(false,?new?CustomError(‘Some?error?message‘));
|
|
11、Group use declarations |
从同一 namespace 导入的类、函数和常量现在可以通过单个 use 语句 一次性导入了。 |
//?PHP?7+?及更高版本的代码
use?some\namespace\{ClassA,?ClassB,?ClassC?as?C};
use?function?some\namespace\{fn_a,?fn_b,?fn_c};
use?const?some\namespace\{ConstA,?ConstB,?ConstC};
|
|
12、生成器可以返回表达式 |
允许在生成器函数中通过使用 return 语法来返回一个表达式 (但是不允许返回引用值), 可以通过调用 Generator::getReturn() 方法来获取生成器的返回值, 但是这个方法只能在生成器完成产生工作以后调用一次。 |
$gen?=?(function()?{
????yield?1;
????yield?2;
????return?3;
})();
foreach?($gen?as?$val)?{
????echo?$val,?PHP_EOL;
}
echo?$gen->getReturn(),?PHP_EOL;
|
|
13、生成器委托 |
只需在最外层生成器中使用 yield from, 就可以把一个生成器自动委派给其他的生成器, Traversable 对象或者 array。 |
function?gen()
{
????yield?1;
????yield?2;
????yield?from?gen2();
}
function?gen2()
{
????yield?3;
????yield?4;
}
foreach?(gen()?as?$val)
{
????echo?$val,?PHP_EOL;
}
|
|
14、整数除法函数 intdiv() |
进行 整数的除法运算。 |
|
|
15、可以使用 list() 函数来展开实现了 ArrayAccess 接口的对象 |
|
|
7.1 |
1、Nullable类型 |
参数以及返回值的类型通过在类型前加上一个问号使之允许为空 |
function?testReturn():??string
{
????return?‘elePHPant‘;
}
var_dump(testReturn());
function?testReturn():??string
{
????return?null;
}
var_dump(testReturn());
function?test(?string?$name)
{
????var_dump($name);
}
test(‘elePHPant‘);
test(null);
test();
|
|
2、Void 函数 |
方法要么干脆省去 return 语句,要么使用一个空的 return 语句。?
对于 void 函数来说,NULL 不是一个合法的返回值。
|
function?swap(&$left,?&$right)?:?void
{
????if?($left?===?$right)?{
????????return;
????}
????$tmp?=?$left;
????$left?=?$right;
????$right?=?$tmp;
}
$a?=?1;
$b?=?2;
var_dump(swap($a,?$b),?$a,?$b);
|
|
3、对称性数组解构 |
短数组语法([])现在作为list()语法的一个备选项,可以用于将数组的值赋给一些变量(包括在foreach中) |
$data?=?[
????[1,?‘Tom‘],
????[2,?‘Fred‘],
];
//?list()?style
list($id1,?$name1)?=?$data[0];
//?[]?style
[$id1,?$name1]?=?$data[0];
//?list()?style
foreach?($data?as?list($id,?$name))?{
????//?logic?here?with?$id?and?$name
}
//?[]?style
foreach?($data?as?[$id,?$name])?{
????//?logic?here?with?$id?and?$name
}
|
|
4、类常量可见性 |
|
class?ConstDemo
{
????const?PUBLIC_CONST_A?=?1;
????public?const?PUBLIC_CONST_B?=?2;
????protected?const?PROTECTED_CONST?=?3;
????private?const?PRIVATE_CONST?=?4;
}
|
|
5、iterable 伪类 |
|
function?iterator(iterable?$iter)
{
????foreach?($iter?as?$val)?{
????????//
????}
}
|
|
6、多异常捕获处理 |
|
try?{
????//?some?code
}?catch?(FirstException?|?SecondException?$e)?{
????//?handle?first?and?second?exceptions
}
|
|
7、list()现在支持键名 |
这意味着它可以将任意类型的数组 都赋值给一些变量 |
$data?=?[
????["id"?=>?1,?"name"?=>?‘Tom‘],
????["id"?=>?2,?"name"?=>?‘Fred‘],
];
//?list()?style
list("id"?=>?$id1,?"name"?=>?$name1)?=?$data[0];
//?[]?style
["id"?=>?$id1,?"name"?=>?$name1]?=?$data[0];
//?list()?style
foreach?($data?as?list("id"?=>?$id,?"name"?=>?$name))?{
????//?logic?here?with?$id?and?$name
}
//?[]?style
foreach?($data?as?["id"?=>?$id,?"name"?=>?$name])?{
????//?logic?here?with?$id?and?$name
}
|
|
8、支持为负的字符串偏移量 |
一个负数的偏移量会被理解为一个从字符串结尾开始的偏移量。 |
var_dump("abcdef"[-2]);
var_dump(strpos("aabbcc", "b", -3));
|
7.2 |
1、新的object类型 |
这种新的类型 object, 引进了可用于逆变(contravariant)参数输入和协变(covariant)返回任何对象类型。 |
function?test(object?$obj)?:?object
{
????return?new?SplQueue();
}
test(new?StdClass());
|
|
2、通过名称加载扩展 |
使用 dl() 函数进行启用 |
|
|
3、允许重写抽象方法(Abstract method) |
|
abstract?class?A
{
????abstract?function?test(string?$s);
}
abstract?class?B?extends?A
{
????//?overridden?-?still?maintaining?contravariance?for?parameters?and?covariance?for?return
????abstract?function?test($s)?:?int;
}
|
|
4、扩展了参数类型 |
重写方法和接口实现的参数类型现在可以省略了。不过这仍然是符合LSP,因为现在这种参数类型是逆变的。 |
interface?A
{
????public?function?Test(array?$input);
}
class?B?implements?A
{
????public?function?Test($input){}?//?type?omitted?for?$input
}
|
|
5、允许分组命名空间的尾部逗号 |
|
use?Foo\Bar\{
????Foo,
????Bar,
????Baz,
};
|
|
6、更灵活的Heredoc 与 Nowdoc 语法 |
|
|
|
7、数组的解构支持引用赋值 |
|
?[&$a, [$b, &$c]] = $d
|
|
8、Instanceof 运算符支持字面量 |
判断结果总是?FALSE
|
|
|
9、允许函数和方法被调用时参数最后的空逗号收尾 |
|
|
|
10、多字节字符串的相关函数 |
|
mb_convert_case():
mb_strtolower())
mb_strtoupper())
mb_ereg(‘(?\w+)‘,?‘国‘,?$matches);
//?=>?[0?=>?"国",?1?=>?"国",?"word"?=>?"国"];
mb_ereg_replace(‘\s*(?\w+)\s*‘,?"_\k_\k‘word‘_",?‘?foo?‘);
//?=>?"_foo_foo_"
|
7.4 |
1、属性值类型声明 |
|
class?User?{
????public?int?$id;
????public?string?$name;
}
|
|
2、箭头函数 |
|
$factor?=?10;
$nums?=?array_map(fn($n)?=>?$n?*?$factor,?[1,?2,?3,?4]);
//?$nums?=?array(10,?20,?30,?40);
|
|
3、空值连写赋值运算符 |
|
$array[‘key‘]???=?computeDefault();
//?is?roughly?equivalent?to
if?(!isset($array[‘key‘]))?{
????$array[‘key‘]?=?computeDefault();
}
|
|
4、数组内展开 |
|
$parts?=?[‘apple‘,?‘pear‘];
$fruits?=?[‘banana‘,?‘orange‘,?...$parts,?‘watermelon‘];
//?[‘banana‘,?‘orange‘,?‘apple‘,?‘pear‘,?‘watermelon‘];
|
|
5、数值型字面量分隔符 |
|
6.674_083e-11;?//?float
299_792_458;???//?decimal
0xCAFE_F00D;???//?hexadecimal
0b0101_1111;???//?binary
|
|
6、弱引用 |
引用对象使其不被销毁 |
|
|
7、__toString()方法允许跑出异常 |
|
|