-
强制方式- 强制性是默认模式,不需要指定
-
严格方式 - 严格模式有明确的暗示
- int
- float
- bool
- string
- interfaces
- array
- callable
<?php // Coercive mode function sum(int ...$ints) { return array_sum($ints); } print(sum(2, '3', 4.1)); ?>
这将在浏览器产生输出以下结果:
<?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返回类型声明】
- 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常量数组】
<?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语句】
<?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整数除法】
<?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);