zoukankan      html  css  js  c++  java
  • php7的一些新特性总结

    PHP 的学习新特性

    最近做的项目使用了 php7,但感觉有很多新特性没有用起来。就想总结一下,一些可能会用到的新特性。之前使用的环境是 php5.4,所有也会有 php5.5 和 php5.6 的特性总结进来,这里只列出我觉得在项目中可能用到的特性,主要内容来自 php手册的附录。

    Generators (PHP 5 >= 5.5.0, PHP 7)

    通过添加 yield 关键字支持了 generators,Generators 提供了一个更简单的方法实现迭代器,不需要实现 Iterator 接口。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <?php
    function xrange($start, $limit, $step = 1) {
     for ($i = $start; $i <= $limit; $i += $step) {
      yield $i;
     }
    }
     
    echo 'Single digit odd numbers: ';
     
    /* 注意保存在内存中的数组绝不会被创建或返回 */
    foreach (xrange(1, 9, 2) as $number) {
     echo "$number ";
    }

    以上例程会输出:

    Single digit odd numbers: 1 3 5 7 9

    详情点击生成器

    新增 finally 关键字 (PHP 5 >= 5.5.0, PHP 7)

    try-catch 现在支持 finally

    foreach 现在支持 list() (PHP 5 >= 5.5.0, PHP 7)

    foreach 控制结构现在支持通过 list() 构造将嵌套数组分离到单独的变量。例如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <?php
    $array = [
     [1, 2],
     [3, 4],
    ];
     
    foreach ($array as list($a, $b)) {
     echo "A: $a; B: $b ";
    }
    ?>

    以上例程会输出:

    A: 1; B: 2
    A: 3; B: 4

    array_column (PHP 5 >= 5.5.0, PHP 7)

    array_column — 返回数组中指定的一列

    使用表达式定义常量 (PHP 5 >= 5.6.0, PHP 7)

    在之前的 PHP 版本中, 必须使用静态值来定义常量,声明属性以及指定函数参数默认值。 现在你可以使用包括数值、字符串字面量以及其他常量在内的数值表达式来 定义常量、声明属性以及设置函数参数默认值。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    <?php
    const ONE = 1;
    const TWO = ONE * 2;
     
    class C {
     const THREE = TWO + 1;
     const ONE_THIRD = ONE / self::THREE;
     const SENTENCE = 'The value of THREE is '.self::THREE;
     
     public function f($a = ONE + self::THREE) {
      return $a;
     }
    }
     
    echo (new C)->f()." ";
    echo C::SENTENCE;
    ?>

    以上例程会输出:

    4

    The value of THREE is 3

    现在可以通过 const 关键字来定义类型为 array 的常量。

    1
    2
    3
    4
    5
    <?php
    const ARR = ['a', 'b'];
     
    echo ARR[0];
    ?>

    以上例程会输出:

    a

    使用 ... 运算符定义变长参数函数 (PHP 5 >= 5.6.0, PHP 7)

    现在可以不依赖 func_get_args(), 使用 ... 运算符 来实现 变长参数函数。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <?php
    function f($req, $opt = null, ...$params) {
     // $params 是一个包含了剩余参数的数组
     printf('$req: %d; $opt: %d; number of params: %d'." ",
       $req, $opt, count($params));
    }
     
    f(1);
    f(1, 2);
    f(1, 2, 3);
    f(1, 2, 3, 4);
    f(1, 2, 3, 4, 5);
    ?>

    以上例程会输出:

    $req: 1; $opt: 0; number of params: 0
    $req: 1; $opt: 2; number of params: 0
    $req: 1; $opt: 2; number of params: 1
    $req: 1; $opt: 2; number of params: 2
    $req: 1; $opt: 2; number of params: 3

    使用 ... 运算符进行参数展开 (PHP 5 >= 5.6.0, PHP 7)

    在调用函数的时候,使用 ... 运算符, 将 数组 和 可遍历 对象展开为函数参数。 在其他编程语言,比如 Ruby中,这被称为连接运算符,。

    1
    2
    3
    4
    5
    6
    7
    8
    <?php
    function add($a, $b, $c) {
     return $a + $b + $c;
    }
     
    $operators = [2, 3];
    echo add(1, ...$operators);
    ?>

    以上例程会输出:

    6

    use function 以及 use const (PHP 5 >= 5.6.0, PHP 7)

    use 运算符 被进行了扩展以支持在类中导入外部的函数和常量。 对应的结构为 use function 和 use const。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <?php
    namespace NameSpace {
     const FOO = 42;
     function f() { echo __FUNCTION__." "; }
    }
     
    namespace {
     use const NameSpaceFOO;
     use function NameSpacef;
     
     echo FOO." ";
     f();
    }
    ?>

    以上例程会输出:

    42

    NameSpacef

    __debugInfo() (PHP 5 >= 5.6.0, PHP 7)

    加入 __debugInfo(), 当使用 var_dump() 输出对象的时候, 可以用来控制要输出的属性和值。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    <?php
    class C {
     private $prop;
     
     public function __construct($val) {
      $this->prop = $val;
     }
     
     public function __debugInfo() {
      return [
       'propSquared' => $this->prop ** 2,
      ];
     }
    }
     
    var_dump(new C(42));
    ?>

    以上例程会输出:

    1
    2
    3
    4
    object(C)#1 (1) {
     ["propSquared"]=>
     int(1764)
    }

    标量类型声明 (PHP 7)

    标量类型声明 有两种模式: 强制 (默认) 和 严格模式。 现在可以使用下列类型参数(无论用强制模式还是严格模式): 字符串(string), 整数 (int), 浮点数 (float), 以及布尔值 (bool)。它们扩充了PHP5中引入的其他类型:类名,接口,数组和 回调类型。

    1
    2
    3
    4
    5
    6
    7
    8
    <?php
    // Coercive mode
    function sumOfInts(int ...$ints)
    {
     return array_sum($ints);
    }
     
    var_dump(sumOfInts(2, '3', 4.1));

    以上例程会输出:

    int(9)

    要使用严格模式,一个 declare 声明指令必须放在文件的顶部。这意味着严格声明标量是基于文件可配的。 这个指令不仅影响参数的类型声明,也影响到函数的返回值声明(参见返回值类型声明, 内置的PHP函数以及扩展中加载的PHP函数)

    返回值类型声明 (PHP 7)

    PHP 7 增加了对返回类型声明的支持。 类似于参数类型声明,返回类型声明指明了函数返回值的类型。可用的类型与参数声明中可用的类型相同。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <?php
     
    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]));

    以上例程会输出:

    Array
    (
        [0] => 6
        [1] => 15
        [2] => 24
    )

    null合并运算符 (PHP 7)

    由于日常使用中存在大量同时使用三元表达式和 isset()的情况, 我们添加了null合并运算符 (??) 这个语法糖。如果变量存在且值不为NULL, 它就会返回自身的值,否则返回它的第二个操作数。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <?php
    // 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';
    ?>

    太空船操作符(组合比较符)(PHP 7)

    太空船操作符用于比较两个表达式。当$a小于、等于或大于$b时它分别返回-1、0或1。 比较的原则是沿用 PHP 的常规比较规则进行的。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    <?php
    // Integers
    echo 1 <=> 1; // 0
    echo 1 <=> 2; // -1
    echo 2 <=> 1; // 1
     
    // Floats
    echo 1.5 <=> 1.5; // 0
    echo 1.5 <=> 2.5; // -1
    echo 2.5 <=> 1.5; // 1
      
    // Strings
    echo "a" <=> "a"; // 0
    echo "a" <=> "b"; // -1
    echo "b" <=> "a"; // 1
    ?>

    通过 define() 定义常量数组 (PHP 7)

    Array 类型的常量现在可以通过 define() 来定义。在 PHP5.6 中仅能通过 const 定义。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <?php
    define('ANIMALS', [
     'dog',
     'cat',
     'bird'
    ]);
     
    echo ANIMALS[1]; // outputs "cat"
    ?>

    匿名类 (PHP 7)

    现在支持通过new class 来实例化一个匿名类,这可以用来替代一些“用后即焚”的完整类定义。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    <?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) {
      echo $msg;
     }
    });
     
    var_dump($app->getLogger());
    ?>

    以上例程会输出:

    object(class@anonymous)#2 (0) {
    }

    Closure::call() (PHP 7)

    Closure::call() 现在有着更好的性能,简短干练的暂时绑定一个方法到对象上闭包并调用它。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <?php
    class A {private $x = 1;}
     
    // Pre PHP 7 code
    $getXCB = function() {return $this->x;};
    $getX = $getXCB->bindTo(new A, 'A'); // intermediate closure
    echo $getX();
     
    // PHP 7+ code
    $getX = function() {return $this->x;};
    echo $getX->call(new A);

    以上例程会输出:

    1
    1

    为unserialize()提供过滤 (PHP 7)

    这个特性旨在提供更安全的方式解包不可靠的数据。它通过白名单的方式来防止潜在的代码注入。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <?php
    // converts all objects into __PHP_Incomplete_Class object
    $data = unserialize($foo, ["allowed_classes" => false]);
     
    // converts all objects into __PHP_Incomplete_Class object except those of MyClass and MyClass2
    $data = unserialize($foo, ["allowed_classes" => ["MyClass", "MyClass2"]);
     
    // default behaviour (same as omitting the second argument) that accepts all classes
    $data = unserialize($foo, ["allowed_classes" => true]);

    Group use declarations (PHP 7)

    从同一 namespace 导入的类、函数和常量现在可以通过单个 use 语句 一次性导入了。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    <?php
     
    // Pre PHP 7 code
    use somenamespaceClassA;
    use somenamespaceClassB;
    use somenamespaceClassC as C;
     
    use function somenamespacefn_a;
    use function somenamespacefn_b;
    use function somenamespacefn_c;
     
    use const somenamespaceConstA;
    use const somenamespaceConstB;
    use const somenamespaceConstC;
     
    // PHP 7+ code
    use somenamespace{ClassA, ClassB, ClassC as C};
    use function somenamespace{fn_a, fn_b, fn_c};
    use const somenamespace{ConstA, ConstB, ConstC};
    ?>

    先总结这些,内容都是来自php的文档,之后有用到这里略过的新特性也会补充过来~~

  • 相关阅读:
    POJ3094 UVALive3594 HDU2734 ZOJ2812 Quicksum【进制】
    UVALive5583 UVA562 Dividing coins
    POJ1979 HDU1312 Red and Black【DFS】
    POJ1979 HDU1312 Red and Black【DFS】
    POJ2386 Lake Counting【DFS】
    POJ2386 Lake Counting【DFS】
    HDU4394 Digital Square
    HDU4394 Digital Square
    UVA213 UVALive5152 Message Decoding
    UVA213 UVALive5152 Message Decoding
  • 原文地址:https://www.cnblogs.com/zyiii/p/8822032.html
Copyright © 2011-2022 走看看