您的位置:寻梦网首页编程乐园PHP 编程PHP学习宝典-第六章
PHP学习宝典-第六章

[1] | [2] | [3] | [4] | [5] | [6] | [7] | [8] | [9]    


第六章 - 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 
0x1000;


Print(“integer_10:$integer_10
”)


Print(“integer_8:$integer_8
”)


print(“integer_16:$integer_16
”)

其浏览器输出为:

integer_101000


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.2x10-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自己会做出决定,以科学符号记数尽量用最极端大小的数值,但这与最初的读取格式无关。

字串中的换行符号

虽然PHP为换行符号提供了一个跳脱转义序列(
),但让你知道能够在字串中间从字面上加入换行符号也不错,PHP同样能够处理这种形式。在建立HTML字串时这样会很方便,因为浏览器会忽略(
)换行符号,因此可以用换行符号格式化字串,使得PHP程式码行更短:

点击打开新窗口浏览全图

在文字编辑器中,在前两行尾端隐藏按「Enter」键,这些换行符号保留在字串中,因此一条print叙述可以产生三行PHP输出(行的长度则取决于各种不同编辑器,如果编辑器在显示它们时自动换行,就会看到实际是一长条的三行程式码)。不过浏览器程式会忽略这些换行符号,并自己决定显示时是否换行以及在何处换行,此外如果使用你的浏览器的检视原始码观察原始码的话你会看到这些换行。

限制

对于字串长度没有什么人为的限制,只要在可用的记忆限度内即可,一般应该能不去限制字串长度

阵列

PHP的阵列型别使得程式设计者能够将许多不同型别的值组织在一起,并按照字(也可以按名称)对其进行索引。如果你发现自己在使用名字类似$ thing1、$thing2、 $thing3之类的变数,那就建议你应该采用阵列($things[1]、$thing[2]、 $thing[3]等)。阵列元素是透过方括号中的索引(在这个例子子中是)[1]、 [2]、 [3]等)来使用的,不同型别的元素可指定到同一个阵列中。

学习PHP阵列的最好方式就是透过范例。下面是一些简单的程式范例子,在第一次指定前和指定后查看阵列变数的内容:

点击打开新窗口浏览全图

让我们来说明第一次指定前和指定后发生的什么。在指定前,尽管有了名字,但PHP并不知道变数$my_array的目的是要成为一个阵列,只把它当成与其它变数一样的未指定变数。这意思是说在该变数括到双引号字串时,变数被解释为空字串。阵列索引所参照引用([5])到未指定的变数时一样会作未指定变数。结果是前三条print叙述都以[is]为结尾。

指定之后,$my_array正式成为一个阵列,而结果是在含到双引号字串时列印出「Array」字串。由数字5索引的阵列格已填入了字串「Slot#6」(实妹上,在大多数程式语言中,阵列元素是从0开始计数的)因此可用编号5的索引取字串。这是唯一发生变化的地方——$my_array 的第0格还是没有东西,所以和之前一样没有变化。

阵列的执行

阵列是PHP最酷且最有用的功能之一,虽然它们看上去好像类似其它语言中的阵列,但实际上是相当不贩方式来实行的。

在大多数程式设计语言中,会用类似下面的语句来宣告一个阵列:

Int int_array[10] ;//这不是PHP语法呼和哦!

该语句总共会记忆体中设置十个连续的整数,这些变数可按照int_array范围为0 ~9的编号索引来存取。

另一方面,PHP阵列是可以相互结合的,当进行阵列指定时,实际上添加一个新的囝列格,把它和一个新的索引组合在一起,这个索引可用来获取该值[对于熟悉准凑表(hash table)的程式设计来说这是很有意义的,PHP阵列更像其它语言中的准凑表]。

这里暗示了一件事,那就是读者不用担心指定一个数量非常高的阵列格,例如:

My_ayyay[100000000]= “not scary”//这个就没问题了

因为这样设的结果并不会真的出现很很多的格位,中间那些格位都不存在,因此也不会占用任何记忆体。

字串做为阵列索引

到目前为止,我们的阵列范例子只使用整数来索引编号,其实PHP也可以使用字串值做为索引,例如:

$tasty[‘Spanish’]= “paella”;


$tast [‘Japanese’]= “sashimi”;


$tast [‘Scottish’]= “haggis?”;

这些索引与数字索引的使用方式相同,而且数字和字串索引可用于同一个阵列,它们不会有冲突。

结构型别怎么不见了?

有些程式语言(C、Pascal)提供了「结构(structure)」或「纪录(record)」型别,允许把不同型别的变数包装在一起。这样的语言中,选择复合型别的基本原则是:如果包含水量的所有值是同一型别的,否则就使用结构。

现在的PHP有了物件型别(object type),它除了有更特殊的属性外,也有类似纪录或结构型别的特性。然而在介绍物件之前,PHP也并不真正需要结构型别,因为PHP的阵列并没有限制只能使用一种型别的值。如果从有结构型别的语言中把程式码尊字典转到PHP中,有种可能性就是利用可结合的阵列,并使用字串索引,分别对应原来的栏位名称。

其它阵列特性

其实本章只会粗浅介绍阵列,另外,阵列还可以是多维的,可以用许多不同方法指定,并且还有许多有用的函式,可使用对阵列的观察、重用和操控更容易。在本书第十一章会更深入讲解阵列。

