正如上一篇中所说,参数变量可以包含任何基本数据类型z,参数默认情况下也是可以包含任何类型的对象。这其中PHP根据语境自动转换数据类型起了一部分作用。这种灵活性有它的好处,但是在方法定义中可能会出现一些问题。如下所示:
//定义一个书的类
class Book{
public $title;
public $author;
//构造函数
function __construct($title,$author){
$this->title = $title;
$this->author = $author;
}
}
//定义一个另外的一个类,类里面定义一个方法用以输出书的详细信息
class writeInfo(){
public $obj;
//接受Book类的对象作为参数
function __construct($book){
$this->obj = $book;
}
public function write(){
$str = "书名:{$this->obj->title},作者:{$this->obj->author}";
return $str;
}
}
//使用这两个类
$book = new Book("PHP从入门到精通","LSGO实验室.著");
//将Book类的对象作为参数传入writeInfo类
$write = new writeInfo($book);
$info = $write->write();
print($info);
//返回结果:
//书名:PHP从入门到精通,作者:LSGO实验室.著
writeInfo类只包含了write()方法,该方法接受Book类的对象,并用该对象的属性打印出了书的信息。我们把参数命名为 book,说明write()方法希望接受到一个Book对象,但是在实际的处理 book之前不会知道具体是什么。而那时代码可能已经根据我们自己的预期(接受到了真正的Book对象,但是其他不清楚该函数的程序员并不知道啊!)执行了相应的操作。就比如:
//定义一个书的类
class Book{
public $title;
public $author;
//构造函数
function __construct($title,$author){
$this->title = $title;
$this->author = $author;
}
}
//定义一个另外的一个类,类里面定义一个方法用以输出书的详细信息
class writeInfo(){
public $obj;
//接受Book类的对象作为参数
function __construct($book){
$this->obj = $book;
}
public function write(){
$str = "书名:{$this->obj->title},作者:{$this->obj->author}";
return $str;
}
}
//这里我们新建一个作为干扰的类
class wrong(){
//....
}
$book = new Book("PHP从入门到精通","LSGO实验室.著");
$wrong = new wrong();
//将wrong类的对象而不是book类的对象作为参数传入writeInfo类
$write = new writeInfo($wrong);
$info = $write->write();
print($info);
//这里肯定出错啦!$wrong对应的类里面根本没有定义title、author等属性,访问不到。
为了解决这个问题(没有强制要求参数类型),PHP5引入例如类型提示:要增加一个方法参数的类型提示,只需简单地将所传对象对应的类名放在需要约束的方法参数之前。
运用对象提示,我们修改writeInfo类:
class writeInfo(){
public $obj;
//在$book前面加上对应的类名,表示只能接受Book类的对象作为参数
function __construct(Book $book){
$this->obj = $book;
}
public function write(){
$str = "书名:{$this->obj->title},作者:{$this->obj->author}";
return $str;
}
}
现在,writeInfo类只能接收包含Book类的对象的$book参数。让我们用一个错误的对象来实例化writeInfo类:
//定义一个书的类
class Book{
public $title;
public $author;
//构造函数
function __construct($title,$author){
$this->title = $title;
$this->author = $author;
}
}
//定义一个另外的一个类,类里面定义一个方法用以输出书的详细信息
class writeInfo(){
public $obj;
//接受Book类的对象作为参数
function __construct(Book $book){
$this->obj = $book;
}
public function write(){
$str = "书名:{$this->obj->title},作者:{$this->obj->author}";
return $str;
}
}
//这里我们新建一个作为干扰的类
class wrong(){
//....
}
$book = new Book("PHP从入门到精通","LSGO实验室.著");
$wrong = new wrong();
//将wrong类的对象而不是book类的对象作为参数传入writeInfo类
$write = new writeInfo($wrong);
$info = $write->write();
print($info);
因为writeInfo类的构造函数包含类型提示,给它传递一个wrong对象竟会产生严重的错误:
Catchable fatal error: Argument 1 passed to writeInfo::__construct() must be an instance of Book, instance of wrong given…..
错误提示的大概意思是:writeInfo类的构造函数要求的参数必须是Book类的一个实例(对象),现在所给的是wrong类的一个实例。
有了参数的类型提示,我们不在需要在使用参数前对其进行类型检查,不用担心一些由对象类型错误引起事务bug,因为类型提示是严格执行的。
既然错误提示这么好用,那么类似于”false”和false这种错误是不是也是使用的呢?
很遗憾,类型提示不能用于强制规定参数为某种基本数据类型(int string bool 等),如果要处理基本数据类型,还的在方法体中使用is_int()、in_string()、is_bool()等类型检查函数!但是数组是例外的!我们可以强制规定使用数组作为参数,这被称为数组提示:
function setArray(array $array){
$this->arr = $array;
}
假如给函数setArray()传递的参数不是数组,则会提示:
Catchable fatal error: Argument 1 passed to test() must be an array, string given
“我要的参数是一个数组,你**给我的竟然是字符串!(搞什么飞机啊)”
注意了,数组提示是在PHP5.1中假如的,更低版本的就没法享受数组提示带来的好处了。
在5.1之后的版本中,还新增了对null默认值的参数提示,既可以指定参数为一个特定类型或null值:
class writeInfo{
public $obj;
//类型提示
function __construct(Book $book=null){
$this->obj = $book;
}
function write(){
if($this->obj){
$str = "书名:{$this->obj->title},作者:{$this->obj->author}";
print $str;
}else{
print "你好像什么也没给我传吧?";
}
}
}
这里表示,你要么给setWriter()函数传一个ObjectWriter类的对象,要么就别传参数,不然就要报错了!