PHP中的类型转换规则

来源:互联网 发布:阿里云主机 价格 编辑:程序博客网 时间:2024/04/28 19:57

字符串会被转化为0,请看以下说明:

If you compare an integer with a string, the string is converted to a number. If you compare two numerical strings, they are compared as integers. These rules also apply to the switch statement.

如果任何一个运算数是浮点数,则所有的运算数都被当成浮点数,结果也是浮点数。否则运算数会被解释为整数,结果也是整数。

Recently, an obscure detail in the way PHP processes strings came to my attention in the form of an endless loop occasionally found in phpDocumentor's parsing of a file. The loop came about when a docblock of this form was used:

/**
* 01 some code
* etc.
*/

This is processed by code that checks for simple lists (like 1. blah 2. blah, or - blah - blah, etc.). However, an innocent call to in_array($x, array('1.', '0.')) had surprising and unexpected results: our friendly PHP determined that '01' was in the array('1.', '0.')!! This is of course patently false, and made little to no sense until I realized that unlike my previous understanding (when comparing an integer to a string, the string is converted to an integer), PHP actually converts all numeric-like strings into integers when comparing them, so that this code emits bool(true):

< php
var_dump('01' == '1.');
>

This, of course, seems completely counter-intuitive to me, as I would instead use this code if I wished to check a string for numericness:

< php
var_dump('01' == 1);
>

and continue on my way. What this actually means is that PHP is imposing a new set of rules upon those of us who wish to simply compare our strings in peace. Note that in ANY situation that you have input from uncontrolled sources, and wish to check for comparison to a numeric string, you MUST do one of the following:

  1. use === instead of ==. This will enforce type checking, so that strings are compared as strings
  2. use the 3rd parameter of in_array(), and set it to true
  3. use strcmp() or one of its cousins
If you follow these three rules every time that you compare two strings that should not be compared as numbers, you will be OK.

Note that if you ignore these rules, it could lead to serious security implications, as ==/in_array() will unexpectedly return true in cases where it should not.

Also note that switch/case suffer from the same deficiency, and if there is any chance you will need something like "case '1' :" then you should be using a different system like "if ($a === '1') then blah elseif()..."

In my humble opinion, this auto-conversion is dangerous, but as with many useful features that are so flexible, there is a large precedent for people thinking it is useful enough to outway the danger. I personally think PHP could retain all the benefits of loose typing while removing the auto-conversion of numeric strings to ints just when comparing two strings with == and we would all live happily ever after, but who am I to talk - I just use the language :-).

The important thing is that anyone out there using == and in_array() improperly or with the wrong understanding needs to fix their code right away to avoid weird and hard to debug edge case behavior.

 

当字符串作为数值类型计算时,结果的值和类型按以下方式决定。

  如果字符串中包含任何'.', 'e',及'E'字符,则被作为double类型计算。否则,就作为integer类型计算。
  该值从字符串最开始算起。如果字符串是合法的数字,则使用该值,否则值为 0 。合法的数字是一个符号位(可选),后跟一位或几位数字(也可含有一个十进制的小数点), 后跟一位可选的指数。指数是一个 'e' 或 'E'后跟一个或几个数字。

  $foo = 1 + "10.5"; // $foo is a double (11.5)
  $foo = 1 + "-1.3e3"; // $foo is a double (-1299)
  $foo = 1 + "bob-1.3e3"; // $foo is a double (1)
  $foo = 1 + "bob3"; // $foo is an integer (1)
  $foo = 1 + "10 Small Pigs"; // $foo is an integer (11)
  $foo = 1 + "10 Little Piggies"; // $foo is a double (11); the string contains 'e'

 

 

getType($a);//获得变量的类型,另一种方式:var_dump($a);

