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);
原文地址:https://www.cnblogs.com/rxbook/p/7493860.html