设为首页 - 加入收藏
您的当前位置:主页 > 网络编程 > PHP > 正文

在PHP内核探索:变量类型提示的方法

来源:网络收集 点击数: 时间:2016-08-09

PHP是弱类型语言,向方法传递参数时候也并不严格检查数据类型。 不过有时需要判断传递到方法中的参数,为此PHP中提供了一些函数,来判断数据的类型。 比如is_numeric(),判断是否是一个数值或者可转换为数值的字符串,比如用于判断对象的类型运算符:instanceof。 instanceof 用来测定一个给定的对象是否来自指定的对象类。instanceof 运算符是 PHP 5 引进的。 在此之前是使用的is_a(),不过现在已经不推荐使用。

为了避免对象类型不规范引起的问题,PHP5中引入了类型提示这个概念。在定义方法参数时,同时定义参数的对象类型。 如果在调用的时候,传入参数的类型与定义的参数类型不符,则会报错。这样就可以过滤对象的类型,或者说保证了数据的安全性。

PHP中的类型提示功能只能用于参数为对象的提示,而无法用于为整数,字串,浮点等类型提示。在PHP5.1之后,PHP支持对数组的类型提示。

要使用类型提示,只要在方法(或函数)的对象型参数前加一个已存在的类的名称,当使用类型提示时, 你不仅可以指定对象类型,还可以指定抽象类和接口。

一个数组的类型提示示例:

function array_print(Array $arr) {
    print_r($arr);
}
 
array_print(1);

以上的这段代码有一点问题,它触发了我们这次所介绍的类型提示,这段代码在PHP5.1之后的版本执行,会报错如下:

Catchable fatal error: Argument 1 passed to array_print() must be an array, 
integer given, called in  ...

当我们把函数参数中的整形变量变为数组时,程序会正常运行,调用print_r函数输出数组。 那么这个类型提示是如何实现的呢? 不管是在类中的方法,还是我们调用的函数,都是使用function关键字作为其声明的标记, 而类型提示的实现是与函数的声明相关的,在声明时就已经确定了参数的类型是哪些,但是需要在调用时才会显示出来。 这里,我们从两个方面说明类型提示的实现:

  1. 参数声明时的类型提示
  2. 函数或方法调用时的类型提示

将刚才的那个例子修改一下:

function array_print(Array $arr = 1) {
    print_r($arr);
}
 
array_print(array(1));

这段代码与前面的那个示例相比,函数的参数设置了一个默认值,但是这个默认值是一个整形变量, 它与参数给定的类型提示Array不一样,因此,当我们运行这段代码时会很快看到程序会报错如下:

Fatal error: Default value for parameters with array type hint 
can only be an array or NULL

为什么会很快看到报错呢? 因为默认值的检测过程发生在成中间代码生成阶段,与运行时的报错不同,它还没有生成中间代码,也没有执行中间代码的过程。 在Zend/zend_language_parser.y文件中,我们找到函数的参数列表在编译时都会调用zend_do_receive_arg函数。 而在这个函数的参数列表中,第5个参数( znode *class_type)与我们这节所要表述的类型提示密切相关。 这个参数的作用是声明类型提示中的类型,这里的类型有三种:

  1. 空,即没有类型提示
  2. 类名,用户定义或PHP自定义的类、接口等
  3. 数组,编译期间对应的token是T_ARRAY,即Array字符串

在zend_do_receive_arg函数中,针对class_type参数做了一系列的操作,基本上是针对上面列出的三种类型, 其中对于类名,程序并没有判断这个类是否存在,即使你使用了一个不存在的类名, 程序在报错时,显示的也会是实参所给的对象并不是给定类的实例。

以上是声明类型提示的过程以及在声明过程中对参数默认值的判断过程,下面我们看下在函数或方法调用时类型提示的实现。

上一篇:在PHP内核探索:操作码OpCode的方法
下一篇:没有了
栏目分类

A3站长网 站长网 站长网技术网 站长教程网 织梦CMS教程 织梦模板 帝国CMS模板 联系QQ:26991496 邮箱:26991496@qq.com

A3站长网:欢迎您!谢谢您的访问...

Top