当前位置:首页 > PHP学习宝典-第六章

PHP学习宝典-第六章

点击次数:1231  更新日期:2011-01-03
\n

PHP学习宝典-第六章 (1)
第六章

PHP中的型别

本章重点

◆ 了解PHP的八种型别…Boolean、

◆ NULL、string、array、object与、resource

◆ 建立、读取、显示输出与操控不同型别的物件

从某种型别转换成其它型别

所有程式设计语言都有某些型别系统,且来指定可出现在程式中的数值种类。这些不同的型别常对应于电脑记忆体中不同层级的表示,在很多情况下程式设计者不用考虑位元的表示方式(或是有足够能力处理)。PHP的型别系统是简单合理,而且很有弹性,它把程式设计者与一些低阶段的细节分隔开来。

在本章中,我们将说明PHP的基本型别(integer、double、Boolean、NULL、string、array、object、resource),并且讲解如何读取、如何输出显示、如何、指定给变数、如何转换以及怎么组合在一起。在这一章中既是概论也是参考资料,对已是程式设计老手的人可以跳过不看,但只有部份不太熟悉的人可以只阅读前面几节,不管是谁都可以在往后有问题时回不来查找那些当初看起来无关紧要的细节内容。

首要原则:放松自己

PHP使得在键入变数和值时很容易,这是因为它不需在指定娈数和确定型别,另外也是因为它能够处理很多种型别的转换。

变数型别不必先宣告

正如在上章中已经提到的内容,变数的型别不是需要提前宣告,可由程式设计者直接使用运算式指定值,而PHP自己会负责弄清楚在指定的值是什么型别,如下范例:

first_number=55.5;

second_number=“Not a number at all”;

型别自动转换

PHP在需要时自动进行型别的转换。与现在大多数的程式语言一样,PHP在进行混合式的数字型别计算时,也都可以执行得很好,例如运算式

pi=3+0.14159

的结果就会是个倍精度浮点数,在执行加法前,整数「3」就会被暗中先转换成了浮点数。

根据上下文配制型别

PHP在执行自动型别转换时比大多数语言做得更深入,请看看下面的例子

sub=substr(12345,2,2);

Print(“sub is sub
”);

Substr函式是设计成以一个字串当成一个输入值,然后传回该字串的某部份子字串,由函式的另两个参数来决定取回子字串的起点和长度。在这个例子中,我们并不是给它传递字串值,而是传递了整数12345,结果会怎样呢?实际上执行并不会有什么问题,浏览器一样会输出

Sub is 34

由于substr希望得到的是字串而不是整数,PHP会自动把数字12345转换成了字串「12345」,然后substr就可以做自己的事情了。

因为这种自动的型别转换特性,PHP很难在型别方面出错,不过实际是PHP程式设计者还是需要小心一些,以确保型别的混合使用不会产生「没什么错误、但却也不是正确结果」的情况。

型别总整理]

PHP只有八种型别…Boolean、string、array、object、NULL和resource。

* integer 数字的整数部份,没有小数点,如495。

* double 倍精度浮点数,类似3.14159或49.0等。

* Boolean 布林型别,只可能出现两种值,TRUE或FALSE(真或非真)。

* NULL 一种特殊型别,其值只有可能为NULL。

* string 字串,是字元序列,类似「PHP4支援字串运算」这类的表示法。

* array 阵列,是对一些已经命名且建立索引之其它值的集合。

* object 物件,由程式设计者定义类别(class)的实例,可包装特定于该类

别的其它型别之值和函式。

* tesource 是一种特殊变数,用来存放参照到PHP外部的资源(例如资料库连线)

请注意Boolean、NULL与resource这些型别是PHP4所增加的型别,PHP3并不适用。

当然前面五种型别属于基本型另别,而接续两种(array与object)属于复合型别,这些复合型别可以用来将任意型别的任意值组成一群变数,但是基本型别却不行。我们在本章只会简短复合型别(array与object),因为它们会在各自所属章节详细介绍。最后,resource类型是PHP设计师不会直接处理的特殊型别,而是透过特殊函式来存取资源或是它们传递给所需要的其他函式。