$a = 0100;零开头表示八进制数
$a = 0xFF;0x开头表示十六进制数
$a = 1.2e-4;表示1.2的乘以十的负四次方。类似:$a=1.4+2
$a = true;布尔型的定义,由于PHP是弱类型的,其他的任何类型都可以转化为布尔型。
   原则:字符串零和空字符串代表假,其它代表真,包括空格。
     浮点数只要出现非零的数代表真
     空数组代表假,其它代表真,
     任何非空资源类型代表真,null代表假
     整型零代表假

类型强制转换
   

    自动转换:

                         如 $a = “100abc”;$b = “300bic”;
                              $c = $a + $b;//输出结果是400;
    强制转换:

                        如 $a = “133asb”:
                            $b = (boolean)$a;
                             $c = (object)$a;
                        强制转换为布尔型:在前面加(bool) ,(boolean)
                        强制转换为实数:在前面加(float),(double),(real)
                      强制转换为字符串:在前面加(string)
                       强制转换为数组:在前面加(array)
                         强制转换为对象:在前面加(obect)
                       强制转换的结果相当于将原来变量的副本转变后形成一个新的类型,而原来的变量不变。而使用setType($a,integer)则是将$a转变为整型,原来的$a将不存在。
                注意:由于浮点数占八个字节,而整型占四个字节,所以强制转换时可能会出现溢出现象

数据类型的转换:三种方式
1. 自动转换(运算符)

2. 强制转换(int,integer, string, bool, boolean, float, real, double, array, object)

3. setType

 

自动类型转换是指定义变量时不需要指定变量的数据类型,PHP会根据具体引用变量的具体应用环境,将变量转换为合适的数据类型。在对变量进行赋值操作的时候,经常会用到自动类型转换。自动类型转换主要包括如下两种方式。

1.直接对变量的赋值操作

直接对变量的赋值操作是自动类型转换最简单的应用,变量的数据类型由赋予的值决定。也就是说,当把一个字符串类型的数据赋值给变量时,该变量就是一个字符串类型的变量;当把一个整型数据赋值给变量时,该变量就是一个整型的变量。实际上,2.3.1节的例子2应用的就是自动类型转换。由于这种方式的自动类型转换比较简单,这里就不再给出示例程序了。

2.运算式结果对变量的赋值操作

自动类型转换的第二种应用方式是将一个运算式的结果赋值给一个变量。这种自动类型转换方式又可分为以下两种情况。

1)运算数为同一数据类型

这种情况处理起来比较简单,由于参与运算的所有运算数都是同一数据类型,所以被赋值的变量也属于这种类型。例如下面给出的代码:

  1. $a = 1.23232;
  2. $b= 2.23;  
  3. $c$a$b;

变量a与变量b都是浮点型变量,这两个变量进行相加运算并将运算结果赋值给变量c,那么这时候,变量c就成为了一个浮点型变量。

2)运算数为不同数据类型

如果所有运算数都是数字,将选取占用字节最长的一种运算数的数据类型作为基准数据类型;如果运算数为字符串,将该字符串转型为数字然后再进行求值运算。字符串转换为数字的规定为:如果字符串以数字开头,只取数字部分而去除数字后面部分,根据数字部分构成决定转型为整型数据还是浮点型数据;如果字符串以字母开头,直接将字符串转换为零。例如下面给出的代码:

  1. $a= 1 + 1.23;  
  2. $b = 2 + "3.14";  
  3. $c= 3 + "abc";

在第1个赋值运算式中,运算数包含了整型数字1和浮点型数字1.23,根据规定取浮点型数据类型作为基准数据类型。赋值后变量a的数据类型为浮点型。

在第2个赋值运算式中,运算数包含了整型数字2和字符串型数据"3.14",首先将字符串转换为浮点型数据3.14,然后再进行加法运算。赋值后变量b的数据类型为浮点型。

在第3个赋值运算式中,运算数包含了整型数字3和字符串型数据"abc",首先将字符串转换为整型数字0,然后再进行加法运算。赋值后变量c的数据类型为整型。

 

