学过静态语言开发的朋友都熟悉类型转换,比如Java、C#、C++等。静态语言的好处是变量必须指定类型,这也是一个编译的要求,所以大多数编译型语言都会有强制变量类型的要求。据说PHP在PHP8中也会加入JIT来实现编译功能,并且在7.4中会在声明变量的时候引入类型规范。下面我们来看一下目前PHP中参数类型和返回值类型的使用情况。functionadd(int$a,float$b):int{return(int)$a+$b;}上面代码中,方法参数中定义了参数的类型,包括int类型的$a和$a类型为float$b。然后在方法后面定义了方法的返回值必须是int类型。我们知道,如果计算表达式中出现float类型,那么计算结果就会变成float类型。该方法需要返回一个int类型。所以我们使用了一个cast(int)。定义好参数类型和返回值类型后,如果传递或返回的类型不一致,就会报错。参数类型和返回值类型最好在7以上的版本使用,7之后才支持int、float等基本类型的参数类型声明,具体可以参考文档:https://www.php.net/manual/zh/functions.arguments.php我们通过(int),(float),(bool)等可以实现PHP的类型强制转换,和C基本一样。可以转换的文档包括以下类型:(int),(integer)-转换为整型integer(bool),(boolean)-转换为布尔类型boolean(float),(double),(real)-转换为float(string)-转换为字符串string(array)-转换为数组array(object)-转换为对象object(unset)-转换为NULL(PHP5)(二进制)转换和b前缀转换作为PHP5.2被支持。1加上(int),(integer)如果是布尔值,转换结果为false变成0,true变成1。如果是float,则向下取整。比如7.99会被转换为7,如果是字符串,则从字符串的开头开始查找,开头的第一个数字直接成为转换结果,如果开头没有数字,则返回0其他类型转换在文档中没有定义,文档提示“没有定义从其他类型到整数的转换行为。不要依赖任何现有的行为,因为它可能会更改,恕不另行通知。",但是通过测试我们可以发现,其他类型的转换是通过多次类型转换来实现的,比如数组类型到int类型的转换,根据数组是否包含内容,再转换成bool类型转换为int类型//(int)(integer)var_dump((int)true);//1var_dump((int)false);//0var_dump((int)7.99);//7var_dump((int)"35好的");//35var_dump((int)"ok77");//0var_dump((int)"okyes");//0var_dump((int)[]);//0var_dump((int)[3,4,5]);//1(bool)(boolean)转换为boolean时,以下值被认为是FALSE:BooleanFALSE本身整数值0(零)浮点值0.0(零)空字符串,以及string"0"没有元素的数组特殊类型NULL(包括未赋值的变量)从空标签生成的SimpleXML对象所有其他值都被认为是TRUE(包括任何资源和NAN)这里注意负数也是TRUE,只有0是FASLE//(bool)(boolean)var_dump((bo0);//falsevar_dump((bool)1);//truevar_dump((bool)-1);//truevar_dump((bool)0.0);//falsevar_dump((bool)1.1);//truevar_dump((bool)-1.1);//truevar_dump((bool)"");//falsevar_dump((bool)"0");//falsevar_dump((bool)"a");//truevar_dump((bool)[]);//falsevar_dump((bool)['a']);//true$a;var_dump((bool)$a);//falsevar_dump((bool)NULL);//false(string)布尔值,false转换为空字符串"",true转换为"1"int或float类型,转换为字符串形式的字面量,例如1转换为“1”数组,object分别转换为“Array”和“Object”字面量资源类型,资源类型将转换为"Resourceid#1"NULL形式的文字被转换为空字符串""直接将数组、对象或资源转换为字符串将不会得到任何有用的信息,除了它的类型。可以使用函数print_r()和var_dump()列出这些类型的内容注意:测试结果,对象类型需要实现__tostring()魔术函数,否则报错无法转换为字符串类型//(字符串)var_dump((字符串)真);//"1"var_dump((string)false);//""var_dump((string)55);//"55"var_dump((string)12.22);//"12.22"var_dump((string)['a']);//“数组”类S{function__tostring(){return"S";}}var_dump((字符串)新S());//"S"var_dump((string)NULL);//""(array)foranyinteger,float,string,booleanandresourcetypes,如果将值转换为数组,您将得到一个只有一个元素的数组,索引为0,这是标量的值。换句话说,(array)$scalarValue与array($scalarValue)完全相同。如果一个对象被类型转换为数组,则结果是一个数组,其单元格是该对象的属性。键名将是成员变量名,但有一些例外:整数属性不可访问;私有变量以类名为前缀;受保护的变量以“*”为前缀。这些前缀前后都有一个NULL字符。将NULL转换为数组将导致空数组//(array)var_dump((array)1);var_dump((array)2.2);var_dump((array)"a");var_dump((array)true);classArr{公共$a=1;私人$b=2.2;protected$c="f";}classChildArrextendsArr{public$a=2;私人$d="g";private$e=1;}var_dump((array)newArr());var_dump((array)newChildArr());var_dump((array)null);(object)如果一个对象转换为一个对象,它不会有任何变化。如果将任何其他类型的值转换为对象,将创建内置类stdClass的实例。如果值为NULL,则新实例为空。将数组转换为对象会使键名成为具有对应值的属性名注意:PHP7.2.0之前的版本,数字键只能通过迭代访问//(object)var_dump((object)1);var_dump((object)1.1);var_dump((object)"string");var_dump((object)true);var_dump((object)NULL);var_dump((object)[1,2,3]);var_dump((对象)["a"=>1,"b"=>2,"c"=>3]);(unset)使用(unset)$var将变量转换为null不会删除变量或取消设置其值。只需返回NULL值//(unset)var_dump((unset)1);var_dump((unset)1.1);var_dump((unset)"string");var_dump((unset)true);var_dump((unset)null);var_dump((unset)[1,2,3]);var_dump((unset)new\stdClass());(binary)将所有类型转换为二进制字符串。二进制字符串是Unicode字符串,不同于传统上使用的普通PHP字符串。二进制字符串是字节串,没有字符集。具体区别类似于数据库中的binary和char类型和blob和text类型,日常开发中基本用不到,了解一下即可//(binary)var_dump((binary)1);var_dump((binary)1.1);var_dump((binary)"string");var_dump((binary)true);var_dump((binary)null);var_dump((binary)[1,2,3]);var_dump((binary)newS());以上就是我们强制转换的所有类型,其中有一些引用了资源类型(Resource),但是没有强制转换资源类型。因为资源类型多为handle操作,如数据库链接、文件读写等,强制其他类型为资源类型是没有意义的。这篇文章的内容在面试题中会经常出现,而在实际开发中逻辑判断中出现的很多BUG往往都是PHP的自动类型转换导致的,所以这篇文章一定会让你收藏拿出来。有意想不到的收获!!测试代码:https://github.com/zhangyue0503/dev-blog/blob/master/php/201910/source/php%E4%B8%AD%E7%9A%84%E5%BC%BA%E5%88%B6%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2.php参考文档:https://www.php.net/manual/zh/language.types.type-juggling.php#language.types.typecasting============各媒体平台均可搜索【硬核项目经理】