简单型别

PHP中的简单型别(integer、double、Boolean、NULL和string)对于有程式设计经验的人来说一定很熟悉(虽然我们并非针对熟练的人,但我们还是要详细讲解它们)。唯一会让C语言程式设计者感到吃惊的可能就是PHP的型别怎么少。

大多数程式语言都有几种不同大小的数字型别,较大的数值型别允许值的范围更广,但也会占用更多的记忆体空间。例如,C语言有short型别(用于相对较小的整数),long型别(用于可能很大的整数)和int型别(这是种中间型别,但实际上不是和short就是和long型别相同),它还有不同精确度的浮点数类型,在记忆体使用和功能之间的取拾可能会令你烦恼,但这种型别选择还是很有意义的。PHP设计开发人员帮我们做出了很好的取拾,透过只用两种数字型别简化了这个难题,这两种型别分别对应于C语言中的整数和浮点数型别。

整数型别

Integer是简单的型别,对应于包括正数和负数的简单整数。整数可指定值给变数,或者可用在运算式中,如下所示的例子:

int_var=12345;

another_int=-12345+12345;//等于

读取格式

整数实际上可用三种相对于不同基数的方式来读取,十进位(基数为10)、八进位(基数为8)和十六进位(基数为16)。十进位格式是预设值,八进位整数的前置是以「0」来指定的,十六进位的前置为「0x」。任何格式都可以前置「-」符号来命使整数为负数。例如:

integer_10 = 1000;

integer_8 = -01000;

integer_16 = 0×1000;

Print(“integer_10:integer_10
”);

Print(“integer_8:integer_8
”);

print(“integer_16:integer_16
”);

其浏览器输出为:

integer_10: 1000

integer_8: -512

integer_16: 4096

(请注意,读取格式只影响整数被读取时是如何换的,储存在integer_8中的值并不会记下最初是以8为基数编写的。人、从内部来看,理所当然地这些数字都是以二进位式表示的,而在最的输出是以10为基数的转换结果,因为这是预设列印的,另外它也会把 int变数合并进字串的预设置)。

范围

整数可以多大(或多小)呢?因为PHP整数是对应于C的long型别,而该类型取决于你使用机器系统上的字的长度,所以很难明确地回答这个问题。不过在大多数常见系统一台上,最大的整数是「231-1」(或2,147,483,647),最小(负)整数是「-(231-1)」(或-2,147,483,647)。

就我们所知,目前没有能指出完成式中最大整数的PHP常数(类似C语言中的MAXINT),如果有疑问,请参见本章最后面的补充内容,如果你真的有需要使用非常大的整数,PHP是有一些专精度(arbitrary-precision)函式,请参阅第十二章关于「BC」该节。

double型别

double是倍精度浮点数,例如

first_double = 123.456;

second_double = 0.456;

seven_double = 2.0 ;

请注意even_double是个「四舍五入取整数(round)」的数字,但并不表示它是个整数型别。整数型别和倍精度型虽数是以不同的基楚格式储存的,例如下列运算式:

five = even_double+3;

的结果的个倍精度型别数,而不是个整数型别,即使它列出的结果是「5」。然而,在所有情况下,都可以自由地在数学运算式中混合使用倍精度浮点数和整数,让PHP自己来选型别来处理。

在预设情况下,列出倍精度数字时采用了所需的最少的小数位数,例如,程式码,

many = 2.2888800;

many_2 = 2.2111200;

few = many + many_2;

Print(“many + many_2 = few
”);

在浏览器中产生下面的输出:

2.28888 + 2.21112 = 4.5

如果需要更精确地控制输出显示结果,可参阅第十章的printf函式

读取格式

倍精度浮点数的典型取格式是「-X.Y」,其中「-」是选择性的,用来指定负数,X和Y 是0-9之间的数字序列。X部份可以省略(如果数字在-1.0至1.0之间),Y部份也可以省略(没有小数点)。前置的工结尾的0都可忽略,下面皆为有效果的倍精度浮点数例子:

small_positive = 0.12345;

small_negative = -.12345

even_double = 2.00000;

still_double = 2.;

另外,倍业精长数度可按科学符号记数法来指定,在前面格式尾端添加字母e和想在的10的整数乘幕,例如,「2.2e-3」将对应于「2.2×10-3」。数字的浮点数部份不需要严格限制在1.0和10.0之间的范围。下面所有范围例程式码行皆为有效:

small_positive=5.6-3;

Ptint(“small_positive is small_postive
”);

large_positive=2.8e+16;

Ptint(“large_positive is large_postive
”);

small_negative = -2222e-10;

Ptint(“small_negative is small_negative
”);

large_negative=-0.00189e6;

Ptint(“large_negative is large_negative
”);

他在们在浏览器的输出为:

small_positive is 0.0055

larger_positive is 2.8e+16

sall_negative is -2.222e-07

large_negative is -1890

请注意,与八进位和十六进位整数一样,一旦PHP结束了读取数字的过程,读取格式就与前面的变数不相干了,它不会记得最初是用科学符号记数法指定的,输出列印值的时候,PHP自己会做出决定,以科学符号记数尽量用最极端大小的数值,但这与最初的读取格式无关。

Boolean型别

Boolean值表示或非真值,用于控制类似if语句中「测试判断」的结构。在下一章中将会看到Boolean值可使用逻辑运算子组合起来,以组成更复杂的Boolean运算式。

Boolean型别是PHP4新增的,PHP3没有那么正统的Boolean型别,而是很简单地利用其它型别的某些值作为判断真或假来对待(这种方法对于用Perl的高手来说一定很熟悉)。其差别并没有想像中那么大,因为可在Boolean的本文中使用其它型别,PHP4会先做自动型别转换(在本部分稍后的「PHP 3和PHP 4的Boolean型别」会介绍介于PHP 3 与PHP 4两者处理上的差异)。

Boolean常数

PHP提供了两个常数来做为Boolean值使用,那就是TRUE和FALSE,可以按下面的方式使用它们:

if (TRUE)

print(“This will always print
”);

else

print(“This will never print
”);

将其它型别解译为Boolean型别

以下是有决定不是Boolean型别的值是「真(TRUE)或非真(FALSE)」的规则:

1. 如果该值为数字、且确切等于0,则为非真,否则为真。

2. 如果该值为字串、且字串为空值(其中没有任何字元)或字串是「0」则为非真,否则为真。

3. NULL值恒为非真。

4. 如果该值为复型别(array或object),如果它不含任何值的话皆为非真,否则为真。对于object而言,拥有值意谓著该物件成员曾被指定内容。

5. 合法的resource型别为真(虽然有些函式会在成功时回应resource为真,并在失败时回传非真)。

对于有关转换不同型别的值更详细的说明请参见本章稍后的「指定和强制转换」。

范例

下面的每个变数会是TRUE,当用于Boolean本文中时TRUE值会嵌入其名字所表示的变数。

true_num = 3 + 0.14159;

true_str = “Tried and true”

ture_array「49」= “An array element”;//参阅下一节

false_array = array() ;

false_null = NULL;

fales_num = 999 – 999;

false_str = 〝〞;//字元长度为零的字串

不要把double当成Boolean使用

请注意,虽然是述规则1中暗示了倍精度浮点数0.0转化为Boolean值FALSE,但把浮点表示式用作Boolean运算式还是很危险,因为可能有误舍去的情况。例如:

floatool = sqrt(2.0)*sqrt(2.0) – 2.0;

if (floatbool)

print(“Floating-point Booleans are dangerous!
”);

else

print(“It worked…this time.
”);

print(“The actual value is floatool
”);

floatbool的值非常接近0.0,但它是非0的,因此得到了并不想要的真值(TRUE)。以整数来当成Boolean的角色则安全许多,只要和其它整数在进行运算时保持在整数允许的大小范围内,就应该没有取整数舍入的错误。

