cncml手绘网

标题: 【PHP系列】PHP 7.0新增特性详解 [打印本页]

作者: admin    时间: 2018-6-21 22:38
标题: 【PHP系列】PHP 7.0新增特性详解
开始介绍PHP7.0新特性,具体的可以参照官网的介绍,我来挑一些给大家详细讲解下
http://php.net/manual/en/migration70.new-features.php" n; _, T) W# @, p0 |* B
1. ?? 运算符(NULL 合并运算符)
. q; E( p* |( d8 r$ E
  1. $a = $_GET['a'] ?? 1;
复制代码

: l9 X2 l5 V7 W* g
它相当于:
  1. $a = empty($_GET['a']) ? 1 : $_GET['a'];
复制代码
. K7 Q$ x) Q' v2 d8 ^  F# `0 W
我们知道三元运算符是可以这样用的:
  1. $a ?: 1
复制代码
: A" C1 {" N* C6 s
但是这是建立在 $a 已经定义了的前提上。新增的 ?? 运算符可以简化判断。简化代码的同时也更直观了!

) l5 I* s1 G8 O8 V. }
2. 函数返回值类型声明
官方文档提供的例子(注意 ... 的边长参数语法在 PHP 5.6 以上的版本中才有):
/ R, R0 i4 e* l! i
  1. <?php9 h6 g' u4 ?& a# f
  2. function arraysSum(array ...$arrays): array
    3 A& d- K* m7 u: |7 Y
  3. {
    ! }1 X* `2 {0 ]1 [8 O$ V) E7 r
  4.     return array_map(function(array $array): int {
    % _6 z* n: C; W; d7 B! Z3 V4 ~
  5.          return array_sum($array);" B: g/ ^3 w% U6 b/ K" x
  6.     }, $arrays);9 {9 ~5 J, ]% x% J! a8 H$ m; x
  7. }
    0 O8 ]5 m0 [- d. e

  8. 8 f. B0 v/ G$ A3 N" v" i
  9. print_r(arraysSum([1,2,3], [4,5,6], [7,8,9]));
复制代码

! l* v" p) ~: m
5 W; M  }- X* l2 L6 f
从这个例子中可以看出现在函数(包括匿名函数)都可以指定返回值的类型。
这个特性可以帮助我们避免一些 PHP 的隐式类型转换带来的问题。在定义一个函数之前就想好预期的结果可以避免一些不必要的错误。
不过这里也有一个特点需要注意。PHP 7 增加了一个 declare 指令:strict_types,既使用严格模式。
使用返回值类型声明时,如果没有声明为严格模式,如果返回值不是预期的类型,PHP 还是会对其进行强制类型转换。但是如果是严格模式, 则会出发一个 TypeError 的 Fatal error。
强制模式:
  1. <?phpfunction foo($a) : int
    ; h' \2 I3 S, m" ?0 k
  2. {
    2 f) n; ^# M% b% E
  3.     return $a;1 |  B  X$ p+ E- w$ |
  4. }
    ' @1 [' ~: i# q/ e  F9 H! Y0 C  E
  5. 3 L: O) v  W! L% ~: Q
  6. foo(1.0);
复制代码
5 q8 f* C8 @6 \( ]& t: F" y

9 M6 e4 r# O% u- L1 ~
以上代码可以正常执行,foo 函数返回 int 1,没有任何错误。
严格模式:
  1. <?php! C* H! x/ d; Y) v! W( X: {$ U
  2. declare(strict_types=1);
    # h7 @( J# ^6 R$ ], T, s2 r3 E+ W

  3. 8 |* I+ d+ |& l& e" Q
  4. function foo($a) : int5 {7 y* s- m$ ~1 d' b' O
  5. {
    : s# f5 b8 j. T0 ~- z/ q
  6.     return $a;+ h- i' ?- e, P6 w9 @6 k" b
  7. }2 r# X/ x( N. s' o, G

  8. & e# }' x* ]# j# W
  9. foo(1.0);
复制代码
8 \; Y+ o4 B4 C  e/ w2 t

/ j. I6 b4 y* D" ?7 S1 r. D
在声明之后,就会触发致命错误。
# PHP Fatal error:  Uncaught TypeError: Return value of foo() must be of the type integer, float returned in test.php:6; F1 [3 ~2 I( j% k7 V, O' A$ R( w
3. 标量类型声明
PHP 7 中的函数的形参类型声明可以是标量了。在 PHP 5 中只能是类名、接口、array 或者 callable (PHP 5.4,即可以是函数,包括匿名函数),现在也可以使用 string、int、float和 bool 了。
  1. <?php* k- Z/ M. y0 X( G  Q1 c& b
  2. // Coercive mode
    7 n* o1 j# G2 S1 A$ R. ~# ?9 h
  3. function sumOfInts(int ...$ints)* J* i# @# M/ {. M) P% m
  4. {
    " h- ~. C1 i) o1 S5 Y- p; @
  5.     return array_sum($ints);
    5 u, N: r, J0 M* N
  6. }' x1 k, A: F3 s- R9 _& E, z* E
  7. & b7 A6 @" n% m2 B
  8. var_dump(sumOfInts(2, '3', 4.1));
复制代码
0 ?, d% f/ g4 o( }5 {: d& M
) s8 o; [  E2 d) r! ^* x% v
需要注意的是上文提到的严格模式的问题在这里同样适用:强制模式(默认,既强制类型转换)下还是会对不符合预期的参数进行强制类型转换,严格模式下则触发 TypeError 的致命错误。
4. use 批量声明
PHP 7 中 use 可以在一句话中声明多个类或函数或 const 了:
  1. <?php% K1 A7 O0 @) b: z4 |
  2. use some\namespace\{ClassA, ClassB, ClassC as C};
    " s7 u4 y. G) _
  3. use function some\namespace\{fn_a, fn_b, fn_c};3 m* s0 w" O. B; q2 J3 {
  4. use const some\namespace\{ConstA, ConstB, ConstC};
复制代码

; \+ `- C! S" A* m9 g5 O9 t3 V9 t
但还是要写出每个类或函数或 const 的名称(并没有像 python 一样的 from some import * 的方法)。
需要留意的问题是:如果你使用的是基于 composer 和 PSR-4 的框架,这种写法是否能成功的加载类文件?其实是可以的,composer 注册的自动加载方法是在类被调用的时候根据类的命名空间去查找位置,这种写法对其没有影响。
再来简单说几个:
1、PHP 5.3 开始有了匿名函数,现在又有了匿名类了;
2、define 现在可以定义常量数组;
3、闭包( Closure)增加了一个 call 方法;
4、生成器(或者叫迭代器更合适)可以有一个最终返回值(return),也可以通过 yield from 的新语法进入一个另外一个生成器中(生成器委托)。
生成器的两个新特性(return 和 yield from)可以组合。具体的大家可以自行测试。
. t+ `5 H4 o+ G# l; \  [$ `0 f

2 A( ?9 f$ Z8 |




欢迎光临 cncml手绘网 (http://www.cncml.com/) Powered by Discuz! X3.2