发新话题
打印

PHP与MySQL 5程序设计(第2版)

当前章节:3.1 界定PHP代码

前面两章涵盖了关于PHP语言的一些基础知识。到目前为止,你已经对这种语言的背景和历史有所熟悉,并且深入了解了安装和配置的有关概念和过程。这些内容为本书余下的部分奠定了基础,即如何创建强大的PHP应用程序。从这一章开始,我们将逐步展开讨论,首先介绍PHP语言的众多基本功能。具体地,本章内容包括:
  ● 如何界定PHP代码,使解析引擎能确定应当解析和执行脚本的哪些部分,而哪些部分应当忽略。
  ● 介绍对代码加注释的各种方法(借用UNIX shell脚本、C和C++语言的方法)。
  ● 如何使用echo()、print()、printf()和sprintf()语句输出数据。
  ● 讨论PHP的数据类型、变量、操作符和语句。
  ● 全面介绍PHP的关键控制结构和语句,包括if-else-elseif、while、foreach、include、require、break、continue和declare。
学完本章之后,你不但能掌握创建有用的基本PHP应用程序所必需的知识,还会了解需要哪些知识来学习后面的章节。
3.1 界定PHP代码
PHP的优点之一是可以把PHP代码直接嵌入到静态HTML页面中。要让代码做事情,必须把页面传递给PHP引擎进行解释。但是,如果解释器将每一行都看作是PHP命令,效率将非常低下。因此,解析器需要一种方法来立即确定页面中的哪些部分是PHP代码。逻辑上,这是通过界定PHP代码来实现的。共有4种不同的界定形式,这一节将逐一进行介绍。
3.1.1 默认语法
默认的界定语法以<?php开头,以?>结束,如下:

如果把上述代码保存为test.php,从Web服务器(已启用PHP)调用时,将得到如图3-1所示的输出。

图3-1  示例PHP输出

3.1.2 短标记
还有一种不太常见的形式,可以使用更短的界定语法。这种语法称为短标记(short-tag),其中省略了默认语法中必需的php引用。但是,要使用这个特性,需要启用PHP的short_open_tag指令。示例如下:

注意   虽然短标记定界符非常方便,但要记住这会与XML和XHTML语法冲突。所以出于一致性的原因,应当使用默认语法。

一般情况下会使用print或echo语句来显示信息。启用短标记时,可以省略这些语句,而使用一种称为短路语法(short-circuit syntax)的输出形式:

这与下面两种形式在功能上是相同的:

3.1.3 脚本
历史上,某些编辑器(特别是微软的FrontPage编辑器)在处理PHP等采用的转义语法时存在问题。因此,PHP还支持另一种主流的界定形式:<script>。

提示   微软的FrontPage编辑器还能识别下面介绍的ASP风格的界定语法。

3.1.4 ASP风格
Microsoft ASP页面使用了一种类似的策略,使用预定义的字符模式将静态内容和动态内容分开:以<%开头,以%>结束。如果你有使用ASP的背景,并且想继续使用这种语法,PHP也能提供支持。下面是一个例子:

3.1.5 嵌入多个代码块
在一个页面中,PHP代码与非PHP代码可以多次交替出现。例如,下面的示例是可以接受的:

注意,前面块中声明的所有变量都能被“记住”,能由后面的块使用,如此例中的$date变量。
网络无限,生活无限

TOP

当前章节:3.2 注释

