转载请注明出处:https://tlanyan.me/argument-t...PHP7开始支持标量类型声明,强类型语言的味道比较浓。在使用这个特性的过程中,我踩了两个坑:一个是声明了一个boolean类型的参数,最近一次是声明了一个double类型的参数,都导致了运行时错误。为了避免以后再犯类似的错误,这几天看了官方文档。这篇文章是看完之后对PHP函数的类型声明和使用的总结。在语法上,PHP的函数定义经历了几个时期:在古代(PHP4),定义一个函数非常简单,使用函数名(args){body}的语法声明。参数和返回值类型无法指定,参数和返回值类型有无限可能。这是迄今为止最常见的函数声明方式。数组和引用类型的参数值声明(PHP5)数组(array)、类(class)、接口(interface)、函数(callable)都可以用在函数声明中。从5.6开始,支持常量(包括类常量)作为默认参数,以及参数数组(前缀为省略号...)。例如:functionsum(...$numbers){$sum=0;foreach($numbersas$number){$sum+=$number;}return$sum;}注意:如果参数的值可能为null,则null必须是参数的默认值,否则调用时会出错。例如:functionfoo(array$arr=null){...}标量类型和返回值声明(PHP7)函数正式支持标量类型(int、bool、float、string)和返回值类型(可声明类型是与参数)语句相同。从这个版本开始,函数声明可以在形式上表现得像强类型语言,除了语法差异。不幸的是,如果函数的返回值可能为空,则无法指定返回值类型。例如:functiongetModel():Foo{if($this->_model===null){$this->_model=xxxx;//从数据库或其他获取}return$this->_model;//if$this->_model还是null,runningerror}参数和返回值可以为null和void返回类型声明(PHP7.1)当参数和返回值的类型可能为null时,类型被修饰问号(?)解决空值问题(不与默认参数冲突);类型声明增加了iterable,也支持void类型的返回值。例如:functiongetModel(?int$id):?Foo{if($id!==null){$this->_model=xxxx;}else{$this->_model=yyyy;}return$this->_model;}//调用$foo->getModel(null);$foo->getModel(100);//函数声明参数,不提供默认参数。调用时如果不传入参数,会报错//将函数声明改成IntogetModel(?int$id=100){},可以不传参数$foo->getModel();当函数返回值为void时,函数体不能返回任何东西(returnvoid;也是错误的!),或者可以省略return语句。functiontest(array$arr):void{if(!count($arr){return;}//不返回;array_walk($arr,function($elem){xxxx});}查看上面的历史变化,可以看到从PHP7.1开始,函数类型声明已经完善(虽然在实践中用的不多)。注意,文章提到了参数和返回值类型声明。PHP不保证参数类型在运行过程中不会改变,即下面的代码是合法的:functionfoo(array$arr):array{//change$arrfromarraytoint$arr=3;return[];}从这个角度来看,PHP仍然是一种弱类型语言,不能进行静态编译。下面说说实践中踩过的坑。根据官方文档,函数参数和返回值类型声明可用的类型有:class/interfaceself,只能在自己的方法中使用在列表中键入!除非你定义这两种类型,否则在参数和返回值中使用它们是错误的!这也是PHP有点蛋疼的地方。double和float关键字在正常使用中几乎是一样的。例如doubleval是floatval的别名,is_double是is_float的别名。转换时,使用(double)和(float)具有相同的效果。但是用在类型声明中就不一样了。bool和boolean也会出现同样的情况。总结目前PHP7.2稳定版已经发布。建议新项目尽量使用PHP7.1及之后的版本。为了编写清晰且可维护的代码,建议使用声明类型。引用类型或字符串建议使用空值,int/float等标量类型的参数尽量不要使用空值。func_get_argc等函数,如非必要,尽量不用。参考http://php.net/manual/en/func...http://php.net/manual/en/migr...http://php.net/manual/en/migr...
