• PHP 7系列版本演化情况


    PHP很久不用了,很多新特性都搞不清了,稍微整理一下。

    1. 标量参数类型声明[7.0]
    2. 返回值类型声明[7.0]
    3. Nullable类型[7.1]
    4. 属性值类型声明[7.4]
    5. Void 函数[7.1]
    6. 箭头函数[7.4]
    7. 类常量可见性[7.1]
    8. iterable 伪类[7.1]
    9. 新的object类型[7.2]
    10. 允许重写抽象方法[7.2]
    11. 类在实现接口方法时参数类型扩展[7.2]
    12. null合并运算符[7.0]
    13. 空值连写赋值运算符[7.4]
    14. 组合比较符[7.0]
    15. 通过 define() 定义常量数组[7.0]
    16. 支持匿名类[7.0]
    17. Unicode codepoint 转译语法[7.0]
    18. Closure::call()[7.0]
    19. 断言[7.0]
    20. use 分组写法[7.0]
    21. 允许分组命名空间的尾部逗号[7.2]
    22. 生成器可以返回表达式[7.0]
    23. 生成器委托[7.0]
    24. 可以使用 list() 函数来展开实现了 ArrayAccess 接口的对象[7.0]
    25. list()现在支持键名[7.1]
    26. 对称性数组解构[7.1]
    27. 数组的解构支持引用赋值[7.3]
    28. 多异常捕获处理[7.1]
    29. 支持为负的字符串偏移量[7.1]
    30. 通过名称加载扩展 dl()[7.2]
    31. 更灵活的Heredoc 与 Nowdoc 语法[7.3]
    32. Instanceof 运算符支持字面量[7.3]
    33. 允许函数和方法被调用时参数最后的空逗号收尾[7.3]
    34. 多字节字符串的相关函数[7.3]
    35. 数组内展开[7.4]
    36. 数值型字面量分隔符[7.4]
    37. 弱引用[7.4]
    38. __toString() 方法允许抛出异常[7.4]
    PHP 7系列版本演化情况
    新特性:








    7.0
    1、标量参数类型声明
    标量类型声明 有两种模式: 强制 (默认) 和 严格模式。 

    现在可以使用下列类型参数(无论用强制模式还是严格模式): 
    字符串(string), 
    整数 (int), 
    浮点数 (float), 
    以及布尔值 (bool)。

    它们扩充了PHP5中引入的其他类型:类名,接口,数组和 回调类型。
    <?php
    // Coercive mode
    function sumOfInts(int ...$ints)
    {
        return array_sum($ints);
    }

    var_dump(sumOfInts(2'3'4.1));

    2、返回值类型声明
    返回类型声明指明了函数返回值的类型。可用的类型与参数声明中可用的类型相同。
    <?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]));

    3、null合并运算符
    如果变量存在且值不为NULL, 它就会返回自身的值,否则返回它的第二个操作数。
    <?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';
    ?>

    4、太空船操作符(组合比较符)
    用于比较两个表达式。当$a小于、等于或大于$b时它分别返回-1、0或1
    <?php
    // 整数
    echo <=> 1// 0
    echo <=> 2// -1
    echo <=> 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 定义。
    <?php
    define('ANIMALS', [
        'dog',
        'cat',
        'bird'
    ]);

    echo ANIMALS[1]; // 输出 "cat"

    6、匿名类

    <?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());

    7、Unicode codepoint 转译语法
    接受一个以16进制形式的 Unicode codepoint,并打印出一个双引号或heredoc包围的 UTF-8 编码格式的字符串
    echo "u{aa}";
    echo "u{0000aa}";
    echo "u{9999}";

    8、Closure::call()
    简短干练的暂时绑定一个方法到对象上闭包并调用它。
    <?php
    class {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

    // 将所有的对象都转换为 __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。
    <?php
    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 amespace{ClassAClassBClassC as C};
    use function some amespace{fn_afn_bfn_c};
    use const some amespace{ConstAConstBConstC};

    12、生成器可以返回表达式
    允许在生成器函数中通过使用 return 语法来返回一个表达式 (但是不允许返回引用值), 可以通过调用 Generator::getReturn() 方法来获取生成器的返回值, 但是这个方法只能在生成器完成产生工作以后调用一次。
    <?php

    $gen = (function() {
        yield 1;
        yield 2;

        return 3;
    })();

    foreach ($gen as $val) {
        echo $valPHP_EOL;
    }

    echo $gen->getReturn(), PHP_EOL;

    13、生成器委托
    只需在最外层生成器中使用 yield from, 就可以把一个生成器自动委派给其他的生成器, Traversable 对象或者 array。
    <?php

    function gen()
    {
        yield 1;
        yield 2;

        yield from gen2();
    }

    function gen2()
    {
        yield 3;
        yield 4;
    }

    foreach (gen() as $val)
    {
        echo $valPHP_EOL;
    }

    14、整数除法函数 intdiv()
    进行 整数的除法运算。
    <?php

    var_dump(intdiv(10, 3));

    15、可以使用 list() 函数来展开实现了 ArrayAccess 接口的对象


    7.1
    1、Nullable类型
    参数以及返回值的类型通过在类型前加上一个问号使之允许为空
    <?php

    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 不是一个合法的返回值。
    <?php
    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中)
    <?php
    $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、类常量可见性

    <?php
    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 伪类

    <?php
    function iterator(iterable $iter)
    {
        foreach ($iter as $val) {
            //
        }
    }

    6、多异常捕获处理

    <?php
    try {
        // some code
    } catch (FirstException SecondException $e) {
        // handle first and second exceptions
    }

    7、list()现在支持键名
    这意味着它可以将任意类型的数组 都赋值给一些变量
    <?php
    $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、支持为负的字符串偏移量
    一个负数的偏移量会被理解为一个从字符串结尾开始的偏移量。
    <?php
    var_dump("abcdef"[-2]);
    var_dump(strpos("aabbcc", "b", -3));
    7.2
    1、新的object类型
    这种新的类型 object, 引进了可用于逆变(contravariant)参数输入和协变(covariant)返回任何对象类型。
    <?php

    function test(object $obj) : object
    {
        return new SplQueue();
    }

    test(new StdClass());

    2、通过名称加载扩展
    使用 dl() 函数进行启用


    3、允许重写抽象方法(Abstract method)

    <?php

    abstract class A
    {
        abstract function test(string $s);
    }
    abstract class extends A
    {
        // overridden - still maintaining contravariance for parameters and covariance for return
        abstract function test($s) : int;
    }

    4、扩展了参数类型
    重写方法和接口实现的参数类型现在可以省略了。不过这仍然是符合LSP,因为现在这种参数类型是逆变的。
    <?php

    interface A
    {
        public function Test(array $input);
    }

    class implements A
    {
        public function Test($input){} // type omitted for $input
    }

    5、允许分组命名空间的尾部逗号

    <?php

    use FooBar{
        Foo,
        Bar,
        Baz,
    };

    6、更灵活的Heredoc 与 Nowdoc 语法



    7、数组的解构支持引用赋值

     [&$a, [$b, &$c]] = $d

    8、Instanceof 运算符支持字面量
    判断结果总是 FALSE


    9、允许函数和方法被调用时参数最后的空逗号收尾



    10、多字节字符串的相关函数

    mb_convert_case():
    mb_strtolower())
    mb_strtoupper())
    <?php
    mb_ereg('(?<word>w+)''国'$matches);
    // => [0 => "国", 1 => "国", "word" => "国"];

    <?php
    mb_ereg_replace('s*(?<word>w+)s*'"_k<word>_k'word'_"' foo ');
    // => "_foo_foo_"


    7.4
    1、属性值类型声明

    <?php
    class User {
        public int $id;
        public string $name;
    }

    2、箭头函数

    <?php
    $factor 10;
    $nums array_map(fn($n) => $n $factor, [1234]);
    // $nums = array(10, 20, 30, 40);

    3、空值连写赋值运算符

    <?php
    $array['key'] ??= computeDefault();
    // is roughly equivalent to
    if (!isset($array['key'])) {
        $array['key'] = computeDefault();
    }

    4、数组内展开

    <?php
    $parts = ['apple''pear'];
    $fruits = ['banana''orange', ...$parts'watermelon'];
    // ['banana', 'orange', 'apple', 'pear', 'watermelon'];

    5、数值型字面量分隔符

    <?php
    6.674_083e-11// float
    299_792_458;   // decimal
    0xCAFE_F00D;   // hexadecimal
    0b0101_1111;   // binary

    6、弱引用
    引用对象使其不被销毁


    7、__toString()方法允许跑出异常




  • 相关阅读:
    JZOI 4020 Revolution
    JZOJ 4018 Magic
    JZOJ 4017 逃跑
    JZOJ 4016 圈地为王
    JZOJ 4015 数列
    JZOJ 3960 鸡腿の出行
    BZOJ 5005 & JZOI 3959 鸡腿の乒乓
    GCJ2009B&JZOJ 4033 Min Perimeter
    jzoj 3948 Hanoi 塔
    [纯符][纯粹的无聊] 神奇的递推式
  • 原文地址:https://www.cnblogs.com/x3d/p/12975840.html
Copyright © 2020-2023  润新知