zoukankan      html  css  js  c++  java
  • PHP7的新功能

    [转自:http://www.yiibai.com/php7/ ]
     
    【PHP7标量类型声明】
    在PHP7,一个新的功能,标量类型声明已被引入。标量类型声明有两种选择方式 -
    • 强制方式- 强制性是默认模式,不需要指定

    • 严格方式 - 严格模式有明确的暗示

    以下几种类型的函数参数可以通过上述模式被强制执行 -
    • int
    • float
    • bool
    • string
    • interfaces
    • array
    • callable
    示例 - 强制模式
    <?php
       // Coercive mode
       function sum(int ...$ints) {
          return array_sum($ints);
       }
       print(sum(2, '3', 4.1));
    ?>

    这将在浏览器产生输出以下结果:

    9
     
    示例 - 严格模式
    <?php
       // Strict mode
       declare(strict_types=1);
       function sum(int ...$ints) {
          return array_sum($ints);
       }
       print(sum(2, '3', 4.1));
    ?>
    这将在浏览器产生输出以下结果-
    Fatal error: Uncaught TypeError: Argument 2 passed to sum() must be of the type integer, string given, ... 

    【PHP7返回类型声明】

    在PHP7,一个新的功能,返回类型声明已被引入。返回类型声明指定的一个函数返回值的类型。以下类型可以用来作为返回类型声明。
    • int
    • float
    • bool
    • string
    • interfaces
    • array
    • callable
    示例 - 有效的返回类型
    <?php
       declare(strict_types = 1);
       function returnIntValue(int $value): int {
          return $value;
       }
       print(returnIntValue(5));
    ?>
    这将在浏览器产生输出以下结果:
    5
    示例 - 无效的返回类型
    <?php
       declare(strict_types = 1);
       function returnIntValue(int $value): int {
          return $value + 1.0;
       }
       print(returnIntValue(5));
    ?>
    这将在浏览器产生输出以下结果-
    Fatal error: Uncaught TypeError: Return value of returnIntValue() must be of the type integer, float returned...

    【PHP7 Null合并运算符】

    $a = $_GET['a'] ?? 1;

    它相当于:

    $a = isset($_GET['a']) ? $_GET['a'] : 1;

    我们知道三元运算符是可以这样用的:

    $a ?: 1

    但是这是建立在 $a 已经定义了的前提上。新增的 ?? 运算符可以简化判断。

    null合并运算符

    ?? 合并运算符,在第一操作数存在时可被直接返回,否则返回第二操作数。

    $title = $post['title'] ?? NULL;
    
    $title = $post['title'] ?? $get['title'] ?? 'No title';

    uniform变量语法

    $first = ['name' => 'second'];
    $second = 'two';
    echo $$first['name'];
    echo ${Sfirst['name']}; // PHP7
    
    ...
    echo $object->$methods['title'];
    echo $object->{$methods['title']}; // PHP7

    主要是因为PHP7与之前版本PHP的解析方式不一样,在PHP7中加上花括号就可以啦,就像上边代码这样,否则会报错。

    【PHP7  <=>操作符】 

    用于比较两个表达式。<=>操作符将==<>三个比较操作符打包在了一起,具体使用规则如下。

    操作符两边相等时返回 0
    操作符左边小于右边时返回 -1
    操作符左边大于右边时返回 1

    <?php
       //integer comparison
       print( 1 <=> 1);print("<br/>");
       print( 1 <=> 2);print("<br/>");
       print( 2 <=> 1);print("<br/>");
       print("<br/>");
       //float comparison
       print( 1.5 <=> 1.5);print("<br/>");
       print( 1.5 <=> 2.5);print("<br/>");
       print( 2.5 <=> 1.5);print("<br/>");
       print("<br/>");
       //string comparison
       print( "a" <=> "a");print("<br/>");
       print( "a" <=> "b");print("<br/>");
       print( "b" <=> "a");print("<br/>");
    ?>
    这将在浏览器产生输出以下结果:
    0
    -1
    1
    
    0
    -1
    1
    
    0
    -1
    1

    【PHP7常量数组】 

    数组常量现在可以使用 define() 函数定义。 在PHP5.6,它们只能使用 const 关键字定义。
    <?php
       //define a array using define function
       define('animals', [
          'dog',
          'cat',
          'bird'
       ]);
       print(animals[1]);
    ?>
    这将在浏览器产生输出以下结果:
    cat

    从PHP5.6开始常量数组可以用const关键字来声明,在PHP7中常量数组可以通过define函数来初始化。

    const STORES = ['en', 'fr', 'ar']; // php5.6
    define('STORES', ['en', 'fr', 'ar']); // php7

     【PHP7 use语句】

    从PHP7起,单次使用 use 语句可以用来从同一个命名空间导入类,函数和常量(而不用多次使用 use 语句)。
    <?php
    // Before PHP 7
    use comyiibaiClassA;
    use comyiibaiClassB;
    use comyiibaiClassC as C;
    
    use function comyiibaifn_a;
    use function comyiibaifn_b;
    use function comyiibaifn_c;
    
    use const comyiibaiConstA;
    use const comyiibaiConstB;
    use const comyiibaiConstC;
    
    // PHP 7+ code
    use comyiibai{ClassA, ClassB, ClassC as C};
    use function comyiibai{fn_a, fn_b, fn_c};
    use const comyiibai{ConstA, ConstB, ConstC};
    
    ?>

     【PHP7整数除法】

    PHP7引入了intdiv()的新函数,它执行操作数的整数除法并返回结果为 int 类型。
    <?php
    $value = intdiv(10,3);
    var_dump($value);
    print($value);
    ?>

    这将在浏览器产生以下输出:

    int(3) 
    3

    函数返回值类型声明 和 标量类型声明 的重点说明

    官方文档提供的例子(注意 … 的边长参数语法在 PHP 5.6 以上的版本中才有):

    <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])); 

    从这个例子中可以看出现在函数(包括匿名函数)都可以指定返回值的类型。

    这个特性可以帮助我们避免一些 PHP 的隐式类型转换带来的问题。在定义一个函数之前就想好预期的结果可以避免一些不必要的错误。

    不过这里也有一个特点需要注意。PHP 7 增加了一个 declare 指令:strict_types,既使用严格模式。

    使用返回值类型声明时,如果没有声明为严格模式,如果返回值不是预期的类型,PHP 还是会对其进行强制类型转换。但是如果是严格模式, 则会出发一个 TypeError 的 Fatal error。

    强制模式:

    <php 
    function foo($a) : int 
    { 
        return $a; 
    } 
     
    foo(1.0); 

    以上代码可以正常执行,foo 函数返回 int 1,没有任何错误。 

    严格模式:

    <php 
    declare(strict_types=1); 
     
    function foo($a) : int 
    { 
        return $a; 
    } 
     
    foo(1.0); 
    # PHP Fatal error:  Uncaught TypeError: Return value of foo() must be of the type integer, float returned in test.php:6 

    在声明之后,就会触发致命错误。

    ◆ 标量类型声明

    PHP 7 中的函数的形参类型声明可以是标量了。在 PHP 5 中只能是类名、接口、array 或者 callable (PHP 5.4,即可以是函数,包括匿名函数),现在也可以使用 string、int、float和 bool 了。

    官方示例:

    <php 
    // Coercive mode 
    function sumOfInts(int ...$ints) 
    { 
        return array_sum($ints); 
    } 
     
    var_dump(sumOfInts(2, '3', 4.1)); 

    需要注意的是上文提到的严格模式的问题在这里同样适用:强制模式(默认,既强制类型转换)下还是会对不符合预期的参数进行强制类型转换,严格模式下则触发 TypeError 的致命错误。

    类型声明

    看代码,一目了然了。

    class person
    {
        public function age(int $age) : string
        {
            return 'Age is ' . $age;
        }
    }

    匿名类

    匿名类的声明与使用时同时进行的,具备其他类所具备的所以功能,区别在于匿名类没有类名。语法如下:

    new class(argument) { definition };

    匿名类是没有类名的,但在PHP内部,会在内存的引用地址表中为其分配一个全局唯一的名称。

    $name = new class('You') {
        public function __construct($name)
        {
            echo $name;
        }
    };

    匿名类可以继承父类及父类的方法。

    class Packt
    {
        protected $number;
    
        public function __construct()
        {
            echo 'parent construct';
        }
    
        public function getNumber() : float
        {
            return $this->number;
        }
    }
    
    $number = new class(5) extends Packt
    {
        public function __construct(float $number)
        {
            parent::__construct();
            $this->number = $number;
        }
    };
    
    echo $number->getNumber();

    匿名类可以继承接口。

    interface Publishers
    {
        public function __construct(string name, string address);
        public function getName();
        public function getAddress();
    }
    
    class packt
    {
        protected $number;
        protected $name;
        protected $address;
        public function ...
    }
    
    $info = new class('name', 'address') extends Packt implement Publishers
    {
        public function __construct(string $name, string $address)
        {
            $this->name = $name;
            $this->address = $address;
        }
    
        public function getName() : string
        {
            return $this->name;
        }
    
        public function getAddress() : string
        {
            return $this->address;
        }
    }
    
    echo $info->getName() . ' ' . $info->getAddress();

    匿名类可以嵌套在一个类中使用。

    class Math
    {
        public $first_number = 10;
        public $second_number = 10;
        public function add() : float
        {
            return $this->first_number + $this->second_number;
        }
    
        public function mutiply_sum()
        {
            return new class() extends Math
            {
                public function mutiply(float $third_number) : float
                {
                    return $this->add() * $third_number;
                }
            };
        }
    }
    
    $math = new Math();
    echo $math->mutiply_sum()->mutiply(2);
  • 相关阅读:
    【ASP.NET Core 3.1】【鉴权,授权】OAuth2.0四种授权模式--客户端模式
    DIY申请达姆施塔特工业大学计算机专业(Informatik)硕士(Master)【附个人简历和动机信】
    解决Parsing error: Invalid ecmaVersion问题
    Rust: Couldn't resolve host name (Could not resolve host: crates
    mapreduce中使用python
    使用service管理hdfs,yarn
    gunicorn+flask+centos启动flask脚本
    python编写shell
    记录一次linux部署flask
    安装Ubuntu 20.04 后的一些优化和美化步骤
  • 原文地址:https://www.cnblogs.com/rxbook/p/7493860.html
Copyright © 2011-2022 走看看