PHP强制类型转换的实现方式

(int),(integer)

将其他数据类型强制转换为整型

$a = "3";$b = (int)$a;$c = (integer)$a;

(bool),(boolean)

将其他数据类型强制转换为布尔型

$a = "3";$b = (bool)$a; $c = (boolean)$a;

(float),(double),(real)

将其他数据类型强制转换为浮点型

$a = "3"; $b = (float)$a;$c = (double)$a;$d = (real)$a;

(string)

将其他数据类型强制转换为字符串

$a = 3; $b = (string)$a;

(array)

将其他数据类型强制转换为数组

$a = "3"; $b = (array)$a;

(object)

将其他数据类型强制转换为对象

$a = "3"; $b = (object)$a;

 

其他数据类型转换为整型

   

浮点型

整型

向下取整,即不会四舍五入而是直接去掉浮点型数据小数点后边的部分,只保留整数部分

布尔型

整型

TRUE转换成整型数字1FALSE转换成整型数字0

字符串

整型

字符串为纯整型数字,转换成相应的整型数字

字符串为带小数点数字,转换时去除小数点后面部分,保留整数部分

字符串以整型数字开头,转换时去除整型数字后面部分,然后按照规则1进行处理

字符串以带小数点数字开头,转换时去除小数后面部分,然后按规则2进行处理

字符串内容以非数字开头直接转换为0

 

其他数据类型转换为浮点型

整型

浮点型

将整型数据直接转换为浮点型,数值保持不变

布尔型

浮点型

TRUE转换成浮点型数字1FALSE转换成浮点型数字0

字符串

浮点型

字符串为整型数字,直接转换成相应的浮点型数字

字符串以数字开头,转换时去除数字后面部分,然后按照规则1进行处理

字符串以带小数点数字开头,转换时直接去除数字后面部分,只保留数字部分

字符串以非数字内容开头直接转换为0

 

其他数据类型转换为布尔型

整型

布尔型

0转换为FALSE,非零的其他整型数字转换为TRUE

浮点型

布尔型

0转换为FALSE,非零的其他浮点型数字转换为TRUE

字符串

布尔型

空字符串或字符串内容为零转换为FALSE,其他字符串转换为TRUE

NULL

布尔型

直接转换为FALSE

数组

布尔型

空数组转换为FALSE,非空数组转换为TRUE

 

 

 

其他数据类型转换为数组

   

整型、浮点型、布尔型

字符串、资源

数组

将这几个数据类型强制转换为数组时,得到的数组只包含一个数据元素,该数据就是未转换前的数据,并且该数据的数据类型也与未转换前相同

对象

数组

转换时将对象的成员变量的名称作为各数组元素的key,而转换后数组每个keyvalue都为空,如果成员变量为私有的(private),转换后key的名称为“类名+成员变量名”,如果成员变量为公有的(public),转换后key的名称为成员变量名,如果成员变量为受保护的(protected),转换后key的名称为“*+成员变量名”

NULL

数组

直接转换为一个空数组

 

 

其他数据类型转换为对象

原类型

目标类型

转换规则

整型、浮点型

布尔型、字符串

对象

将其他类型变量转换为对象时,将会新建一个名为“scalar”的属性,并将原变量的值存储在这个属性中

数组

对象

将数组转换为对象时,数组的key作为对象成员变量的名称,对应各个keyvalue作为对象成员变量保存的值

NULL

对象

直接转换为一个空对象

 

其他数据类型转换为字符串

整型

字符串

转换时直接在整型数据两边加上双引号作为转换后的结果

浮点型

字符串

转换时直接在浮点型数据两边加上双引号作为转换后的结果

布尔型

字符串

TRUE转换为字符串“1FALSE转换为字符串“0

数组

字符串

直接转换为字符串“Array

对象

字符串

直接转换为字符串“Object

NULL

字符串

直接转换为空字符串

原创粉丝点击