物件

PHP的另外一种基本型别就是物件,这是PHP进入物件导向程式语言的通道。有如阵列一般,物件也是一种复合型别,并可以使你将其他各种型别整合为一个物件,物件拥有额外更加复准的属性,包含水量可以将函式视为资料整合在内,并可以使用其他物件道向的观念,并期许你参阅该章节来学到更多的资讯。

Resources

Resources是PHP本身之外一种用来参照记忆体的特殊值,你不需要知道太多关于Resources就可以 写PHP,我们会简单介绍所有可能的Resources,但是请安心跳过以下「要如何处理资源」部分。

到底何者是Resources呢?

Resources是PHP用来与外部程式沟通的型别(可以是资料库或者影像处理程式),PHP可能需要使用这些程式在记忆体所配置的资源,大体上PHP 程式设计师不需在PHP设计上担心记忆体的释放,如果你在PHP程式内产生一个字串(必须占据一部份记忆体位置),你可以忘记它的一切细节直到程式结束, PHP(或者所架的Wed伺服器)会在你的程式执行完毕后释回适当的记忆体,即使并非马上。

外部的程式(资料库等等)可能无法如此聪明的释放记忆体,等到你的程式已经运作之后你可能设想到为你的资料库保留适当的记忆体,PHP用这种方式所处理的方法是将所有有如这般外部程式存取记忆体的特殊函式都回传Resources,并用来让PHP检查是否你的程式可以取得这些资源,如果没有人可以使用这些资源的话,PHP会藉由记数此资源的参照,使得外部程式可以正确解决这类问题,如果参照计数为0的话这个资源就可以被释回了。

要如何处理资源?

通常PHP程式设计师本身并不需建立这些资源,他们藉由呼叫一些特殊函式来回传这些资源型别,并将之传迅给其他需要资源型别的函式。例如(我们会在本书第二部份介绍),你可以乎要mysql_connect()函式(用来回传连线到M y S Q L资料参照),并存放结果到一个变数,并传迅它给mysql_query()函式(使用此连线来存取资料库)。

基本上你使用这个连线资源所南需要的步骤是将它存放在一具变数并将它传迅至需要的函式内,你可以在程式结束后透过PHP来清除这个资源。无论如何,如果你觉得在程式结束之前这个资源在程式执行中已经耗尽了许多记忆体并想要提前释放的话,你应该可以如同这样做:

$my_resource=mysql_connect();//存放变数


//使用连线资源的程式片段


$my_resource=NULL;//变数不再参照原资源


$my_resource的指定会使得PHP检查没有其他程式使用MySQL资源然后才开始释放它。

型别测试

因为变数能够根据重新指定来改变型别,有时就需要在程式执行时弄清楚某个值的型别。PHP既提供了一般的型别测试函式(gettype()),也为五种资料型别分别提供了Boolean函式。这些函式中有的还具有可替换的名称,表6-1总了这些函式:

表6-1函式的型别测试

点击打开新窗口浏览全图

指定和强制转换

正如前面已经讲过的,PHP常常在本文需要时自动把一种型别转换成另一种,不过PHP程式设计者也可以强制发生这样的转换。无论在哪种情况下,程试设计者都应该知道期望得到什么结果。

型别转换行为

以下是PHP从一种型别转换成另一种时的一些通则:

整数到倍精度浮点数:建立精确符合的倍精度浮点数(例如int4变成double4.0倍)。

倍精度浮点数到整数:小数部分被舍去。

数字到Boolean:如果等于0,则为FALSE,否则为TRUE。

数字到字串:字串按数字显示时的外观来建立。整数输出显示为一个数字序列,倍精度浮点数按所需的最小精度来输出,小数点后字数很多的倍精度浮点值将转换为笠学符号记数法。

Boolean到数字:如果是TRUE,则得到1,如果是FALSE,则得到0。

Boolean的字串:如果是TRUE,则得到1,如果是FALSE则得到空字串。

NULL到数字:0

NULL到Boolean:FALSE

字串到数字:等同于从字串「读取」一个数字,然后把它椟换成给定的型别。如果无法读出数字,则得值为0,并非所有字串都需要能够读取才算成功。

字串到Boolean:如果是空字串或0,则为FALSE,否则为TRUE。

简单型别(数字或字串)的阵列:等同于用指定给索引0的这个值建立一个新阵列。

阵列到数字:未定义(详见以下说明)

阵列到Boolean:如果阵列没有元素,则为FALSE,否则为TRUE。

阵列到字串:即为「Arryay」。

物件到数字:未定义(详见以下说明)。

物件到Boolean:如果物件含有任合成员变数拥有值的话为TRUE,否则为FALSE。

物件到字串:「Object」.

资源到Boolean:FALSE。

资源到数字:未定义(详见以下说明)

资源到数字:有时有如「Resource id #1」(但是无法十分依赖这个惯例)。

在上述列表中,我们发现有些型别在转换为数值型别时是未定义的,在上述说明中,未定义意指PHP设计者并没有在未业PHP版本定下何种最终的转换规则,所以坏消息就是必须根据你的程式写法所定,你可能在你使用的特定PHP版本发现可以转换为数值型别,但是却可能无法在下一个版本运作。

[上一页]    [下一页]