3.2 注释
无论是为你自己着想,还是为以后负责维护代码的程序员考虑,都需要对代码添加充分的注释,其重要性再强调都不为过。PHP提供了几种注释语法,将在这一节分别介绍。
3.2.1 单行C++语法
注释通常不会超过一行。因为这种注释很简短,所以没必要界定注释的结束,换行符(\n)完全可以满足此需要。PHP支持C++的单行注释语法,以双斜线(//)开头,如下:

3.2.2 Shell语法
PHP还支持另一种C++风格的单行语法,称为shell语法,它以#符号开头。可以将前面的例子重写如下:

3.2.3 多行C语法
代码中通常需要有一些详细的功能描述或其他解释内容,这些说明可能包括多行。虽然可以在每一行前面都加上C++或shell风格的定界符,不过,PHP还支持一种多行形式,同时标注注释的开始和结束。考虑下面的多行注释:

多行注释语法对于根据代码生成文档尤其有用,因为这样可以很明确地区分出各个注释,如果使用单行语法很难做到如此方便。
网络无限,生活无限

TOP

3.3 输出
大多数Web应用程序都有高度的交互性。写得好的脚本会经常与用户通信,可能通过工具界面,也可能通过请求响应。PHP提供了一系列显示信息的方法,本节将分别介绍。
3.3.1 print()

pirnt()语句负责为用户提供反馈,能显示原始字符串和变量。以下都是print()语句:

所有这些语句都能生成同样的输出:


前三种形式很容易理解,但最后一种理解起来却不太容易。在最后这种形式中,3个字符串使用点号拼接起来,点号在这里称为拼接(concatenation)操作符。在拼接变量、常量和静态字符串时通常会采用这种做法。在本书中你也将反复看到这种用法。
注解   虽然正式语法要求使用括号把参数括起来,但也可以省略括号。许多程序员倾向于省略括号,因为即使没有括号目标参数也同样很清晰。

3.3.2 echo()

echo()语句与print()类似,但有两点不同。首先,echo()语句不能用在复杂表达式中,因为它返回void,而print()返回一个Boolean值。其次,echo()能输出多个字符串。这个功能可能有问题;使用它也许只是出于偏好,没有其他原因。不过,如果确实需要,也可以用这个特性。下面是一个例子:

以上代码生成的内容如下:


提示    哪一个更快,echo()还是print()?它们在功能上可以互换,这就使很多人都在考虑这个问题。答案是echo()函数稍微快一些,因为它没有返回值,而print()要返回一个Boolean值,通知调用者语句是否已经成功地输出。不过,你可能注意不到速度上的任何差别,所以选择哪个语句可以认为是一个风格方面的问题。

3.3.3 printf()

printf()函数的功能与print()相同,会输出args中指定的参数,但是它的输出将根据format进行格式化。format参数可以对输出数据进行充分地控制,如对齐方式、精度、类型或位置。这个参数由5部分组成,按以下顺序出现:
  ● 填充提示符:可选,这一部分确定为达到正确的字符串大小所用的填充字符。默认为空格,也可以指定其他填充提示符(在字符前加一个单引号)。
  ● 对齐提示符:可选,这一部分确定输出是左对齐还是右对齐。默认为右对齐,可以用一个负号设置为左对齐。
  ● 宽度提示符:可选,这一部分确定此函数输出的最少字符数。
  ● 精度提示符:可选,确定应显示的小数位数,这一部分只影响浮点数类型的数据。
  ● 类型提示符:这一部分确定如何转换参数。它所支持的类型提示符如表3-1所列。

表3-1 所支持的类型提示符

类    型

描    述

%b
将参数认为是一个整数,显示为二进制数
%c
将参数认为是一个整数,显示为对应的ASCII字符
%d
将参数认为是一个整数,显示为有符号十进制数
%f
将参数认为是一个浮点数,显示为浮点数
%o
将参数认为是一个整数,显示为八进制数
%s
将参数认为是一个字符串,显示为字符串
%u
将参数认为是一个整数,显示为无符号十进制数
%x
将参数认为是一个整数,显示为小写的十六进制数
%X
将参数认为是一个整数,显示为大写的十六进制数

以下是几个例子:

有时,如果能改变参数的输出顺序,或者在参数列表并不重复列出某个参数的情况下能重复输出这个参数,这将会很方便。为此,可以根据位置来引用参数。例如,%2$表示参数位于参数列表的第2个位置,而%3$表示参数列表中的第3个参数。但是,置于format字符串中时,美元符必须转义,例如,转义为%2\$。下面是两个例子:

3.3.4 sprintf()

sprintf()函数的功能与printf()相同,但它将输出指派到字符串,而不是直接指派到标准输出。示例如下:
网络无限,生活无限

TOP

当前章节:3.4 数据类型

3.4 数据类型
数据类型是具有相同特性的一组数据的统称。常见的数据类型包括字符串型、整型、浮点型和布尔型。PHP早就提供了丰富的数据类型,PHP 5中又有更多补充。本节将介绍这些数据类型,可以分为3类:标量数据类型、复合数据类型和特殊数据类型。
3.4.1 标量数据类型
标量数据类型能包含单个的一项信息,以下都属于标量数据类型:布尔型、整型、浮点型和字符串型。
1. 布尔型
布尔数据类型以数学家乔治·布尔(1815—1864)的名字命名,他被认为是信息论的创始人之一。布尔变量表示真实性,只支持两个值:TRUE(真)或FALSE(假),不区分大小写。另一方面,也可以使用0来表示FALSE,非0值表示TRUE。下面是几个例子:

2. 整型
整数就是一个不包含小数部分的数。十进制数(基数为10)、八进制数(基数为8)和十六进制数(基数为16)都属于这一类。下面是几个例子:

所支持的最大整数与平台有关,一般是正负231。如果试图在PHP脚本中超出此限制,将自动转换为浮点数。示例如下:

这将得到下面的结果:


3. 浮点型
浮点数(floating-point number)也称为单精度数(float)、双精度数(double)或实数(real number),可以指定包含小数部分的数。浮点数用于表示货币值、重量、距离,以及用简单的整数无法满足要求的其他表示。PHP浮点数可以用多种方式指定,如下:

4. 字符串
简言之,字符串是一个字符序列,看作是一个连续的组。这样的组通常用单引号或双引号界定,不过PHP还支持另一种界定方法,这将在3.9节中介绍。所有三种界定方法都将在这一节中进行讨论。
下面是一些有效的字符串例子:

历史上,PHP将字符串看作数组(关于数组的更多信息,请参见下一节),允许通过数组偏移记法访问特定的字符。例如,如果有以下字符串:

可以将字符串当作数组来访问和显示某个字符,如下:

虽然这很方便,但会导致一些混淆,因此PHP 5引入了专门的字符串偏移功能,第9章将做详细介绍。此外,第9章还将重点介绍PHP中很多重要的字符串和正则表达式函数。
3.4.2 复合数据类型
复合数据类型允许将多个相同类型的项聚集起来,表示为一个实体。这包含数组(array)和对象(object)。
1. 数组
将一系列类似的项聚集在一起,并以某种特定的方式进行排列和引用,这通常很有用。这些数据结构称为数组(array),正式的定义是有索引的数据值集合。每个数组索引(也称为键(key))引用一个对应的值。索引可以是一个简单的数,指示某个值在系列中的位置;也可以与值有某种直接关联。例如,如果要创建美国各州的列表,可以使用数字索引的数组,如下:

如果项目要求将美国各州与其州府关联,该怎么做呢?这时就不用数字索引作为键,而是使用关联索引,如下:

第5章将对数组概念做正式的介绍,所以,即使现在还没有完全理解这些概念,也不要过于担心。只要记住,PHP语言的确支持数组数据类型。
注解   PHP还支持包含多维的数组,这称为多维数组(multidimensional array)。第5章将介绍有关概念。

2. 对象
PHP支持的另一种复合数据类型是对象。对象是面向对象程序设计范型的核心概念。如果你才刚刚接触面向对象程序设计,也不要担心,因为第6章和第7章将专门全面地介绍面向对象概念。
与PHP语言包含的其他数据类型不同,对象必须显式地进行声明。声明对象属性和行为在类(class)中进行。下面是类声明和相应对象实例化的一个普通的例子:


类定义创建了一些与数据结构相关的属性和函数,这里的数据结构名为appliance。根据以上声明,appliance不具备什么功能。它只有一个属性power。这个属性可以使用方法setPower()进行修改。
但是请记住,类定义是一个模板,本身无法进行操作,而是要基于此模板创建对象。这是通过new关键字实现的。因此,在上面代码的最后一行,创建了类appliance的一个对象,名为blender。
这样就可以使用方法setPower()来设置blender对象的power属性:

改进PHP的面向对象开发模型是PHP 5的重点。第6章和第7章主要介绍这个重要特性。
3.4.3 特殊数据类型
特殊数据类型包括那些提供某种特殊用途的类型,因此无法归入其他任何类别。这包含资源(resource)和空(null)数据类型。
1. 资源
PHP通常用于与一些外部数据源交互,如数据库、文件和网络流。通常,这种交互通过句柄(handle)完成,成功地连接资源时会对句柄命名。这些句柄将保持对资源的引用,直到通信结束,此时将撤销句柄。这些句柄就属于资源数据类型。
并非所有函数都返回资源;只是在PHP脚本中负责将资源绑定到变量的函数才会返回资源。这种函数包括fopen()、mysql_connect()和pdf_new()。例如,下例中,$link就是一个资源类型的变量:

资源类型的变量并不真正保存一个值;实际上只保存一个指针,指向所打开的资源连接。事实上,如果输出其内容,将看到一个资源ID号引用。
2. null
null(空)就表示“无”,这一直都是令程序员新手困惑的概念。null不表示空格,也不表示零;它表示没有值,“什么也没有”。PHP中,如果满足下列情况,则认为一个值为null:
  ● 没有设置为任何预定义的值。
  ● 明确地赋值为null。
  ● 使用函数unset()清除。
null数据类型只有一个值Null:

3.4.4 类型强制转换
将一个变量强制转换为与原类型不同的另一种类型,称为类型强制转换(type casting)。将变量强制转换为另一种类型,就能作为其他类型来计算。为此,可以在变量前面加上要转换的类型。在变量前插入表3-2所列的转换操作符就可以强制转换类型。

表3-2 类型转换操作符

转换操作符

转换为

(array)
数组
(bool) 或 (boolean)
布尔值
(int) 或 (integer)
整数
(object)
对象
(real) 或 (double) 或 (float)
浮点数
  (string)
字符串

考虑以下的例子。假设要将一个整数转换为双精度数:

虽然$variable1最初保存的是整数值13,但双精度转换可以临时将类型转换为双精度类型(即13变为13.0),然后将这个值赋给$variable2。
现在考虑相反的情况。将双精度类型转换为整数类型时,会有出人意料的影响:

双精度数的小数部分被截断。注意,无论小数值是多少,双精度数每次都会向下取整。
还可以将数据类型强制转换为数组的一个成员。所转换的值将成为数组的第一个成员:

注意,不能把这作为向数组中增加项的标准方式,因为这只适用于新创建数组的第一个成员。如果转换到一个已经存在的数组,原数组将被清空,只是在第1个位置上保留新转换的值。
如果将字符串数据类型转换为整型会发生什么呢?让我们看一下:

这没什么实际意义。反过来,将整数转换为字符串会怎么样?由于PHP的松散类型设计,这样就会返回整数值而不做任何修改。但是,在下一节将看到,PHP有时会根据特定情况主动转换为最合适的类型。
最后再举一个例子:任何数据类型都可以转换为对象。结果是,该变量成为了对象的一个属性,该属性名为scalar:

然后可以如下引用这个值:

3.4.5 类型自动转换
因为PHP对于类型的定义非常松散,所以有时会根据引用变量的环境,将变量自动转换为最适合的类型。考虑下面的代码:

结果不所出料:$total赋值为20,为此,已经将$count变量从字符串转换为整数类型。下面来看另一个例子:

因为最前面的$total字符串以整数值开头,所以计算中就使用了这个值。但是,如果它以数值的内容开头,则值为0。再考虑一个例子:

在这个例子中,为了计算if语句的值,字符串被转换为布尔类型。在PHP编程中,这确实是一个常用的做法,你不仅会经常看到,而且在优化代码时也很有用。
考虑最后一个特别有趣的例子。如果数学计算中用到包含.、e或E的字符串,这个字符串将作为浮点数进行计算:

3.4.6 与类型有关的函数
有些函数可以用于验证数据类型或者完成类型转换,这一节就要介绍这些函数。
1. settype()

settype()函数将var指定的变量转换为type指定的类型。type有7个可取值:array、boolean、float、integer、null、object和string。如果转换成功,则返回TRUE;否则,返回FALSE。
2. gettype()

getype()函数返回var所指定变量的类型。共有8个可能的值:array、boolean、float、integer、null、object、unknow和string。
3.4.7 类型标识符函数
可以用很多函数来确定变量的类型,包括is_array()、is_bool()、is_float()、is_integer()、is_null()、is_numeric()、is_object()、is_resource()、is_scalar()和is_string()。因为所有这些函数都有相同的命名约定、参数和返回值,所以下面将它们合并为一个一般形式来加以介绍。
is_name()

所有这些函数都可以归为一组,因为它们最终完成的是相同的任务。各函数都是确定var所指定的变量是否满足函数名所指定的特定条件。如果var属于该类型,就返回TRUE;否则就返回FALSE。下面是一个例子:

此代码返回如下内容:


注意,在结果为false的情况下,没有返回值。你可能会考虑为什么$item前面有一个反斜杠。由于美元符有一个特殊作用,一般用于标识变量,所以必须有一种方法告诉解释器,将这里的美元符视为要输出到屏幕的正常字符。在美元符前加上反斜杠就可以做到这一点。
网络无限,生活无限

TOP

当前章节:3.5 标识符

3.5 标识符
标识符(identifier)是适用于变量、函数和其他各种用户定义对象的一般术语。PHP标识符必须满足以下性质:
  ● 标识符可以由一个或多个字符组成,必须以字母或下划线开头。此外,标识符只能由字母、数字、下划线字符和从127到255的其他ASCII字符组成。以下是几个例子:

合    法

非    法

my_function
This&that
Size
!counter
_someword
4ward

  ● 标识符区分大小写。因此,变量$recipe不同于变量$Recipe、$rEciPe或$recipE。
  ● 标识符可以是任意长度。这很有好处,因为这样一来,程序员就能通过标识符名准确地描述标识符的用途。
  ● 标识符名不能与任何PHP预定义关键字相同。在PHP手册的附录中可以看到所有预定义关键字的完整列表。
网络无限,生活无限

TOP

当前章节:3.6 变量

3.6 变量
虽然这一章的很多例子中已经使用了变量,但我们还没有正式地介绍变量的概念。这一节就要介绍变量的概念,首先给出变量的定义。简言之,变量(variable)是可以在不同时刻存储不同值的符号。例如,假设你创建一个基于Web的计算器,它能完成数学任务。当然,用户希望输入他选择的值;因此,程序必须能够动态地存储这些值,并完成相应的计算。同时,程序员需要在应用程序中以用户友好的方式来引用保存这些值的地方。这两个任务变量都能完成。
由于这种编程概念相当重要,因此有必要指出声明和处理变量的基本规则。本节将详细地讨论这些规则。
注解   变量是命名的内存位置,其中包含有数据,可以在程序执行期间进行处理。

3.6.1 变量声明
变量总是以美元符$开头,然后是变量名。变量名遵循标识符的命名规则,即变量名可以以字母或下划线开头,要由字母、下划线、数字或从127~255的其他ASCII字符组成。下面是合法的变量:

注意变量是区分大小写的。例如,下列变量之间没有任何关系:

有趣的是,PHP中不需要显式声明变量,这与Perl中不同。相反,变量声明可以与赋值同时进行。但是,可以这样做并不意味着就应当这样做。好的编程实践是:所有变量都应当在使用前进行声明,最好带有注释。
声明变量之后,就可以为其赋值。变量赋值有两种方法:值赋值和引用赋值。下面将介绍这两种方法。
1. 值赋值
按值赋值就是将赋值表达式的值复制到变量。这是最常见的一类赋值。下面是几个例子:

记住,每个变量都拥有表达式赋给它的一个副本。例如,$number和$age都有自己唯一的值12的副本。如果希望两个变量指向一个值的同一个副本,则需要通过引用赋值,下面就将介绍引用赋值。
2. 引用赋值
PHP 4引入了引用赋值的功能,这说明,所创建的变量与另一个变量引用的内容相同。因此,如果多个变量引用了同一个内容,修改其中任意一个变量,在其余的变量上都将有所反映。在等于号后面加一个&符号就可以完成引用赋值。考虑一个例子:

PHP还支持另一种引用赋值语法,即将&符号放在所引用变量的前面。下面是这种语法的一个例子:

引用对于函数参数和返回值也有重要的作用,另外,在面向对象程序设计中同样意义重大。第4章和第6章将分别介绍这些特性。
3.6.2 变量作用域
无论怎样声明变量(按值或按引用),总之在PHP脚本的任何位置都可以声明变量。但是,声明的位置会大大影响访问变量的范围。这个可访问的范围称为作用域(scope)。
PHP变量有4种作用域:
  ● 局部变量;
  ● 函数参数;
  ● 全局变量;
  ● 静态变量。
1. 局部变量
在函数中声明的变量认为是局部变量,即它只能在该函数中引用。如果在函数外赋值,将被认为是完全不同的另一个变量(即不同于函数中所包含的那个变量)。注意,退出声明变量的函数时,该变量及相应的值就会撤销。
局部变量很有用,因为它消除了出现意外副作用的可能性,否则,这些副作用将导致可全局访问的变量被有意或无意地修改。考虑如下代码:

代码的执行结果为:

可以看到,这里输出了两个不同的$x值。这是因为assignx()函数内的$x是局部变量。修改局部$x的值不会对函数外部的任何值产生影响。同样地,修改函数外部的$x也不会对assignx()内的任何变量有影响。
2. 函数参数
PHP与其他很多编程语言一样,任何接受参数的函数都必须在函数首部中声明这些参数。虽然这些参数接受函数外部的值,但退出函数后就无法再访问这些参数。
注解   本节只适用于按值传递的参数,而不是按引用传递的参数。按引用传递的参数会受到函数内部修改的影响。如果你还不理解这句话,不要担心,因为第4章将详细介绍这些内容。

函数参数在函数名后面的括号内声明。它们的声明方式与一般的变量很相似:

记住,虽然在声明参数的函数内部可以访问和处理这些函数参数,但当函数执行结束时,参数就会撤销。
3. 全局变量
与局部变量相反,全局变量可以在程序的任何地方访问。但是,为了修改一个全局变量,必须在要修改该变量的函数中将其显式地声明为全局变量。这很容易做到,只要在变量前面加上关键字GLOBAL,这样就可以将其识别为全局变量。如果将GLOBAL关键字放在一个已有的变量前面,则是告诉PHP要使用同名的变量。考虑一个例子:

$somevar的值显示为16。但是,如果省略下面这行代码:

变量$somevar将赋值为1,因为$somevar在addit()函数中被认为是一个局部变量。这个局部声明将隐含地设置为0,然后是1,最后显示的值就是1。
声明全局变量的另一种方法是使用PHP的$GLOBALS数组,下一节将正式介绍有关内容。考虑前面的例子,可以使用$GLOBALS数组将变量$somevar声明为全局变量:

返回值如下:


无论选择何种方法将变量转换为全局作用域,都要当心。全局作用域一直以来都是困扰程序员的一个问题,因为草率使用会引发意外的结果。因此,虽然全局变量非常有用,但使用时一定要谨慎。
4. 静态变量
我们讨论的最后一种变量作用域称为静态(static)作用域。函数参数在函数退出时会撤销,与声明为函数参数的变量不同,静态变量在函数退出时不会丢失值,并且再次调用此函数时还能保留这个值。在变量名前面加上关键字STATIC就可以声明一个静态变量:

考虑一个例子:

这个脚本的输出会是什么?如果变量$count没有指明为静态(相应地,$count就是一个局部变量),输出将会如下所示:


但是,因为$count是静态的,它会在每次执行函数时保留前面的值。所以输出如下:


静态作用域对于递归函数很有用。递归函数(recursive function)是一个功能强大的编程概念,它是一个可以重复调用自身的函数,直到满足某个条件为止。递归函数将在第4章详细介绍。
3.6.3 PHP的超级全局变量
PHP提供了很多有用的预定义变量,可以在执行脚本的任何位置访问,用于提供大量与环境有关的信息。可以通过这些变量获得关于当前用户会话、用户操作环境和本地操作环境等详细信息。PHP会创建部分变量,而其他许多变量的可用性和值则取决于操作系统和Web服务器。因此,下面的代码并没有试图收集所有预定义变量及其值的完整列表,而只是输出了与给定Web服务器和脚本执行环境有关的所有预定义变量:

它返回的变量如下所示。在Windows服务器上执行这段代码,花点时间研究一下所生成的变量列表。在后面的例子中还会看到其中一些变量。





可以看到,在此可以得到很多信息,有些信息很有用,有些则不太有用。可以将其中一个变量当作常规的变量进行显示。例如,显示用户的IP地址:

这会返回一个数字型的IP地址,如192.0.34.166。
还可以获得关于用户浏览器和操作系统的信息。考虑以下代码:

这会返回如下的信息:


PHP有9个预定义的变量数组,这个例子只展示了其中的一个。本节剩下的部分将主要介绍每个数组的作用和内容。
注解    要使用预定义变量数组,必须在php.ini文件中启用配置参数track_vars。在PHP 4.03中,track_vars总是启用的。

1. $_SERVER
$_SERVER超级全局变量包含由Web服务器创建的信息,它提供了服务器和客户配置及当前请求环境的有关信息。根据服务器不同,$_SERVER中的变量值和变量个数会有差别,不过一般都可以找到CGI 1.1规范(可以从美国国家超级计算应用中心(http://hoohoo.ncsa.uiuc.edu/ cgi/env.html)得到)中定义的变量。你会发现,这些变量在应用程序中都非常有用,其中包括:
  ● $_SERVER['HTTP_REFERER']:引导用户到达当前位置的页面的URL。
  ● $_SERVER['REMOTE_ADDR']:客户IP地址。
  ● $_SERVER['REQUEST_URI']:URL的路径部分。例如,如果URL是http://www. example.com/blog/apache/index.html,那么URI就是/blog/apache/index.html。
  ● $_SERVER['HTTP_USER_AGENT']:客户的用户代理,一般会提供操作系统和浏览器的有关信息。
2. $_GET
$_GET超级全局变量包含使用GET方法传递的参数的有关信息。如果请求URL http://www.example.com/index.html?cat=apache&amp;id=157,就可以使用$_GET超级全局变量访问如下变量:

默认情况下,要访问通过GET方法传递的变量,$_GET超级全局变量是唯一的途径。不能用$cat、$id等方式来引用GET变量。之所以推荐使用这种方式访问GET信息,原因将在第21章解释。
3. $_POST
$_POST超级全局变量包含用POST方法传递的参数的有关信息。考虑如下用于请求用户信息的表单:

通过目标脚本subscribe.php,就可以使用下面的POST变量:

与$_GET一样,在默认情况下,$_POST超级全局变量是访问POST变量的唯一方式。不能用$email、$pswd、$subscribe等方式引用POST变量。
4. $_COOKIE
$_COOKIE超级全局变量存储了通过HTTP cookie传递到脚本的信息。这些cookie一般是由以前执行的PHP脚本通过PHP函数setcookie()设置的。例如,假设使用setcookie()存储了一个名为example.com、值为ab2213的cookie。以后就可以通过调用$_COOKIE["example.com"]来获得这个值。第18章将详细介绍PHP的cookie处理功能。
5. $_FILES
$_FILES超级全局变量包含通过POST方法向服务器上传的数据的有关信息。这个超级全局变量与其他的变量略有不同,它是一个二维数组,包含5个元素。第一个下标表示表单的文件上传元素名;第二个下标是五个预定义下标之一,这些下标描述了上传文件的某个属性:
  ● $_FILES['upload-name']['name']:从客户端向服务器上传文件的文件名。
  ● $_FILES['upload-name']['type']:上传文件的MIME类型。这个变量是否赋值取决于浏览器的功能。
  ● $_FILES['upload-name']['size']:上传文件的大小(以字节为单位)。
  ● $_FILES['upload-name']['tmp_name']:上传之后,将此文件移到最终位置之前赋予的临时名。
  ● $_FILES['upload-name']['error']:上传状态码。尽管这个变量名为error,但实际上在成功的情况下也会填写这个变量。它有五个可能的值:
n   UPLOAD_ERR_OK:文件成功上传。
n   UPLOAD_ERR_INI_SIZE:文件大小超出了upload_max_filesize指令所指定的最大值。
n   UPLOAD_ERR_FORM_SIZE:文件大小超出了MAX_FILE_SIZE隐藏表单域参数(可选)指定的最大值。
n   UPLOAD_ERR_PARTIAL:文件只上传了一部分。
n   UPLOAD_ERR_NO_FILE:上传表单中没有指定文件。
第15章将全面介绍PHP的文件上传功能。
6. $_ENV
$_ENV超级全局变量提供PHP解析器所在服务器环境的有关信息。此数组中的变量包括:
  ● $_ENV['HOSTNAME']:服务器主机名。
  ● $_ENV['SHELL']:系统shell。
7. $_REQUEST
$_REQUEST超级全局变量是个“全能选手”,它记录了通过各种输入方法传递给脚本的变量,特别是GET、POST和cookie。这些变量的顺序不依赖于它们在发送脚本中出现的顺序,而是依赖于variables_order配置指令所指定的顺序。虽然它很诱人,但不要用这个超级全局变量处理变量,因为它不安全,原因请参考第21章。
8. $_SESSION
$_SESSION超级全局变量包含与所有会话变量有关的信息。注册会话信息能为你提供便利,这样就能在整个网站中引用这些会话信息,而无需通过GET或POST显式地传递数据。第18章将主要介绍PHP强大的会话处理功能。
9. $GLOBALS
$GLOBALS超级全局变量数组可以认为是超级全局变量的超集,包含全局作用域内的所有变量。执行下面的代码可以查看$GLOBALS中的所有变量:

3.6.4 变量的变量
有时候,你可能希望使用这样一个变量,它的内容本身可以动态地视为变量。考虑一个典型的变量赋值:

有趣的是,接下来可以在原变量名前面再加一个美元符,这就会将其值spaghetti作为一个变量,可以再为它赋另一个值:

其作用是把& meatballs赋给名为spaghetti的变量。
因此,下面两行代码将得到相同的结果:

两个结果都是字符串spaghetti & meatballs。
网络无限,生活无限

TOP

当前章节:3.7 常量

3.7 常量
常量(constant)是指在程序执行中无法修改的值。当处理绝对不需要修改的值时,常量非常有用,例如p(3.141592)或一英里相当于多少英尺(5 280)。常量一旦定义,就无法在程序其他地方修改(或重新定义)。常量使用define()函数定义。
define()

define()函数定义一个由name指定的常量,赋值为value。如果使用可选参数case- insensitive,并且这个参数值为TRUE,那么后面对此常量的引用将不区分大小写。考虑下面的例子,其中定义了数学常量PI:

下面的代码使用了这个常量:

此代码生成如下结果:


关于前面的代码有几点需要注意。首先,常量引用前面不需要使用美元符。其次,一旦定义常量,就不能重新定义或取消已定义的常量(例如2*PI);如果需要根据常量生成一个值,这个值必须存储在另一个变量中。最后,常量是全局的,可以在脚本的任何位置引用。
网络无限,生活无限

TOP

当前章节:3.8 表达式

3.8 表达式
表达式(expression)是一个短语,它表示程序中的某个特定动作。所有表达式至少由一个操作数和一个或多个操作符组成。下面是几个例子:

3.8.1 操作数
操作数是表达式的输入。通过每天的数学计算,以及前面的编程经验,你可能对操作数的处理和使用早已经熟悉。下面是操作数的一些例子:

3.8.2 操作符
操作符(operator)是表达式中指定某个动作的符号。许多操作符对你来说可能已经很熟悉了。无论如何,要记住PHP会根据操作符(置于两个操作数之间)的类型自动进行类型转换,这在其他编程语言中并不多见。
操作符的优先级和结合性是编程语言的重要特性。本节将介绍这两个概念。表3-3包含了所有操作符的完整列表,这里操作符按照优先级从高到低的顺序排列。

表3-3 操作符优先级、结合性和作用

操作符

结合性

作    用

new

对象初始化
()

建立表达式的子组
[]

包围索引
! ~ ++ --

布尔非,按位取反,自增,自减
@

错误控制
/ * %

除法,乘法,取模
+ - .

加法,减法,拼接
<< >>

左移,右移
< <= > >=

小于,小于等于,大于,大于等于
== != === <>

等于,不等于,相同,不相同
& ^ |

位与,位异或,位或
&& ||

布尔与,布尔或
?:

三元操作符
= += *= /= .= %=&=
|= ^= <<= >>=

赋值操作符
AND XOR OR

布尔与,布尔异或,布尔或
,

分隔表达式,例子:
$days = array(1=>"Monday", 2=>"Tuesday")

1. 操作符优先级
操作符优先级(operator precedence)是操作符的一个特性,确定以何种顺序计算周围的操作数。PHP遵循小学算术课所用的标准优先级规则。下面是几个例子:

可以等价地写为:

因为乘法操作符的优先级比加法操作符的高。
2. 操作符结合性
操作符的结合性(associativity)指定了相同优先级运算(即有相同的优先级值,如表3-3所示)的计算顺序。结合性可以有两个方向,从左到右或从右到左。从左到右结合性表示组成表达式的各种运算从左向右进行计算。考虑如下例子:

这个例子与下例相同:

这个表达式结果为840,因为乘法(*)操作符的结合性是从左至右。
相反,从右到左结合性将从右到左地计算相同优先级的操作符:

上面的示例与下例相同:

计算这个表达式时,变量$value、$a、$b和$c都将包含值5,因为赋值操作符(=)的结合性是从右到左。
3. 算术操作符
算术操作符如表3-4所列,用于完成各种算术运算,在许多PHP程序中将会频繁用到。幸运的是,这些算术操作符很容易使用。

表3-4 算术操作符

示    例

说    明

输    出

$a + $b
加法
$a和$b的和
$a - $b
减法
$a和$b的差
$a * $b
乘法
$a和$b的乘积
$a / $b
除法
$a和$b的商
$a % $b
取模
$a除以$b的余数

顺便提一下,PHP提供了大量预定义的数学函数,能够完成基本的转换和计算对数、平方根和几何值等运算。这些函数的最新列表请查看手册。
4. 赋值操作符
赋值操作符(assignment operator)将一个数据值赋给一个变量。最简单的赋值操作符会赋某个值,有些操作符(称为快捷赋值操作符)在赋值之前会完成另外某个运算。表3-5列出了一些使用此类操作符的例子。

表3-5 赋值操作符

示    例

说    明

输    出

$a = 5
赋值
$a等于5
$a += 5
加法赋值
$a等于$a减5
$a *= 5
乘法赋值
$a等于$a乘以5
$a /= 5
除法赋值
$a等于$a除以5
$a .= 5
拼接赋值
$a等于$a拼接5

5. 字符串操作符
PHP的字符串操作符(参见表3-6)提供了拼接字符串的便捷方式。有两个这样的操作符,包括拼接操作符(.)和拼接赋值操作符(.=),这在上一节已经讨论过。

表3-6 字符串操作符

示    例

说    明

输    出

$a = "abc"."def";
拼接
$a赋值为字符串“abcdef”
$a .= "ghijkl";
拼接赋值
$a等于它的当前值与“ghijkl”的拼接结果

注解   拼接(concatenate)表示将两个或多个对象组合起来,形成一个实体。

下面是一个使用字符串操作符的例子:

PHP的字符串处理功能并非只包括这两个拼接操作符。有关功能请参阅第9章。
6. 自增和自减操作符
自增(++)和自减(--)操作符如表3-7所列,为代码的简洁性提供了一些便利。这是一种简化的方式,可以将变量的当前值增1或减1。

表3-7 自增和自减操作符

示    例

说    明

输    出

++$a, $a++
自增
$a增1
--$a, $a--
自减
$a减1

这些操作符可以放在变量的任意一边,但放的位置不同会有一些略微不同的效果。考虑以下示例的输出:

可以看出,自增和自减操作符使用的顺序对变量的值有重要影响。将操作数放在操作符前面称为前自增和前自减运算,而放在后面则称为后自增和后自减运算。
7. 逻辑操作符
与算术操作符类似,逻辑操作符(参见表3-8)在许多PHP应用程序中都起到重要作用,利用逻辑操作符可以根据多个变量的值进行判断,这使得控制程序的流程成为可能。逻辑操作符常用于控制结构中,如if条件和while及for循环。

表3-8 逻辑操作符

示    例

说    明

输    出

$a && $b

如果$a和$b都为true,则输出true
$a AND $b

如果$a和$b都为true,则输出true
$a || $b

如果$a或$b为true,则输出true
$a OR $b

如果$a或$b为true,则输出true
!$a

如果$a不为true,则输出true
NOT $a

如果$a不为true,则输出true
$a XOR $b
异或
如果只有$a或$b为true,则输出true

逻辑操作符还常用于提供其他运算结果的详细信息,尤其是有返回值的运算:

会有两种输出:
  ● 文件filename.txt存在。
  ● 输出句子“File does not exist!”。
8. 相等操作符
相等操作符(参见表3-9)用来比较两个值,测试其相等性。

表3-9 相等操作符

示    例

说    明

输    出

$a == $b
是否相等
如果$a和$b相等,则输出true
$a != $b
是否不相等
如果$a和$b不相等,则输出true
$a === $b
是否相同
如果$a和$b相等,并且类型也相同,则输出true

只用一个等号测试相等性(例如$a = $b)是个很常见的错误,即使是有经验的程序员也常犯这个错误。记住,这会变成将$b的值赋给$a,而不会得到预期的结果。
9. 比较操作符
比较操作符(参见表3-10)与逻辑操作符相似,通过比较两个或多个变量值的结果,提供了一种控制程序流程的方法。

表3-10 比较操作符

示    例

说    明

输    出

$a < $b
小于
如果$a小于$b,则输出true
$a > $b
大于
如果$a大于$b,则输出true
$a <= $b
小于或等于
如果$a小于或等于$b,则输出true

(续)

示    例

说    明

输    出

$a >= $b
大于或等于
如果$a大于或等于$b,则输出true
($a == 12) ? 5 : -1
三元运算
如果$a等于12,返回值为5;否则返回值为-1

注意,比较操作符只能用来比较数值。虽然也可以使用这些操作符比较字符串,但很可能得不到预期的结果。要比较字符串值,还有另外一组预定义的函数,有关内容将在第9章详细讨论。
10. 位操作符
位操作符(bitwise operator)在组成整数值的各个“位”层次上检查和处理整数值(这正是位操作符名字的由来)。为了充分理解这个概念,需要至少对十进制数的二进制表示有一些基本了解。表3-11列出了一些十进制数及其相应的二进制表示形式。

表3-11 二进制表示形式

十进制整数

二进制表示形式

2
10
5
101
10
1010
12
1100
145
10010001
1 452 012
101100010011111101100

表3-12所列的位操作符是逻辑操作符的一些变体,但会得到完全不同的结果。

表3-12 位操作符

示    例

说    明

输    出

$a & $b

$a和$b包含的每一位相与
$a | $b

$a或$b包含的每一位相或
$a ^ $b
异或
$a或$b包含的每一位相异或
~ $b

$b中的每一位取反
$a << $b
左移
$a将接收到$b左移两位的值
$a >> $b
右移
$a将接收到$b右移两位的值

如果希望学习关于二进制编码和位操作符的更多知识,了解其重要性,请访问Randall Hyde提供的在线参考:The Art of Assembly Language Programming(汇编语言编程艺术),位于http://webster.cs.ucr.edu/。这是Web上的最棒的资源之一。
网络无限,生活无限

TOP

当前章节:3.9 字符串插入

3.9 字符串插入
为了给开发人员处理字符串值提供最大的灵活性,PHP为字面插入和内容插入提供了一种办法。考虑下面的字符串:

你可能会认为$animal是变量,而\n是换行符,因此,它们应当进行相应的解释。但是,如果你希望原样输出所写的字符串,或者希望生成换行符,但变量要以字面形式($animal)输出,或者反之,$animal要作为变量解释,而\n要原样输出,该怎么做呢?这些情况在PHP中都是可能的,具体取决于字符串如何界定,以及是否通过预定义序列对某些关键字符进行转义。本节将讨论这些问题。
3.9.1 双引号
用双引号括起的字符串在PHP脚本中最为常见,因为它们提供了最大的灵活性,其原因是变量和转义序列都会得到相应的解析。考虑如下例子:

这个例子会返回:


转义序列也会得到解析。考虑下面这个例子:

它将在浏览器源代码中返回如下内容:


重申一下,这个输出出现在浏览器源代码中,而不是出现在浏览器窗口中。这种换行符会被浏览器窗口忽略。但是,如果查看源代码,将看到确实会分两行输出。如果数据输出到文本文件中,结果也是一样(即分两行输出)。
除了换行符,PHP还能识别很多特殊的转义序列,如表3-13所示。

表3-13 可识别的转义序列

转义序列

描    述

\n
换行符
\r
回车
\t
水平制表符
\\
反斜杠
\$
美元符
\"
双引号
\[0-7]{1,3}
八进制记法
\x[0-9A-Fa-f]{1,2}
十六进制记法

3.9.2 单引号
当字符串应当按照声明形式的原样解释时,可以用单引号括起这个字符串。这表示,解析字符串时,变量和转义序列都不会进行解析。例如,考虑下面的单引号字符串:

这会生成:


记住,“it’s”中的单引号进行了转义。忽略反斜杠转义字符将导致语法错误,除非启用magic_quotes_gpc配置指令。再来看一个例子:

这会生成:

此例中,在字符串最后出现的反斜杠必须转义,否则,PHP解析器会理解为最后一个单引号将被转义。但是,如果反斜杠出现在字符串的其他位置,就不需要转义。
3.9.3 Heredoc
Heredoc语法为输出大量文本提供了一种便利的方式。它不是使用双引号或单引号来界定字符串,而是采用了两个相同的标识符。下面是一个例子:

关于这个例子,有几个值得注意的地方:
  ● 开始和结束标识符必须相同,此示例中的开始和结束标识符是EXCERPT。可以选择你喜欢的任何开始和结束标识符,但要求它们必须完全相同。唯一的限制是该标识符必须完全由字母数字字符和下划线组成,而且不能以数字或下划线开头。
  ● 开始标识符前面必须有三个左尖括号:<<<。
  ● Heredoc语法与双引号界定的字符串遵循相同的解析规则。即,变量和转义序列都将得到解析。唯一的区别是,此处的双引号不需要转义。
  ● 结束标识符必须在一行开始处,而且前面不能有空格或任何其他多余的字符。这通常会使用户混淆,所以,要当心确保你的heredoc字符串符合这个烦人的要求。此外,开始或结束标识符后面的任何空格都会导致语法错误。
如果需要处理大量内容,又不希望使用转义引号,此时Heredoc语法尤其有用。
网络无限,生活无限

TOP

当前章节:3.10 控制结构

3.10 控制结构
控制结构(control structure)确定了应用程序中的代码流程,定义了一些执行特性,例如某条语句是否多次执行,执行多少次,以及某个代码块何时交出执行控制权。这些结构还提供一种简单的方法,可以在当前执行脚本中引入全新的代码段(通过文件包含语句)。这一节将介绍PHP语言可用的各种控制结构。
3.10.1 执行控制语句
return和declare语句分别能很好地控制一个代码块何时开始和何时结束。
1. declare()

declare()语句用于指定代码块的执行频度。当前支持的指令(directive)只有一个:tick。PHP将tick定义为一个事件,这种事件在PHP解析器执行一些低级语句时发生。tick可以用于对代码做基准测试和调试、完成简单的多任务处理或者是需要控制低级语句执行的其他任务。
这个事件在函数中定义,可通过register_tick_function()函数注册为一个tick事件。以后可以通过unregister_tick_function()函数取消该事件的注册。下面将介绍这两个函数。事件频度通过相应地设置declare函数的指令来指定,例如ticks=N,这里N是该事件调用之间发生的低级语句的数目。
l   register_tick_function()

register_tick_function()将function指定的函数注册为tick事件。
l   unregister_tick_function()

unregister_tick_function()取消以前注册的由function指定的函数。
2. return()
return()语句通常在函数体内使用,向函数调用者返回输出。如果在全局作用域内调用return(),脚本将立即结束执行。如果在使用include()或require()所包含的脚本中调用return(),控制权将返回到文件调用者。可以把参数包围在括号里,不过这是可选的。下面是一个例子:

调用此函数将向调用者返回下面的结果:


3.10.2 条件语句
条件语句使程序可以根据各种输入做出响应,基于输入值使用逻辑来辨别各种不同的条件。这对于开发计算机软件相当基本,所以,各种主流编程语言都包括大量条件语句,PHP也不例外。
1. if
if条件是所有主流编程语言中最常见的结构,为条件代码的执行提供了一种便利的方法。其语法为:

考虑一个例子,假设在用户猜对预先确定的秘密数字后要确保显示一条祝贺消息:

条件体只包含一条语句时,如果你很懒,可以不使用大括号。下面是前例的另一种形式:

注解   对于if、while、for、foreach和switch控制结构,还有另外一种语法。它将前大括号改为冒号(:),将后大括号分别改为endif;、endwhile;、endfor;、endforeach;和endswitch;。在可预见的将来这种方式仍然可用,但已经计划在未来的版本中废弃这种语法。

2. else
前面的示例有个问题,它的输出只能为猜对秘密数字的用户输出结果。所有其他用户都被忽略了,而且根本没有给出错误原因的相关提示。如果无论结果如何都要提供一个响应该怎么办?为此,需要一种办法来处理不满足if条件需求的情况,这正是else语句的功能。下面对前面的例子做了修改,为两种情况都提供了响应:

与if一样,如果只有一条代码语句,else语句的大括号可以省略。
3. elseif
if-else组合在“二选一”的情况下非常实用,即只可能有两种结果。如果有多种可能的结果怎么办?需要一种办法来考虑每一种可能的输出,这可以通过elseif语句实现。再次修改前面的秘密数字例子,这一次如果用户的猜测与秘密数字很接近(相差在10以内),则提供一个消息:

与所有条件一样,elseif在只包含一条语句时可以忽略大括号。
4. switch
可以把switch语句看作if-else组合的一种变体,如果需要比较有很多值的变量,通常会使用switch语句:

注意,在每个case块的末尾处都有break语句。如果没有break语句,就会执行所有后续的case块,直到遇到break语句为止。作为这种情况的一个例子,可以删除前例中的所有break语句,并将$category设置为weather。结果将如下:


3.10.3 循环语句
虽然形式可能有所不同,但所有流行编程语言中都必定有循环语句。这不奇怪,因为往往需要重复一段指令直到满足特定条件为止,这是程序中实现的一个常见任务,而循环机制为此提供了一种简单的方式。PHP提供了几种这样的循环机制,如果你熟悉其他编程语言,应该不会对此感到惊讶。
1. while
while语句指定了一个条件,在其嵌入代码结束执行前,必须满足这个条件。其语法是:

在下面的示例中,$count的初始值为1。然后求$count的平方,并输出。接下来$count变量加1,进行循环,直到$count的值到达5为止。

输出如下:


与所有其他控制结构一样,在while语句中可以嵌入多个条件表达式。例如,下面的while块将判断是否到达文件尾或读取并输出了5行:

对于上述条件,无论sports.txt文件的大小如何,最多只会输出sports.txt文件中的5行。
2. do...while
do...while循环条件是while的一种变体,它在代码块的结束处验证循环条件,而不是在开始处。其语法为:

while和do...while在功能上相似;唯一的区别在于while语句中的代码块可能永远不会被执行,而do...while语句中的代码块总是至少会执行一次。考虑如下例子:

输出是:


虽然11超出了while条件的限制,但内嵌的代码仍执行了一次,因为条件是在结束的时候判断的!
3. for
for语句提供了比while更复杂的循环机制。其语法为:

使用PHP的for循环,需要记住几点规则:
  ● 第一个表达式expression1在第一次循环迭代时自动计算。
  ● 第二个表达式expression2在每次迭代时进行计算。这个表达式确定是否继续循环。
  ● 第三个表达式expression3在每次循环结束时计算。
  ● 任何一个表达式都可以为空,它们可以由for块内部的逻辑所取代。
记住这些规则,考虑下面几个示例,它们都将显示一个公里/英里的对应表:


三个示例的结果都如下:


4. foreach
foreach循环结构语法最擅长循环处理数组,从数组中提取每个“键/值”对,直到获得所有项,或满足某些内部条件为止。它有两种语法形式,以下分别给出一个示例。第一种语法从数组中获取每个值,每次迭代都将指针后移(更接近数组末尾)。其语法是:

考虑一个例子。假设要输出一个由链接组成的数组:

结果将是:


第二种形式适合处理包含键和值的数组。语法如下:

修改前面的例子,假设$links数组包含链接和相应的链接标题:

数组中的每个元素都包含键和相应的值。foreach语句可以很容易地从数组中获取键/值对,如下:

结果是每个链接嵌入在相应的标题中,如下:


这种获取键/值的方法还有很多其他形式,第5章将对有关内容进行介绍。
5. break
如果包含一个break语句,将立即结束do...while、for、foreach、switch或while循环的执行。例如,下面的for循环在伪随机数是一个素数时结束:

下面是上例的输出:


6. continue
continue语句使当前循环迭代执行结束,并从下一次迭代开始执行。例如,如果$usernames[$x]中含有值"missing",下面的while体将重新开始:

结果输出如下:


3.10.4 文件包含语句
崇尚效率的程序员总是会从确保重用性和模块性的角度考虑。最普遍的方式是把功能组件隔离为单独的文件,然后在需要时重新组装。PHP提供了四种在应用程序中包含文件的语句,本节将分别介绍。
1. include()

include()语句将在其被调用的位置处包含一个文件。包含一个文件与在该语句所在位置复制指定文件的数据具有相同内容的结果。
与print和echo语句一样,使用include()时可以忽略括号。例如,假设希望包含一系列预定义的函数和配置变量,可以将这些函数和配置变量放在单独的文件中(例如,名为init.php),然后在每个PHP脚本顶部包含这个文件,如下:

还可以根据条件来执行include()语句。例如,假设一个include()语句放在if语句内,那么只有在if语句为真时才包含该文件。在条件语句中使用include()有个怪现象,它必须包围在语句块大括号中,或者用其他语句包围符括起。考虑下面两段代码中语法的不同。第一段是不正确的,因为它没有适当的块包围符。

第二段是正确的用法,在此将include()语句包围在大括号中:

关于include()语句有一个误解,以为由于所包含的代码会嵌入在PHP执行块中,所以不需要PHP转义标记。但是,事实并非如此;必须始终使用定界符。因此,不要指望只是将PHP命令放在一个文件中就能得到正确的解析,如下:

实际上,任何PHP语句都必须使用正确的转义标记包围,如下所示:

提示   所包含文件中的所有代码都会继承其调用者位置处的变量作用域。

有趣的是,只要为include()的参数提供了合法的URL,include()语句还能包含位于远程服务器的文件。如果文件所在的服务器支持PHP,通过传递必要的键/值对,可以像GET请求那样解析所包含文件中的变量,如下:

包含远程文件时必须满足两个条件。首先,allow_url_fopen配置指令必须启用。其次,必须支持URL包装器。第二个条件将在第16章详细讨论。
2. include_once()

include_once()函数的作用与include()相同,不过它会首先验证是否已经包含了该文件。如果已经包含,则不再执行include_once()。否则,则必须包含该文件。除了这一点区别,include_once与include()完全相同。
在条件语句中使用include_once()与include()一样有相同的怪现象。
3. require()

require()在很大程度与include()相同,都是将一个模板文件包含到require()调用所在的位置。
require()和include()之间有两点重要的区别。首先,无论require()的位置如何,指定文件都将包含到出现require()的脚本中。例如,即使require()放在计算为假的if语句中,依然会包含指定文件!
提示   只有启用allow_url_fopen时(这是默认值),才可以在require()中使用URL。

第二个重要的区别是:require()出错时,脚本将停止执行,而在使用include()的情况下,脚本将继续执行。一种可能的错误是require()语句不正确地引用了目标路径。
3.10.5 require_once()

随着网站越来越大,你会发现会重复地包含某些文件。这也许不是问题,但有时修改了所包含文件中的变量后,却由于后面再次包含原来的文件而被覆盖,你可能不希望出现这种情况。还可能出现另一个问题,即所包含文件中函数名的冲突。使用require_once()函数就可以解决这些问题。
require_once()函数确保文件只包含一次。在遇到require_once()后,后面再试图包含相同的文件时都将被忽略。
除了require_once()的验证过程外,其他方面都与require()相同。
网络无限,生活无限

TOP

发新话题