php是一种弱类型的编程语言,在php程序中,变量的数据类型可以随着其值的不同而自动发生改变,php也不会对变量的数据类型进行强制检查或约束.
我们可以参考下面一个简单的代码示例:
- <?php
- class Person {
- }
- $a = 1; //此时,$a为整数类型型(Integer)
- var_dump($a);
- $a = 1.0; //此时,$a为浮点类型(Float)
- var_dump($a);
- $a = 'CodePlayer'; //此时,$a为字符串类型(String)
- var_dump($a);
- $a = array('CodePlayer' => 'http://www.111cn.net'); //此时,$a为数组类型(Array)
- var_dump($a);
- $a = new Person(); //此时,$a为Person对象类型(Object)
- var_dump($a);
- $a = mysql_connect('localhost', 'username', 'password'); //此时,$a为资源类型(Resource)
- var_dump($a);
- ?>
php弱数据类型的特点使得php使用起来显得简单而灵活,不过,这同样也是一把达摩克利斯之剑,也正是由于php弱数据类型的特点,在编写php程序代码时,开发人员更需要时刻注意变量数据类型的变化,尤其是变量作为函数的参数进行传递时,更需要注意这一点,毕竟,大多数的函数参数都只期望是某种特定的数据类型,例如,在下面的例子中,函数sayHi()期望接收的参数类型是Person对象类型,但是,由于php并不是强类型的语言,也不会强制检查变量的类型,因此我们可以向函数中传递任意类型的参数,从而导致程序报错或逻辑出现异常,实例代码如下:
- <?php
- class Person {
- public $name = 'CodePlayer';
- public $age = 3;
- }
- function sayHi($person){
- echo "Hello! My name is $person->name. I'm $person->age years old.";
- }
- $p = '张三';
- sayHi($p); //不是期望的Person对象类型,将出现Notice级别错误信息,程序仍然继续运行
- echo 'Suffix'; //仍然会输出该文本信息
- ?>
从php 5开始,我们就可以使用新增的类型约束机制来对函数参数的部分数据类型进行类型约束。同样以上面的代码为例,我们可以在编写sayHi()函数时要求传递进来的参数必须是Person对象类型,否则引发致命错误(Fatal Error),并终止当前页面脚本的运行。要使用php的类型约束机制非常简单,我们只需要在函数声明的参数变量前添加指定的类型名称即可。当我们调用该函数时,php会强制检查函数的参数是否为指定的类型,如果不是指定的类型则引发致命错误,代码如下:
- <?php
- class Person {
- public $name = 'CodePlayer';
- public $age = 3;
- }
- function sayHi(Person $person){
- echo "Hello! My name is $person->name. I'm $person->age years old.";
- }
- $person = '张三';
- sayHi($person); //不是期望的Person对象类型,引发Fatal Error致命错误,程序终止运行
- echo 'Suffix'; //不会输出该文本信息,程序终止运行
- ?>
值得注意的是,在php 5中,目前只有对象、接口、数组、callable类型的参数变量才能使用类型约束(数组类型是从php 5.1版本开始支持的,callable类型是从php 5.4版本开始支持的)。
注意:如果使用类型约束的参数变量没有声明其默认值为null,调用该函数时就不能给对应的参数变量传递null值,否则同样也会报错。
类型约束不能用于标量类型如 int 或 string。Traits 也不允许。
Example #1 类型约束示例代码如下:
- <?php
- //如下面的类
- class MyClass
- {
- /**
- * 测试函数
- * 第一个参数必须为 OtherClass 类的一个对象
- */
- public function test(OtherClass $otherclass) {
- echo $otherclass->var;
- }
- /**
- * 另一个测试函数
- * 第一个参数必须为数组
- */
- public function test_array(array $input_array) {
- print_r($input_array);
- }
- }
- /**
- * 第一个参数必须为递归类型
- */
- public function test_interface(Traversable $iterator) {
- echo get_class($iterator);
- }
- /**
- * 第一个参数必须为回调类型
- */
- public function test_callable(callable $callback, $data) {
- call_user_func($callback, $data);
- }
- }
- // OtherClass 类定义
- class OtherClass {
- public $var = 'Hello World';
- }
- ?>
函数调用的参数与定义的参数类型不一致时,会抛出一个可捕获的致命错误,代码如下:
- <?php
- // 两个类的对象
- $myclass = new MyClass;
- $otherclass = new OtherClass;
- // 致命错误:第一个参数必须是 OtherClass 类的一个对象
- $myclass->test('hello');
- // 致命错误:第一个参数必须为 OtherClass 类的一个实例
- $foo = new stdClass;
- $myclass->test($foo);
- // 致命错误:第一个参数不能为 null
- $myclass->test(null);
- // 正确:输出 Hello World
- $myclass->test($otherclass);
- // 致命错误:第一个参数必须为数组
- $myclass->test_array('a string');
- // 正确:输出数组
- $myclass->test_array(array('a', 'b', 'c'));
- // 正确:输出 ArrayObject
- $myclass->test_interface(new ArrayObject(array()));
- // 正确:输出 int(1)
- $myclass->test_callable('var_dump', 1);
- ?>
类型约束不只是用在类的成员函数里,也能使用在函数里,代码如下:
- <?php
- // 如下面的类
- class MyClass {
- public $var = 'Hello World';
- }
- /**
- * 测试函数
- * 第一个参数必须是 MyClass 类的一个对象
- */
- function MyFunction (MyClass $foo) {
- echo $foo->var;
- }
- // 正确
- $myclass = new MyClass;
- MyFunction($myclass);
- ?>
类型约束允许 NULL 值:
- <?php
- /* 接受 NULL 值 */
- function test(stdClass $obj = NULL) {
- }
- test(NULL);
- test(new stdClass);
- ?>
波比源码 » php5类型约束学习笔记