简介:
在PHP7之前,我们在函数和类之间传递参数时不必声明变量类型,返回数据时也不必声明变量类型。任何数据类型都可以被传递、返回。这样会给PHP带来一个很大的问题:PHP不清楚传递的是什么类型的变量,函数、方法接收到的变量也不知道是什么类型。为了解决这个问题,PHP7中引入了类型声明,目前明确的有两类变量可以声明类型:形参和返回值。
类型声明在OOP与PHP程序中属于同一个特性,因为它既可以用在程序的函数中,也可以用在对象的方法中。
形参类型声明:
PHP7支持的形参类型声明的类型有:字符串型(string), 整型 (int), 浮点类型 (float), 以及布尔类型 (bool)。
class Person
{
public function age(int $age)
{
return $age;
}
public function name(string $name)
{
return $name;
}
public function isAlive(bool $alive)
{
return $alive;
}
}
$person = new Person();
echo $person->name('Revin');
echo $person->age(27);
echo $person->isAlive(TRUE);
上面的代码,创建一个 Person 类,里面有三个方法,每个方法接受不同类型的形参且有着类型声明。如果执行上面的代码,能够正确运行并通过类型检测。
Age 支持浮点数型,例如 27.5
如果传递一个浮点数作为age方法的形参,也是正常运行的。代码如下:
echo $person->age(30.5);
默认请看下,形参类型声明不是完全限制的,这就意味着我们可以传递一个浮点给期望得到整型数的方法, 也同样可以传递一个整形给期望得到整形术的方法。
//echo $person->name(11111111111);
echo $person->name('Revin');
echo $person->age(27.5);
echo $person->isAlive(TRUE);
这样也就失去了指定声明形参类型,不过可以做一些限制,代码如下:
开启严格模式. 注意必须放在程序首行,否则会报Fatal error: strict_types declaration must be the very first statement in the script in ...
declare(strict_types = 1);
此时我们若再传递一个浮点数给age方法的话,会得到一个 Fatal error: Uncaught TypeError,这个Fatal 错误 的意思是 Person::age
只能接受一个整型数而非浮点型数。
注意:爱需要字符串形参的情况下,如果传入的不是字符串形参的话,也会出现以上类似的Fatal 错误。例如以下报错代码:
echo $person->isAlive('true');
返回类型声明:
PHP 7 的另一个重要特性就是支持返回类型的声明,无论实在函数还是对象的方法中。
这有点类似形参类型声明,对刚才的 Person 类进行修改,代码如下:
declare(strict_types = 1);
class Person
{
public function age(float $age) : float
{
return $age;
}
public function name(string $name) : string
{
return $name;
}
public function isAlive(bool $alive) : string
{
return ($alive) ? 'Yes' : 'No';
}
}
$person = new Person();
echo $person->name('revin');
echo $person->age(27.5);
echo $person->isAlive(TRUE);
上面的代码 返回类型声明使用了 data-type 语法,对于形参类型声明与返回类型声明。
举个返回类型是对象的栗子:
修改上面的代码,加Address类, Person 类中加入 getAddress 方法,并且返回类型是Address对象。
declare(strict_types = 1);
class Address
{
public function getAddress()
{
return ['street' => 'shanghai', 'country' => 'China'];
}
}
class Person
{
public function age(float $age) : float
{
return $age;
}
public function name(string $name) : string
{
return $name;
}
public function isAlive(bool $alive) : string
{
return ($alive) ? 'Yes' : 'No';
}
public function getAddress() : Address
{
return new Address();
}
}
$person = new Person();
var_dump($person->getAddress());
上面的代码执行没有问题,调用Persion
类中的 getAddress 方法执行完毕后,返回一个Address类型的数据。
若上面Persion
类中的getAddress 方法修改如下
public function getAddress() : Address
{
return ['street' => 'shanghai', 'country' => 'China'];
}
再次实行会Fatal 错误,这是因为Persion
类中的 getAddress 方法返回了一个数组,而不是方法声明的Address类型的返回值。
Fatal error: Uncaught TypeError: Return value of Person::getAddress() must be an instance of Address, array returned in ..
为什么要使用类型声明?
它可以让函数、方法的形参与返回值有所预期,避免出现不必要的数据传递,从而造成错误。PHP 7 这个特性使代码更清晰且可读性更强,能够清楚的知道怎么样的数据类型将会被传递与返回。
补充知识: 三个点语法是什么?
当你看php7 官方的相关文档时m会看到...
的东西,如下示例:
<?php
// Coercive mode
function sumOfInts(int ...$ints)
{
return array_sum($ints);
}
var_dump(sumOfInts(2, '3', 4.1));
其实这是PHP5.6 新特性-PHP 可变参数,详情官方文档:http://php.net/manual/zh/functions.arguments.php#functions.variable-arg-list , 把传进来的值,转成数组.
资料:
PHP 7 标量类型声明 RFC