PHP3和PHP4的Boolean型别

因为PHP3没有独立的Boolean型别,常数TRUE和FALSE的真实值是其它型别,有些实验可显示出他们的值是什么。不过还是请记住,在非Boolean情况下并不鼓励使用常数,因为它可能导致与PHP4不相容。一般遵循的法则是:不的Boolean值进行是否明确相等的比对,而是直接把它们合并到测试中去。

举例来说,假设编写了某个函式,已经有一个值定给变数truth_value。这个变数可能是个数字串,但在按照前面讲过的转换规则解译时应该有真或非真值。应该怎么使用这个变数才能够在PHP3和PHP4中都有效相容呢?以下是正确示范:

if (truth_value)//漂亮的PHP!在PHP3或PHP4中都很安全

print(“truth_value is true!
”);

错误的方法则类似这样编写:

if (truth_value==TRUE)//不太好的PHP…与Boolean比较

print(“truth_value is true!
”);

上述错误示范在PHP3与PHP4的方法可能不同,假设truth_value值为「3」时,PHP4会进行是否相等的比较之前就会把「3」转换成Boolean值,即TRUE,而PHP3会测试数字「3」,看它是否与TRUE的实际值相等,然后测试结果会失改。

NULL型别

Boolean型别可能看似一种小型别,因为它只有两种可能的值。然而NULL型别更是如此,NULL型别只有一种可能的值,就是NULL,你可以使用下列方式来指定NULL值:

my_var=NULL;

那么究竟NULL的特殊之处在哪里呢,NULL的意思就是此变数缺乏储存值(你可以解释为没有值,或是尚未指定值),一个被指定为NULL的变数与一个尚未被宣告的变数是几乎无法区分的,基本上变数被指定为NULL有下列特性:

◆ 在Boolean的判断句为非真

◆ 当你使用IsSet()测试时会回传非真(其他型别接回传真)

◆ 如果你传递变数到函式并回传回来时PHP不会显示警告,但是传递为宣告的变数有时会产生警告

NULL值的最佳时机应是当你需要一个不存在任何内容的变数时,而且根据你的需要,你希望阅读你程式的我与PHP本身都能清楚的了解。上述最后一点在你传递变数给函式时是特别要注意的。

例如,以下的虚拟程式可能在变数authorization传递给test_authorization()函式却未指定的情况下可能显示警告的例子(根据你的错误回报设定而言):

if(test_authorization( authorization)) {

//用来允许权限的某些程式片断

}

另一方面,以下程式:

authorization = NULL;

//程式可能已经或尚未设定 authorization

if(test_authorization( authorization)) {

//用来允许权限的某些程式片断

}

假设你已经在test_authorization()处置针对NULL参数的处理,将不会产生变数不正常的警告,这样的写法可以使你程式阅读的人更加清楚你想要使用一个除非原先已经有指定值之外可能为NULL的变数。

string型别

string就是字元的序列,如下所示:

string_1 = “This is a string in double quotes.”;

string_2 = ˋThis is a somewhat longer,singly quoted stringˊ;

string_39 = “This string has thirty-nine characters.”;

string_0 = “”;//字元数为零的字串

字串可括在单引号或双引号中,分别在读取的时候有不同含义。单引号字串几乎是按字面的意思来对待,而双引号字串把变数以相应的值替代,并且专门解释了某些字元序列。

单引号字串

除非内含一些特殊使用的字元之外,可用单引号字串按字面上的字元读取并保存。下面程式码:

literally = ‘My variable will not print!
’;

print(literally);

将在浏览器产生如下的输出:

My variable will not print!


单引号字串也是遵循一个通则,不同类型的引号在字串中出现并不会使该字串出问题或中断,下面的语句是有效的:

singly_quoted = ‘This quote mark :“is no big deal’;

如果要在单引号括住的字串嵌入一个单引号,可以反斜线来配合进行转义,如下所示:

singly_quoted = ‘This quote mark’s no big deal either’;

在用单引号括住的字串中,虽然大多数情况下反斜线是用作特定字元配合解译的,如果想要在字串中出现反斜线,则可以使用二条反斜线()成为普通反斜线的转义序列。当把反斜线当成字串中的最后一个字元时,这种方法很有用,如下所示:

win_path = ‘C:InetPubPHP’;

Print(“A Windows-style pathname:win_path
”);

显示的输出为:

A Windows-style pathname:C:InetPubPHP

我们可以使用单反斜线在输出时产生最开始的二个斜线,但在字串末端需要进行跳脱转义,使得结束的引号不被转义。

这些跳脱转义序列(和 、)是单引字串的字面处理方式中唯一出现的例外。

双引号字串

以双引号定界限划分的字串(像「“this”」),在PHP中以两种方式进行预先处理:

1. 反斜线()开始的某些字串序列会以特殊符号替换。

2. 变数名称(以开始)会替换成它们的值的字串所表示之形式。

跳脱转义序列替换方式是:


替换成换行符号


替换成Enter

替换成跳位字元

$ 替换成「$」符号本身

” 替换成单个双引号(”)

替换成单个反斜线()

上面的前三个替换使得在字串中包含某些可见的空白字元变得很容易。「$」序列使得可在需要时包含「$」符号,它不会被解释为变数的开始。「”」序列使得在字串中可以包含一个双引号符号,而不会当成终止的那个双引号。最后,因为「」字元是所有这些序列的开始,你需要有一种方式能够需要这个字元时也可以包含进去,而不会把它当做是特别要跳脱序列的开始。若要做到这一点,使用「」就行了。

和单引号字串一样,若是不同类的引号则可自由使用,不用加入跳脱转义字元,如下所示:

has_apostrophe = “There′s no problem here”;

变数的插入

无论何时未做跳脱转义的「$」出现该变数的当前值插入接到字串中。这样做的确切结果取决变数是如何被设定的:

◆ 如果变数就是设成为字串值,该字串被插入(或并接)到带双引号的字串中。

◆ 如果变数当前不是设为一个串值,该值会被转换成字串,然后插入。

◆ 如果变数当前没有被设定过,PHP什么也不插入(或是插入一个空字串)。

下面是一个示范的例子:

this = “this”;

that = “that”;

the_other = 2.2000000000;

Ptint(“$this,not, that+the_other
”);

产生的PHP输出为:

This ,,that + 2.2


在浏览器中会看到这样的结果:

This ,,that + 2.2

如果读者对这个例子中的某个部分感到困惑,那就值得研究一下PHP如何解析print叙述中的字串。首先,注意该字串带有四个「$」符号,每个都会被解释为变数名称的开头。这些变数名称在遇到第一个无法解释为变数名称的合法字元时终止。有效字元是字母、数字和底线(_);在前面例子中输出字串内「无效」的终止字元是(按顺序):逗号、另一人逗号、加号(+)的左括号(<)。前两个变数找出对应的字串(ˋ thisˊ和ˋthatˊ),因此这些字串按字面会并接在一起。下一个变数($not_set)从未被指定过值,因此完全从正在建构的字串中省略掉了。最后一个变数($the_other)相对应为一个浮点数,这个值被转换为字串(就是「2.2」),然后把它插入正在建构的字串中。

关于把数字转换成字串的详细内容,请参考本章后面的「指定和强制转换」一节。

正如我们在第五章中提到的,双引号字串的所有这些解释都是在读取字串时发生的,而不是在输出显示(print)的时候。如果把范例的字串储存在某个变数中,以后再输出显示,它仍然会反映了前面程式码中的变数值,即使那些变数在这期间已经发生了改变。

除了单引号与双引号之外,尚有其他方式可以产生字串(称为heredoc语法),这种方法可以使你更容易将字串与变数合并在一起,我们会在第十章提及。


\n

出处:南方Linux

\n