现在的位置: 首页 > 综合 > 正文

PHP中的类型转换规则

2012年10月04日 ⁄ 综合 ⁄ 共 6656字 ⁄ 字号 评论关闭

字符串会被转化为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
转换成整型数字
1

FALSE
转换成整型数字
0

字符串

整型

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

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

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

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

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

 

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









整型

浮点型

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

布尔型

浮点型

TRUE
转换成浮点型数字
1

FALSE
转换成浮点型数字
0

字符串

浮点型

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

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

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

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

 

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









整型

布尔型

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

浮点型

布尔型

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

字符串

布尔型

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

NULL

布尔型

直接转换为
FALSE

数组

布尔型

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

 

 

 

其他数据类型转换为数组


 


 







整型、浮点型、布尔型

字符串、资源

数组

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

对象

数组

转换时将对象的成员变量的名称作为各数组元素的
key
,而转换后数组每个
key

value
都为空,如果成员变量为私有的(
private
),转换后
key
的名称为“类名
+
成员变量名”,如果成员变量为公有的(
public
),转换后
key
的名称为成员变量名,如果成员变量为受保护的(
protected
),转换后
key
的名称为“
*+
成员变量名”

NULL

数组

直接转换为一个空数组

 

 

其他数据类型转换为对象

原类型

目标类型

转换规则

整型、浮点型

布尔型、字符串

对象

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

数组

对象

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

value
作为对象成员变量保存的值

NULL

对象

直接转换为一个空对象

 

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









整型

字符串

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

浮点型

字符串

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

布尔型

字符串

TRUE
转换为字符串“
1


FALSE
转换为字符串“
0

数组

字符串

直接转换为字符串“
Array

对象

字符串

直接转换为字符串“
Object

NULL

字符串

直接转换为空字符串

抱歉!评论已关闭.