PHP7 新特性

PHP / 87人浏览 / 0人评论

1. 运算符(NULL 合并运算符)


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


相当于:


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


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


$a ?: 1


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


 


2. 函数返回值类型声明


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
)



强制模式:


function foo($a) : int 

  return $a; 

foo(1.0); 


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


严格模式:


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 


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


 


3. 标量类型声明


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


官方示例:


// Coercive mode 


function sumOfInts(int ...$ints) 



  return array_sum($ints); 



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


以上例程会输出:


int(9)

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


 


4. use 批量声明


PHP 7 中 use 可以在一句话中声明多个类或函数或 const 了:


use some/namespace/{ClassA, ClassB, ClassC as C}; 


use function some/namespace/{fn_a, fn_b, fn_c}; 


use const some/namespace/{ConstA, ConstB, ConstC}; 


但还是要写出每个类或函数或 const 的名称(并没有像 python 一样的 from some import * 的方法)。


需要留意的问题是:如果你使用的是基于 composer 和 PSR-4 的框架,这种写法是否能成功的加载类文件?其实是可以的,composer 注册的自动加载方法是在类被调用的时候根据类的命名空间去查找位置,这种写法对其没有影响。


 


5. 太空舱操作符(组合比较操作符)


太空船操作符用于比较两个表达式。当$a小于、等于或大于$b时它分别返回-1、0或1。 比较的原则是沿用 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


 

6. 通过 define() 定义常量数组 


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


define('ANIMALS', [
    'dog',
    'cat',
    'bird'
]);
echo ANIMALS[1]; // outputs "cat"

 


7. 迭代器


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


$gen = (function() {
    yield 1;
    yield 2;
    return 3;
})();
foreach ($gen as $val) {
    echo $val, PHP_EOL;
}
echo $gen->getReturn(), PHP_EOL;

 

以上例程会输出:


1

2

3


8. 匿名类 


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


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) {

}


详细文档可以参考 匿名类.


 


9. 闭包 Closure::call()


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


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

0 条评论

还没有人发表评论

发表评论 取消回复