我们知道,php
作为弱类型语言,对变量的类型并没有显示的要求,所有的都是在底层自动进行处理。 但是,在应用层面其实也是提供了type-hinting
功能。这点对于php
代码的规范也是必须的。
但是,对于 type-hinting
,在 php5
中并全面,而是在php7
中才完善起来的。
type-hinting
首先,我们先简单介绍一下什么是type-hinting
。 了解c
语言的码友都知道,c
语言对类型的要求非常严格,我们看下面的函数定义
int add(int a,int b)
{
return a+b;
}
当我们要调用add
函数的时候所传的参数a
和b
必须是整型(int),而且返回值也必须是整型。如果有任意一个参数或者返回值的类型不一致,在编译的时候就会失败。 这就是 type-hinting
。
下面我们再看一段php
代码
function add($a,$b)
{
return $a + $b;
}
同样在我们调用add
函数的时候,所传参数就不必须是整型,而且返回值也是任意类型都可以。当然,我们期望的是$a
,$b
和返回值都是整型的,但是由于php
弱类型的特性,即使不是整型程序也会正常运行。所以经常会导致比较难调试的bug。这类代码在php
中是最常见的。
当然,对于php
来说,即使没有语法上的type-hinting
,我们也可以通过编码自己来实现。例如
function add($a,$b)
{
if(!is_int($a) || !is_int($b)) {
die("Type Error\n");
}
return $a + $b;
}
上面的写法虽然也能保证参数都是整型,然而缺不便于维护。因此type-hinting
在php
中也是有一定的必要性的。
下面我们正式介绍在php5
和php7
中type-hinting
有什么不同。
php5 中的 type-hinting
其实在php5
中已经提供了 type-hinting
的功能,只是还不是特别完善。 只是对于object
和array
的限定。
array
就比较容易理解了
function merge_array(array $a,array $b)
{
return merge($a,$b);
}
$a = array("one","two");
$b = array("three","foue");
print_r(merge_array($a,$b));
合并两个数组,要求参数必须都是数组,$a
和$b
是两个数组,这没什么问题。如果$a
$b
不是数组,那就会报错了
function merge_array(array $a,array $b)
{
return merge($a,$b);
}
$a = 1;
$b = 2;
print_r(merge_array($a,$b));
执行结果报错,部分错误信息
PHP Catchable fatal error: Argument 1 passed to merge_array() must be of the type array, integer given, ...
...
object
要求的就是所属当前类的实例对象。也就是说,参数中所接收的对象必须是当前类的一个实例。
function example(string $a)
{
var_dump($a);
}
上面的string
并不是字符串,而是一个string
类。如果我们直接传一个字符串就会报错
function example(string $a)
{
var_dump($a);
}
$str = "string";
example($str);
上面代码会报错
PHP Catchable fatal error: Argument 1 passed to example() must be an instance of string, string given, ...
...
正确的代码应该是这样的
class string
{
}
function example(string $a)
{
var_dump($a);
}
$obj = new string;
example($obj);
当然了,string
可以换成任意的类名。像 int
string
bool
等这些类型都不是原始的数据类型。如果写在函数参数前面那就都是表示的类。我们的类基本上是不会起这些名字的。 当然,除了类名也可以是接口名。
interface TextContract{}
class Test implements TestContract
{
}
function example(TestContract $a)
{
var_dump($a);
}
$obj = new Test;
example($obj);
我个人认为,php5
中的type-hinting
主要是为了接口而实现的。接口相当于一个标准,一个接口多个实现,只要符合该标准就可以通过。如果单独对于一个类进行限定,其实没什么太大的意义。
php7 中的 type-hinting
对于php7
,type-hinting
就很完善了,除了包含了php5
中的情况之外,对于string
,int
,boolean
等这些类型也进行了限定。在php7
中像string
、int
就不能作为类名了。
class string{}
这是会报错的
PHP Fatal error: Cannot use 'string' as class name as it is reserved ...
...
对函数的参数进行了string
或者int
等类型限定之后,那么调用函数时传的参数就必须是相对应的数据类型了。
function concact(string $a,string $b)
{
return $a.$b;
}
$a = "Hello ";
$b = "World";
print concact($a,$b);
function add(int $a,int $b)
{
return $a + $b;
}
$c = 11;
$d = 12;
print add($c,$d);
综上,就是 php5
和 php7
中参数type-hinting
的不同之处。
在 C
中除了对于参数的类型限定之外,还有对于返回值的类型进行的限定。而在上面的例子中我们只是比较了php5
和php7
的参数的不同,对于返回值有没有什么不同呢。其实是有的。
在php5
中对于返回值是没有进行限定的。 而在php7
中对与返回值也是有type-hinting
的。
function add(int $a,int $b) : int
{
return $a + $b;
}
$a = 1;
$b = 2;
print add($a,$b);
冒号 ':
' 后面的就是对返回值的类型进行的限定。这是在php5
中不存在的。
到此一个完整的type-hinting
在php5
和php7
中的不同之处结束了。