1.4 PHP语言基础
作为一种编程语言,PHP和大部分语言一样,都有着相同的一些语法规则,但也有一些属于PHP本身特有的语法。PHP的语法规定很多,可以用详细的一章来介绍,在这里,我们只简要介绍如下。
1.4.1 PHP基本语法
1. 注释
在PHP的程序中,加入注释的方法很灵活。可以使用C语言、C++语言或者是UNIX的Shell语言的注释方式,你可以使用块注释,单行注释,你也可以使用多行注释和文档注释,更方便的是,你也可以混合使用。
常用的注释符号有单行注释//用于注释一行;块注释符号/*和*/注释掉中间的多行语句。
2. 命名规则
在PHP命名中,遵循一定的命名规则,对于提高代码的可读性是非常重要的。
在给变量命名的时候,除了变量名外,所有实例,包括类,类常量,均采用大小写混合的方式,第一个单词的首字母小写,其后单词的首字母大写。尽管在语法上使用下画线或美元符号开头命名是允许的,但是,我们在实际应用中应该尽量避免这种命名方法。
变量名应简短且富于描述。变量名的选用应该易于记忆,即能够指出其用途。尽量避免单个字符的变量名,除非是一次性的临时变量。
3. 数据类型
PHP数据类型是具有相同特性的一组数据的统称。
PHP支持8种原始类型,其中标量类型4种,符合类型两种,特殊类型两种。常见的数据类型包括字符串型、整型、浮点型和布尔型。
(1) 布尔型(Boolean)类型最初出现在PHP4中,布尔型类型是表示条件是真(非0)还是假(0)的数据类型。
PHP的数据类型属于弱类型,PHP的变量在使用的时候可以根据具体情况自动转换成所需要的变量类型,布尔型的变量决定了条件语句的结果, 通常我们使用某些运算符返回Boolean值,并将其传递给控制流程。
(2) 字符串是由一系列的字符序列组成的。无论哪种语言,字符串操作都是一个重要的基础,往往是最简单的,但是却是最重要的。
(3) 整型是PHP中很常用的一个数据类型。它的取值范围是这样一个集合:Z={…-2,-1,0,1,2…},整型除作为必要的运算数据外,整型值还经常用于循环控制变量等处。
(4) 浮点型通常是指我们说的实数,它是用十进制数字表示数字值,它的取值范围取决于具体的机器,PHP浮点型与C编译器的双精度数据类型范围相同,通常允许的取值范围是1.7E-308和1.7E+308之间,精确到15位数字。
(5) 数组实际上是一个数据集合,相当于是一个数据容器,很多数据存放在里面,我们可以按一定方法存进去或取出来,还可以对它里面的数据进行排序等各种操作,还可以检查里面有没有我们想要的数据等。
4. 运算符和关键字
运算符是指可以通过给出的一个或多个值来产生另一个值的符号。
PHP提供三种类型的运算符。
第一种是一元运算符,只运算一个值,例如 !(取反运算符)或 ++(加一运算符)。
第二种是有限二元运算符,PHP支持的大多数运算符都是这种。
第三种是三元运算符:?:。它被用来根据一个表达式的不同取值而在另两个表达式中选择一个。
(1) 算术运算符
算术运算符如表1-3所示。
表1-3 PHP的算术运算符
(2) 字符串运算符
在PHP中,应用与字符串的运算符有两个:
第一个是连接运算符(“.”),它返回其左右参数连接后的字符串。
第二个是连接赋值运算符(“.=”),它将右边参数附加到左边的参数后。
(3) 赋值运算符
PHP基本的赋值运算符是“=”。它并不是“等于”的意思,而是把右边表达式的值赋给左边的变量。
(4) 比较运算符
比较运算符是用来比较两个值的操作符,比较运算符的表达式根据比较结果返回布尔型变量值:true或者false。比较运算符如表1-4所示。
表1-4 PHP的比较运算符
(5) 逻辑运算符
逻辑运算(logical operators)通常用来测试真值或假值的。逻辑运算符如表1-5所示。
表1-5 PHP的逻辑运算符
(6) 位运算符
位运算符可以将一个整型变量当做一系列的位来处理,在PHP中,位运算符可能并不经常使用。位运算符如表1-6所示。
表1-6 PHP的位运算符
(7) 自增与自减运算符
在PHP中自增与自减运算符表示为:++和--。自增与自减运算符如表1-7所示。
表1-7 PHP的自增与自减运算符
(8) 关键字
关键字(keyword)是语言为其核心功能而保留的单词。在对变量、函数、类和常量进行命名时,不能使用与关键字一样的名字,关键字是区分大小写的,如表1-8所示。
表1-8 PHP的保留关键字
5. 条件分支语句
条件语句是为能使应用程序在运行时根据不同的条件来执行不同的程序块而设置的,在PHP中,支持if和switch两种条件语句。
(1) if语句
在PHP中,if语句是最常用的条件语句之一,同时,if语句也是大多数程序开发语言中存在的条件语句。if条件语句的语法如下:
<?php if (表达式){ 语句块 }elseif (表达式){ 语句块 }elseif (表达式){ 语句块 ... }else{ 语句块 } ?>
if条件语句的表达式是一个返回值为布尔类型的表达式,如果表达式返回的值为true,那么在接下来的语句块将被执行,否则,程序将跳过下面的语句块,继续往下执行。在上述的if条件语句的语法中,我们可以加入else语句,当以前表达式的返回值都不为true时,else语句块中的语句将被执行。
(2)switch语句
switch语句是PHP中另外一种条件判断语句。Switch条件分支语句简化了使用if语句进行的多重嵌套判断。在编写条件比较复杂的程序时,如果使用较多的if语句,那么会使语句间的逻辑关系变得十分复杂,同时也会增加程序调试和维护的难度。switch语句提供了一个可读性更好的多重if嵌套的解决方案。
switch条件分支语句也称情况语句,其功能是从多个待选择符的条件中选择一个符合条件的语句,switch语句的基本语法如下:
<?php switch (条件表达式){ case 条件1: 语句块 break; case条件2: 语句块 ... break; default: 语句块 } ?>
6. 循环
PHP中的循环有for循环、while循环、do…while循环、foreach循环四种。
(1) for循环
for循环是经常能够使用到的循环语句,for循环可以确定循环的次数,在使用for循环的时候首先要为循环变量设置一个初始值和一个终值,循环变量可以是任意合法的表识符,循环变量的类型可以是整型、布尔型、字符类型等。
for循环的的基本语法如下:
<?php for(循环变量初始值;循环条件;计数器){ 循环体 } ?>
for循环的3个参数含义如下。
循环变量初始值:顾名思义,就是从for循环的哪个值开始循环。
循环条件:当满足什么条件时继续循环。
计数器:就是没执行完一次循环以后,对循环变量按怎么样的方式进行记数。
在使用for循环的时候应该注意以下几点。
① 循环体中的语句可以是简单语句也可以是符合语句。
② 循环变量必须是有序数据类型的变量。
③ 不允许任何语句在循环体中改变循环变量的值。
为了理解for循环的循环流程,我们使用下图来描述for循环的循环结构。
根据计数器的不同计数方式,我们可以将for循环分为递增循环和递减循环。
(2)while循环
while循环语句又称当行循环语句,即“当……是”循环执行循环体。该语句的执行过程是先判断while后的布尔表达式,然后再执行,while语句是当条件语句的表达式的值为true时,执行其中的循环体,直到条件表达式的值为false时才退出循环。
while循环的基本语法如下:
while(条件表达式){ 循环体 }
while循环的流程图如图1-26所示。
图1-25 for循环流程图
图1-26 while循环流程图
程序从条件表达式进入循环体语句,如果条件表达式的值为true,那么继续循环,直到条件表达式的值为false时退出循环。
(3)do…while循环
do…while循环也是PHP中经常用到的循环语句,该语句不同于while循环,while循环在执行循环体之前,先判断循环条件是不是成立,如果成立,则执行循环体,并且进行计数,如果循环条件不成立,则跳出循环,不执行循环体;而do…while循环语句则不同,do…while循环至少执行一次循环体,然后再判断循环条件是否成立,若循环条件成立,则返回继续执行循环体,否则,跳出循环。do…while循环语句的基本语法如下:
<?php do{ 循环体 }while(条件语句) ?>
它的循环结构我们可以用图1-27来表示。
图1-27 do…while循环结构
从do…while的循环结构可以看出,其循环条件放在循环体的后面来判断,也就是说, do…while循环先执行一次循环体,然后再判断循环条件是否成立来决定是否继续执行循环体。
(4)foreach循环
foreach循环结构是在PHP4中引入的,并且foreach循环只能用于循环访问数组的元素,自PHP5开始,foreach循环还可以遍历对象,本节只介绍它在数组循环中的使用方法。
在使用foreach循环遍历数组之前,必须先对要遍历的数组进行初始化,否则,PHP会产生错误。
foreach循环的的语法可以分为两种情况来写,第一种情况语法如下:
<?php foreach (array_expression as $value){ 循环体 } ?>
这种格式的语法将遍历给定的array_expression数组。在每次循环中,当前单元的值被赋给$value,并且数组内部的指针向前移一步,以便于在下次循环中能够取到下一个单元的数值。
foreach循环的第二种语法如下:
<?php foreach (array_expression as $key => $value){ 循环体 } ?>
这种语法与第一种相比,它将一个数组元素分解为$key和$value两个部分,$key是数组的索引,$value是这个索引的值,它们的名字可以随意。
(5)continue与break在循环中的应用
continue在循环结构中用来跳过本次循环中剩余的代码,并在判断条件值为真时开始执行下一次循环。 continue接受一个可选的数字参数来决定跳过几重循环到循环结尾,而break则直接跳出本循环,继续执行循环以外的程序。
1.4.2 字符串和正则表达式
1. 字符串
一个字母、一个数字、一个标点,这些组成丰富语言的基本元素,我们称之为一个“字符”,在以二进制模式工作的计算机中,每一个字符都用一个代码来表示,这种代码叫做ASCII码,如ASCII码65就代表大写字母A,美国国家标准学会(American National Standard Institute, ANSI)制定了可见和不可见(如:Enter、退格等控制字符)的共127字符。
零个或者多个字符组成的有限序列,也就是n(n≧0)个字符的集合,就叫做字符串。一个字符串,可以是我们看起来有意义的一个单词、一句话、一篇文章,也有可能是毫无意义的字符堆积。字符串最常用的功能是人机对话,告诉用户发生了什么,以及下一步需要做什么。
在书写上,字符串一般都写在成对的单引号或者双引号中。
一般来说,对字符串的操作有连接、分割成子串、求字符串长度、两个字符串比较、查找子串、替换字符串中间的部分子串等。
下面我们简要介绍一些常用的字符串操作函数。
函数语法:string chop ( string $str [, string $charlist] )。
函数作用:去除字符串尾部的空格等特殊字符,如果指定了第二个参数,则去除字符串尾部的第二个参数指定的字符。
函数语法:string ltrim ( string $str [, string $charlist] )。
函数作用:去除字符串头部的空格等特殊字符,如果指定了第二个参数,则去除字符串头部的第二个参数指定的字符。
函数语法:string trim ( string $str [, string $charlist] )。
函数作用:去除字符串头部和尾部的空格等特殊字符,如果指定了第二个参数,则去除字符串头部和尾部的第二个参数指定的字符。
函数语法:string addslashes ( string str )
函数作用:使用反斜线引用字符串。
stripslashes()函数和addslashes()相反,是把被addslashes()函数加上的转义符取消。
函数语法:string stripslashes ( string )
函数语法:string strtoupper ( string $string )
函数说明:将字符串string的字母全部以大写字母的形式返回。
函数语法:string strtolower ( string $string )
函数说明:将字符串string的字母全部以小写字母的形式返回。
函数语法:array explode ( string $separator, string $string [, int $limit] )
函数作用:将字符串$string用$separator来分割,每出现一次$separator,就多出一个两个$separator之间的字符组成的字符串元素,函数最后返回值是一个数组。如果使用了第三个参数$limit,则函数返回的数组最多包含$limit个元素,剩余未被分割的字符串作为最后一个元素。函数实际使用时,最常见的$separator是空格或者“||”、“,”。
函数语法:string implode ( string $glue, array $pieces )
函数作用:把数组的各元素合成成一个用$glue连接起来的字符串。
函数语法:string strtok ( string $str, string $token )
函数作用:字符串 $str用字符串 $token的值切开成小段小段的字符串,返回$token第一次出现前的部分子字符串,如果重复执行该函数,则不再需要$str参数,将依次返回后续的下一个$token出现前的部分子字符串。
函数语法:string substr ( string $string, int $start [, int $length] )
函数作用:取得字符串$string从$start开始的$length长度的子字符串,如果没有$length参数,则取到$string的最后一个字符。
$string字符串的各字符位置($start参数)从0开始;如果$start参数为负数,则从$string字符串倒数第$start个字符开始取得$length长度的子字符串。
如果$length参数为负数,则截取到$string字符串倒数第$length个字符为止。
函数语法:int strlen ( string $string )
函数说明:返回字符串string的长度。
函数语法:string strstr ( string $haystack, string $needle, bool $before_needle )
函数说明:在字符串haystack中查找子字符串needle第一次出现的位置,并返回字符串haystack中从字符串needle开始到母字符串结束的部分。如果参数before_needle为true,则返回字符串haystack中从开始到字符串needle第一次出现位置之间的字符串。
如果字符串haystack中查找不到字符串needle,则返回false。
函数语法:string stristr ( string $haystack, string $needle, bool $before_needle )
函数说明:同strstr(),不同之处为本函数不区分大小写。
函数语法:string strrchr ( string $haystack, string $needle )
函数说明:本函数用来寻找字符串haystack中的字符needle最后一次出现的位置,并返回此位置起至字符串haystack结束之间的字符串。若没有找到needle则返回false。
函数语法:int strpos ( string $haystack, mixed $needle [, int $offset] )
函数说明:寻找字符串haystack中的字符needle最先出现的位置。值得注意的是needle只能是一个字符,中文字等就不适合了。若找不到指定的字符,则返回false值。参数offset可省略,用来表示从offset位置处开始找。
函数语法:int strrpos ( string $haystack, string $needle [, int $offset] )
函数说明:略同strpos(),不同之处是查找并返回needle最后一次出现的位置。
函数语法:mixed str_replace ( mixed $search, mixed $replace, mixed $subject [, int&$count] )
函数说明:将字符串replace代入subject字符串中,将所有的search置换成replace。
函数语法:string md5 ( string $str [, bool $raw_output] )
函数说明:返回字符串str的MD5散列值。
函数语法:string urlencode ( string $str )
函数说明:将字符串str按照URL方式编码,除了 -_. 之外的所有非字母数字字符都将被替换成百分号(%)后跟两位十六进制数,空格则编码为加号(+)。
函数语法:string urldecode ( string $str )
函数说明:解码给出的已编码字符串中的任何 %##。返回解码后的字符串。
函数语法:string base64_encode ( string $data )
函数说明:返回使用base64对data进行编码。设计此种编码是为了使二进制数据可以通过非纯8-bit的传输层传输,例如电子邮件的主体。Base64-encoded数据要比原始数据多占用33%左右的空间。
函数语法:string base64_decode ( string $encoded_data )
函数说明:将encoded_data进行解码,返回原始数据,失败则返回FALSE。
2. 正则表达式
正则表达式是一种可以用于模式匹配和替换的强有力的工具。正则表达式可以让用户通过使用一系列的特殊字符构建匹配模式,然后把匹配模式与数据文件、程序输入以及Web页面的表单输入等目标对象进行比较,根据比较对象中是否包含匹配模式,执行相应的程序。
正则表达式的“祖先”可以一直上溯至对人类神经系统如何工作的早期研究。Warren McCulloch和Walter Pitts这两位神经生理学家研究出一种数学方式来描述这些神经网络。
1956年,一位叫Stephen Kleene的数学家在McCulloch和Pitts早期工作的基础上,发表了一篇标题为“神经网事件的表示法”的论文,引入了正则表达式的概念。正则表达式就是用来描述他称为“正则集的代数”的表达式,因此采用“正则表达式”这个术语。
随后,发现可以将这一工作应用于使用Ken Thompson的计算搜索算法的一些早期研究,Ken Thompson是UNIX的主要发明人。正则表达式的第一个实用应用程序就是UNIX中的qed编辑器。
目前,正则表达式已经在很多软件中得到广泛的应用,包括*nix(Linux,UNIX等),HP等操作系统,PHP,C#,Java等开发环境,以及很多的应用软件中,都可以看到正则表达式的影子。
正则表达式的使用,可以通过简单的办法来实现强大的功能。为了简单有效而又不失强大,造成了正则表达式代码的难度较大,学习起来也不是很容易,所以需要付出一些努力才行。
在字符串处理领域,正则表达式的强大功能令人叹为观止,它可以按照一定的规则匹配一组不确定的字符串,而上节我们介绍的几个函数只能比较两个确定的字符串。那么什么是正则表达式呢?
通俗地讲,正则表达式(regular expression)就是用一个“字符串”来描述一个特征,然后去验证另一个“字符串”是否符合这个特征。比如表达式“ab+”描述的特征是“一个 'a'和任意个 'b' ”,那么 'ab', 'abb', 'abbbbbbbbbb' 都符合这个特征。
正则表达式的用途非常广泛,如:① 验证字符串是否符合指定特征,比如验证是否是合法的邮件地址。② 用来查找字符串,从一个长的文本中查找符合指定特征的字符串,比查找固定字符串更加灵活方便。③ 用来替换,比普通的替换更强大。
列目录时, dir *.txt或ls *.txt中的*.txt就不是一个正则表达式,因为这里*与正则式的*的含义是不同的。
正则表达式是由普通字符(例如字符a到z)以及特殊字符(称为元字符)组成的文字模式。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。
构造正则表达式的方法和创建数学表达式的方法一样。也就是用多种元字符与操作符将小的表达式结合在一起来创建更大的表达式。正则表达式的组件可以是单个的字符、字符集合、字符范围、字符间的选择或者所有这些组件的任意组合。
限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配条件。有*、+、?、{n}、{n,}、{n,m}共6种。
用来描述字符串或单词的边界,共有^、$、\b、\B等4个。
正则表达式的选择是用圆括号将所有选择项括起来,相邻的选择项之间用|分隔。
正则表达式的引用是对一个正则表达式模式或部分模式两边添加圆括号将导致相关匹配存储到一个临时缓冲区中,所捕获的每个子匹配都按照在正则表达式模式中从左至右所遇到的内容存储。存储子匹配的缓冲区编号从1开始,连续编号直至最大99个子表达式。每个缓冲区都可以使用'\n'访问,其中n为一个标识特定缓冲区的一位或两位十进制数。
下面是几个正则表达式的例子。
(1) 表达式 "('|")(.*?)(\1)" 在匹配 " 'Hello', "World" " 时成功,匹配到的内容是" 'Hello' "。再次匹配时可以匹配到" "World" "。
(2) 表达式 "(\w)\1{4,}" 在匹配 "aa bbbb abcdefg ccccc 111121111 999999999" 时成功;匹配到的内容是 "ccccc"。再次匹配时,将得到999999999。这个表达式要求 "\w" 范围的字符至少重复5次,注意与 "\w{5,}" 之间的区别。
(3) 表达式 "<(\w+)\s*(\w+(=('|").*?\4)?\s*)*>.*?</\1>" 在匹配 "<td id='td1' style="bgcolor:white"> </td>" 时成功。如果 "<td>" 与 "</td>" 不配对,则会匹配失败;如果改成其他配对,也可以匹配成功。
(4) "^The":表示所有以"The"开始的字符串("There","The cat"等)。
(5) "of despair$":表示所以以"of despair"结尾的字符串。
(6) "^abc$":表示开始和结尾都是"abc"的字符串。
(7) "notice":表示任何包含"notice"的字符串。
(8) '*','+'和'?'这三个符号,表示一个或一序列字符重复出现的次数。它们分别表示“没有或更多”,“一次或更多”还有“没有或一次”。
"ab*":表示一个字符串有一个a后面跟着零个或若干个b。("a", "ab", "abbb",……)。
"ab+":表示一个字符串有一个a后面跟着至少一个b或者更多。
"ab?":表示一个字符串有一个a后面跟着零个或者一个b。
"a?b+$":表示在字符串的末尾有零个或一个a跟着一个或几个b。
(9) 用大括号表示重复次数的范围。
"ab{2}":表示一个字符串有一个a跟着两个b("abb")。
"ab{2,}":表示一个字符串有一个a跟着至少两个b。
"ab{3,5}":表示一个字符串有一个a跟着3到5个b。
需要注意的是必须指定范围的下限,如:"{0,2}"而不是"{,2}", '*','+'和'?'相当于"{0,}","{1,}"和"{0,1}"。
(10) '¦'表示“或”操作。
"hi¦hello":表示一个字符串里有"hi"或者"hello"。
"(b¦cd)ef":表示"bef"或"cdef";
"(a¦b)*c":表示一串"a""b"混合的字符串后面跟一个"c"。
(11) '.'可以替代任何字符。
"a.[0-9]":表示一个字符串有一个"a"后面跟着一个任意字符和一个数字;
"^.{3}$":表示有任意三个字符的字符串(长度为3个字符);
(12) 方括号表示某些字符允许在一个字符串中的某一特定位置出现。
"[ab]":表示一个字符串有一个"a"或"b"(相当于"a¦b")。
"[a-d]":表示一个字符串包含小写的'a'到'd'中的一个(相当于"a¦b¦c¦d"或者"[abcd]");
"^[a-zA-Z]":表示一个以字母开头的字符串。
"[0-9]%":表示一个百分号前有一位的数字。
",[a-zA-Z0-9]$":表示一个字符串以一个逗号后面跟着一个字母或数字结束。
'^'在方括号里的第一位时表示不希望出现的字符。(如:"%[^a-zA-Z]%"表示两个百分号中不应该出现字母)。
下面是几个常用的正则表达式。
(1) 非负整数:^\d+$
(2) 正整数:^[0-9]*[1-9][0-9]*$
(3) 非正整数:^((-\d+)|(0+))$
(4) 负整数:^-[0-9]*[1-9][0-9]*$
(5) 整数:^-?\d+$
(6) 非负浮点数:^\d+(\.\d+)?$
(7) 正浮点数:^((0-9)+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9] [0-9]*))$
(8) 非正浮点数:^((-\d+\.\d+)?)|(0+(\.0+)?))$
(9) 负浮点数:^(-((正浮点数正则式)))$
(10) 英文字符串:^[A-Za-z]+$
(11) 英文大写串:^[A-Z]+$
(12) 英文小写串:^[a-z]+”
(13) 英文字符数字串:^[A-Za-z0-9]+$
(14) 英数字加下画线串:^\w+$
(15) E-mail地址:^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$
(16) URL:^[a-zA-Z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\s*)?$
3. 常用的正则表达式函数
函数语法:array preg_grep ( string $pattern, array $input [, int $flags] )
函数说明:返回一个包括了input数组中与给定的pattern模式相匹配单元的新数组。如果参数flags为PREG_GREP_INVERT,则返回的是由不匹配pattern单元所组成的新数组。
函数语法:int preg_match_all ( string $pattern, string $subject, array $matches [, int $flags] )
函数说明:在subject中搜索所有与pattern给出的正则表达式匹配的内容并将结果以flags指定的顺序放到数组matches中。搜索到第一个匹配项之后,接下来的搜索从上一个匹配项末尾开始。
函数语法:int preg_match ( string $pattern, string $subject [, array $matches [, int $flags]] )
函数说明:在subject字符串中搜索与pattern给出的正则表达式相匹配的内容。如果提供了matches,则其会被搜索的结果所填充。$matches[0] 将包含与整个模式匹配的文本,$matches[1] 将包含与第一个捕获的括号中的子模式所匹配的文本,以此类推。返回pattern所匹配的次数。要么是0次(没有匹配)或1次,因为preg_match()在第一次匹配之后将停止搜索,如果出错返回FALSE。和preg_match_all()函数的区别在于本函数只匹配一次,而后者全文匹配。
函数语法:string preg_quote ( string $str [, string $delimiter] )
函数说明:以str为参数并给其中每个属于正则表达式语法的字符前面加上一个反斜线。如果你需要以动态生成的字符串作为模式去匹配则可以用此函数转义其中可能包含的特殊字符。如果提供了可选参数delimiter,该字符也将被转义。可以用来转义PCRE函数所需要的定界符,最常用的定界符是斜线 /。正则表达式的特殊字符包括:. \ + * ? [ ^ ] $ ( ) { }= ! < > | :。
函数语法:mixed preg_replace ( mixed $pattern, mixed $replacement, mixed $subject [, int$limit] )
函数说明:在subject中搜索pattern模式的匹配项并替换为replacement。如果指定了limit,则仅替换limit个匹配,如果省略limit或者其值为-1,则所有的匹配项都会被替换。
replacement可以包含\\n形式或$n形式的逆向引用,首选使用后者。每个此种引用将被替换为与第n个被捕获的括号内的子模式所匹配的文本。n可以从0到99,其中 \\0或$0指的是被整个模式所匹配的文本。对左圆括号从左到右计数(从1开始)以取得子模式的数目。
对替换模式在一个逆向引用后面紧接着一个数字时(即:紧接在一个匹配的模式后面的数字),不能使用熟悉的\\1符号来表示逆向引用。举例说 \\11,将会使preg_replace() 搞不清楚是想要一个\\1的逆向引用后面跟着一个数字1还是一个\\11的逆向引用。本例中的解决方法是使用\${1}1。这会形成一个隔离的$1逆向引用,而使另一个1只是单纯的文字。
preg_replace() 的每个参数(除了limit)都可以是一个数组。如果pattern和replacement都是数组,将以其键名在数组中出现的顺序来进行处理。
函数语法:mixed preg_replace_callback ( mixed $pattern, callback $callback, mixed $subject [, int $limit] )
函数说明:本函数的行为几乎和preg_replace() 一样,除了不是提供一个replacement参数,而是指定一个callback函数。该函数将以目标字符串中的匹配数组作为输入参数,并返回用于替换的字符串。
函数语法:array preg_split ( string $pattern, string $subject [, int $limit [, int $flags]] )
函数说明:返回一个数组,包含subject中沿着与pattern匹配的边界所分割的子串。如果指定了limit,则最多返回limit个子串,如果limit是-1,则意味着没有限制,可以用来继续指定可选参数flags。
flags可以是下列标记的任意组合(用按位或运算符 | 组合)。
PREG_SPLIT_NO_EMPTY:如果设定了本标记,则preg_split() 只返回非空的成分。
PREG_SPLIT_DELIM_CAPTURE:如果设定了本标记,定界符模式中的括号表达式也会被捕获并返回。本标记添加于PHP 4.0.5。
PREG_SPLIT_OFFSET_CAPTURE:如果设定了本标记,如果设定本标记,对每个出现的匹配结果也同时返回其附属的字符串偏移量。注意这改变了返回的数组的值,使其中的每个单元也是一个数组,其中第一项为匹配字符串,第二项为其在subject中的偏移量。
4. 正则表达式中的元字符行
表1-9为正则表达式的元字符行。
表1-9 正则表达式的元字符行
1.4.3 PHP面向对象的编程
(1) 类和对象的概念
面向对象的程序设计(OOP),是近年来日趋流行的编程架构,常常被用来作为设计大型软件项目的解决方案,尤其是多人合作的项目。OOP达到了软件工程的三个目标:重用性、灵活性和扩展性,它的基本原则是计算机程序是由单个能够起到子程序作用的单元或对象组合而成。有人说PHP不是一个真正的面向对象的语言,这话不假,PHP是一个混合型语言,你可以使用OOP,也可以使用传统的过程化编程。
类(Class)是变量和作用于这些变量的函数的集合,我们可以把类理解成为是对万事万物的高度概括、归纳出来的抽象概念。
当给一个类的属性赋予具体的值,就生成了基于这个类的一个实例,这个实例就叫做“对象(Object)”。对象是系统中用来描述客观事物的一个实体,它是构成系统的一个基本单位。对象是类的实例,所以,类中定义的属性和方法均可被对象沿用。
面向对象其实是现实世界模型的自然延伸,现实世界中任何实体都可以看做是对象,客观世界就是由对象和对象之间的联系组成的。面向对象的编程思想则力图使对计算机语言中对事物的描述与现实世界中该事物的本来面目尽可能的一致,对象之间通过消息相互作用。
在PHP5中,类的创建通过关键字class来定义。语法如下:
<?php class classname { 变量声明;//属性定义 函数声明;//方法定义 } ?>
所有的属性和方法定义都被封闭在class所引导的花括号中,在声明变量时,须使用三个限定词(public、private、protected)其中的一个进行修饰,以定义变量的访问权限,如:
<?php class form { public $name = "form"; //定义对象默认名称为”form” public $width = 200; //定义为200 private $value1;//一个私有属性 } ?>
类的方法都是以函数的形式存在的,因此和普通函数一样,通过function关键字来定义。
function sum($val1,$val2) { return $val1+$val2; }
当声明一个方法时,我们所做的和在类外部定义一个函数是一样的。类的方法和属性都有与类外部函数不同的各自的命名空间,这意味着我们可以建立一个与类外部函数或者其他类同名的方法,两者不会冲突。
要想使用类提供的功能,则需要把类实例成对象的,定义好一个类之后,就可以使用关键字new来创建一个基于该类的一个对象实例了,new需要类的名称,并返回一个类的实例,该实例也是一个变量,需要在对象名称前加$。如:
<?php $objectname = new classname; ?>
一个类可以实例出多个对象,每个对象都是独立的,每个对象之间是没有联系的,只能说明他们这个类的实例对象,每个对象都有自己各自的属性值。
只要是类里面体现出来的成员属性和成员方法,实例化出来的对象里面就包含了这些属性和方法,当需要访问这些属性变量时用->运算符来引用他们,而不能像普通变量那样用$来直接引导,如$objectname->attribute。当调用这个对象的方法时,同样如此:$objectname->functionname()。
当我们需要在对象外部调用它的某些属性值或者调用它的方法时,是使用“对象变量名->”来调用其属性或方法的,那么,当只有一个类的定义还没有被实例化的时候,或者在这个类定义其某个方法时就需要调用其他属性和方法,此时还没有对象变量的名称,该如何引用呢?
为解决变量的命名冲突和不确定性问题,引入伪变量“$this”代表其当前所在对象。我们可以使用$this来访问自身的方法函数和变量,$this变量可以理解为“我自己的”或者“当前对象”。因而 $this->name可以理解为“我自己的$name属性”或者“当前对象的$name属性”。
在类内部调用该类所定义的属性和其他方法,必须使用$this->取值,而方法内定义的局部变量,作用范围仅限于该方法内部,而不属于对象,因此是不能用$this关键字取值的。
(2) 构造方法
构造函数又叫做构造方法,是对象被通过使用new关键字创建时自动调用的方法,通常用于完成类初始化的工作。如果我们在一个类中声明一个命名为__construct()的函数(__是两个下画线),那么这个函数将被当成是一个构造函数并在生成对象实例时被执行。
就像其他任何函数一样,构造函数也可以有参数或者默认值。
构造函数可以调用本类的属性,也可以调用本类的其他方法,还可以被其他方法显式调用。
(3) 析构函数
和构造函数__construct()相对应,如果我们在一个类中声明一个名为__destruct()的函数, PHP将在对象被销毁前调用它,这个函数我们就叫做析构函数。
当PHP判断程序脚本中某个对象不再使用时,就会调用析构函数来将其从内存中销毁, PHP默认仅仅释放对象属性所占用的内存并销毁该对象相关的资源,析构函数则允许在使用一个对象之后执行任意代码来清除内存。
和其他方法不同,析构函数比较特殊,析构函数不能带有参数,也不要在程序中调用一个对象的析构函数。
(4) 两个对象的全等于比较
当使用全等符(===)时,当且仅当两个对象指向相同类(在某一特定的命名空间中)的同一个对象时才相等,这是更严格意义上的相等,内容相等,对象必须是同一个(相同的内存地址)。
(5) 对象的克隆
当用“=”克隆一个已有对象变量时,实际上只是引用了这个对象地址,改动新变量引用的属性值,原变量也会随之改动,而有的时候我们需要在一个项目里面,使用两个或多个一样的对象,如果使用“new”关键字重新创建对象的话,再赋值上相同的属性,这样做比较烦琐而且也容易出错,所以要根据一个对象完全克隆出一个一模一样的对象,是非常有必要的,关键是克隆以后,两个对象互不干扰,其中的一个对象的改变不会影响到另一个。为此,PHP提供了clone关键字来克隆一个与原对象拥有相同属性和方法的对象,并定义了一个在对象克隆时自动调用的特殊方法:__clone(),像__construct()和__destruct()一样,前面有两个下画线,如果想在克隆时改变默认的内容,就要在__clone中覆写属性或方法。
值得注意的是,__clone()方法不能被直接调用,否则程序就会报错。
(6) 类的继承
当我们已经创建了一些类后,就会发现在同一个范畴内如果再建立一些新的类,将会出现大量的雷同,新类和已有类大部分的属性和方法都相同,此时,有一种方法可以让我们很方便的以这些已有类为基础,快速便捷地生成新的类,不需要重复定义那些相同的属性和方法,大大减少书写代码的时间,提高代码的可重用率,这个方法就是继承。继承是面向对象三大重要特性之一,有着极其重要的作用,它是指建立一个新的派生类,从一个或多个先前已经定义的类中继承属性和方法,并可以重新定义或者加以改进这些属性和方法,从而建立了类的层级,在类与类之间建立了关系。
在面向对象的程序设计中,我们管已有的基础类叫做父类、基类,新的类叫做子类、派生类。子类默认从已有父类遗传有完全相同的属性和方法,只是简单的做一些父类中没有的扩展就可以了。需要值得注意的是,子类从父类继承了全部的属性和方法(父类的私有属性和私有方法除外,私有属性和私有方法的内容下文讲述),这些属性和方法是不能被注销的,不能减少,但是可以用新的值来覆盖他们。子类被创建后,又可以作为父类派生出更多的子类。
继承的重要优点是经济,您可以选择定义一个新类也可以在现有的类上建立子类。这两种方法得到结果是相同的。但是定义一个新类PHP会重新解析并占用一定的系统资源而使用继承的方法可以继承父类而且代码也会显得简洁。
除了上面的优点之外,继承有助于程序的维护,节省工作时间。如我们在已经定义好的父类中增加定义几个属性或者方法,则它的所有子类都不用增加一句代码就全部自动扩展了这些属性和方法。
一个子类可以从一个父类中继承属性和方法,这叫做单继承;也可以从多个父类中同时继承其属性和方法,这叫做多继承。
PHP5中,一个子类只能从一个父类中继承数据,是单继承,PHP5不支持多继承。创建一个子类时使用extends关键字来继承一个父类:
class childrenclassname extends fatherclassname { }
通常父类中的所有属性和方法都被子类全部继承,这并不是绝对的,在类的定义时,被三个限定词public、private、protected之一的private限定的属性和方法是不能被继承的,由这样的子类生成的实例对象就没有了这些属性和方法。
(7) 访问控制
如果类的一个成员被设置成了private私有访问方式,那么它将只对类或者对象实例本身的内部成员开放,不做访问限制,此对象内部的方法可以访问到所有属性和其他方法,不管这些成员被设置成了什么访问方式。
Private成员对外部程序是被屏蔽而不可见的,不能被它们访问到,当前对象以外的任何类、对象、程序都不能读取其私有属性的值,更不能改变它们,也不能调用其私有方法,即使是派生出的子类都不能访问到其父类的私有属性和方法。
Public(公共)成员可以被毫无限制地访问,不管是在类或者对象的内部还是外部,任何程序代码都可以读写public属性的值,都可以调用public方法。
和Private成员类似,Protected(保护) 成员也不能被外部程序访问,但区别之处在于受保护的成员可以被继承出的子类访问到,而私有成员不可以。Public有违封装的精神,因为它们允许子类依赖于一个特定的属性来书写,protected方法就不会带来这方面的担忧.一个使用protected方法的子类需要很清楚它的父类的结构才可以。
(8) parent关键字
PHP在同一个页面和被包含的页面中不能定义相同名称的方法,在同一个类中也不能定义相同名称的方法。但是在父子关系的两个类中,我们可以在子类中定义和父类同名的方法,这样就把父类中继承过来的方法覆盖掉了。当要突出表达子类与众不同的特点的方法时,就必须要改写父类方法。
一种是使用父类的“类名::”来调用父类中被覆盖的方法;另一种是使用“parent::”的方式来调用父类中被覆盖的方法。
“::”是范围解析操作符,用于在没有声明任何实例的情况下访问类中的函数或者基类中的函数和变量。
parent只在子类中使用,特指它的父类,不管父类的名字是什么。
(9) 类的接口
类的接口是一种特殊的抽象类,抽象类又是一种特殊的类,介绍类的接口前,我们需要先知道什么是抽象类。
在面向对象的编程语言中,一个类可以有一个或多个子类,抽象方法就是为了方便继承而引入的。所谓抽象方法就是我们在类里定义的没有方法体的方法,和正常的方法定义不同,没有方法体的意思是指在方法声明的时候没有{}以及其中的内容,而是直接在声明时在方法名后加上“;”结束,另外在声明抽象方法时还要加一个关键字“abstract”来修饰。
如果一个类里面有一个方法是抽象方法,那么这个类就必须要定义为抽象类,抽象类也要使用“abstract”关键字来修饰;在抽象类里面可以有不是抽象的方法和成员属性,但只要有一个方法是抽象的方法,这个类就必须声明为抽象类。
定义抽象类就相当于定义了一种规范,这种规范要求子类去遵守,子类继承抽象类之后,把抽象类里面的抽象方法按照子类的需要实现。子类必须把父类中的抽象方法全部都实现,换句话说,就是父类的抽象方法在子类中必须被重写,只要子类中还存在抽象方法,那么子类还是抽象类,还是不能实例化成对象。
声明一个类的时候我们使用的关键字是“class”,类的定义:class类名{ … },而接口是一种特殊的类,使用的关键字是“interface”,接口的声明:interface接口名{ … }
<?php interface interfacename { public function fun1(); public function fun2(); } ?>
我们使用extends来定义一个子类或一个抽象子类,而当从一个接口生成普通类的时,就要使用implements来实现这个接口,并需要实现接口中的全部抽象方法。
class 类名 implements 接口名 { 属性声明; 方法声明; }
PHP是单继承的,一个类只能有一父类,但是一个类却可以实现多个接口,只要使用“,”将多个接口名连在一起就可以了,就相当于一个类要遵守多个规范。PHP5中不仅一个类可以实现多个接口,也可以在继承一个类的同时还实现多个接口,但一定要先继承类再去实现接口。
(10) 多态性
当我们在子类中改写了父类的方法,或者用多个类来实现同一个接口时,都会导致在有层次关系的类里出现方法同名却不同行为的情况发生,我们管这种情况叫做面向对象的多态性。
1.4.4 PHP程序调试与异常
尽管我们写出了整洁、设计良好的代码, 但在程序运行中仍可能有各种各样的意外出现,当一个程序在运行过程中出现意外时,如除0溢出、数组越界、文件找不到等的异常事件,将阻止程序的正常运行,因此我们在程序设计时,要充分考虑容错性,估计到可能会发生的各种异常情况并做出相应的处理,以便程序可以健康的运行。
在面向对象编程中一般也采用面向对象的异常处理方法,通过throw来抛出异常, try-catch捕获异常,PHP 5.0内核采用了面向对象编程的方法,也引入了这种异常处理的方法。
PHP 5.0开始引入了异常处理类,我们可以通过实例化Exception类或者它的子类来创建一个异常实例,有了这个异常实例,就可以通过Exception类中定义好的getCode()、getFile()、getLine()等方法,来获得相应的属性值。
异常类Exception中属性和方法的定义如下:
<?php class Exception { protected $message; //存储异常信息的变量 private $string; //格式化以后的异常信息 protected $code; //通过构造函数传递的异常代码 protected $file; //产生异常的php文件的文件名 protected $line; //引起异常的代码在php文件中的行数 private $trace; //引起异常后,包含相关信息的一个数组 final private function __clone() { } function __construct($message = NULL, $code = 0) { //构造函数,需要一个出错信息和一个可选的整型错误标记作参数 if (func_num_args()) { $this->message = $message; } $this->code = $code; //默认错误代码为0 $this->file = __FILE__; //文件名 $this->line = __LINE__; //行号 $this->trace = debug_backtrace(); $this->string = StringFormat($this); } //取得出错信息 final public function getMessage() { return $this->message; } // 出错的代码 final public function getCode() { return $this->code; } //异常发生的文件 final public function getFile() { return $this->file; } //异常发生的行数 final public function getLine() { return $this->line; } //跟踪异常每一步传递的路线,存入数组,返回该数组 final public function getTrace() { return $this->trace; } // 和getTrace()功能一样,但可以将数组中的元素转成字符串并按一定格式输出 final public function getTraceAsString() { } // public function __toString() { return $this->string; } } ?>
在面向对象的编程中,如果某一个方法在运行过程中发生了异常,此方法将生成代表该异常的一个对象,并把它交给运行时系统,运行时系统寻找相应的代码来处理这一异常。我们把生成异常对象并把它提交给运行时系统的这个过程称为抛出(throw)一个异常。运行时系统在方法的调用栈中查找,从生成异常的方法开始进行回朔,直到找到包含相应异常处理的方法为止,这一个过程称为捕获(catch)一个异常。
Throw的用法是:
throw new Exception( "Exception Message", 2 );
我们通常使用try-catch语句(包括一个try语句和至少一个catch语句)来捕获程序代码通过throw抛出的异常并处理,try语句用花括号{}指定了一段代码,该段代码可能会抛弃一个或多个异常。任何调用可能会抛出异常的程序代码都应该使用try语句。一旦throw抛出异常,程序会在throw语句后立即终止,它后面的语句不再执行,而是在包含它的所有try块中(可能在上层调用函数中)从里向外寻找含有与其匹配的catch子句的try块。
Catch语句则用来处理可能抛出的异常。catch语句的参数类似于方法的声明,包括一个异常类型和一个异常对象。异常类型必须为Exception类的子类,它指明了catch语句所处理的异常类型,异常对象则由运行时系统在try所指定的代码块中生成并被捕获,花括号中包含对象的处理,其中可以调用对象的方法。
Try-catch语句的语法是:
Try { //可能发生异常的语句 } Catch(异常类型 异常实例) { //异常处理语句 }
如果try块未产生任何异常,try块将正常运行完毕,catch块内容不会被执行。
Try块如果抛出了异常,会立刻在catch中寻找可以捕获此异常的catch块,并运行相应的catch块代码,然后跳出try catch块继续运行。 而try块中抛出异常后面的代码将被跳过。
如果try块中的异常不能被catch块捕获,将抛向系统引发系统致命错误,代码终止运行。
在catch中,异常类型后面跟的是一个变量,这个变量将指向内存中被捕获的异常实例。
如果try块中的程序语句可能抛出两种以上的异常,我们可以在使用throw new Exception($message,$code)时,通过第二个参数$code来指定异常代码,然后在catch块中判断不同的异常代码分别做异常处理。
Catch语句可以有多个,分别处理不同类的异常,有多个扩展的异常处理类时就常用多个catch语句来对应匹配,运行时系统从上到下分别对每个catch语句处理的例外类型进行检测,直到找到类型相匹配的catch语句为止。每个catch语句的参数就像是一个匹配测试一样,第一个发生匹配的catch语句将会执行,而不执行其他的catch语句。这里,类型匹配指catch所处理的异常类型与生成的例外对象的类型完全一致或者是它的父类,因此,catch语句的排列顺序应该是从特殊到一般,将针对特定异常的catch语句写在前面,而将针对一般性的异常的catch语句写在后面。
也可以用一个catch语句处理多个异常类型,这时它的异常类型参数应该是这多个异常类型的父类,如Exception,程序设计中要根据具体的情况来选择catch语句的异常处理类型。
那么我们已经出发了一些在发生时调用程序无法马上处理的异常怎么办呢?类似,将处理这个异常的责任交还给调用当前方法的上一级代码,也就是在catch语句中再次抛出了异常,又叫重掷异常,这就使得异常沿着方法的调用层链逐级向上传递了。
异常是PHP5中的一个新的重要特性,异常机制提供了几个非常关键的好处:
(1) 通过将错误处理集中于catch语句中,我们可以将错误处理从应用流程中独立出来。这也使代码的可读性提高,看起来令人愉快。通过采取非常严格的策略来捕捉所有异常并中止脚本执行,这样可以获得所需的附加的弹性,同时实现安全易用的异常管理。
(2) 重掷异常,可以在catch中传播错误信息,将异常数据流从低层传递至高层,就是说异常被传回最适合决定如何处理异常的地方。这看起来会显得有点奇怪,但实际情况中很经常我们在异常发生的时候无法立刻决定如何处理它。
(3) 异常机制提供的Throw/catch避免了直接返回错误标识,方法的返回值是可以由类来决定。其他程序员使用我们的代码时,可以指定返回一个他希望的形式,而不需要令人疲倦的不停地测试,方便程序定位错误和维护。
有这样一种“美妙的”想法:用一个catch语句捕获所有的异常,最常见的情形就是使用catch(Exception $e)语句。但实际上,在绝大多数情况下,这种做法不值得提倡。为什么呢?
要理解其原因,我们必须回顾一下catch语句的用途。catch语句表示我们预期会出现某种异常,而且希望能够处理该异常。异常类的作用就是告诉PHP我们想要处理的是哪一种异常。由于绝大多数异常都直接或间接从Exception继承,catch(Exception ex)就相当于说我们想要处理所有的异常,可是在同一个catch块中处理几种截然不同的异常是不合适的,catch语句应当尽量指定具体的异常类型,而不应该指定涵盖范围太广的Exception类。必要时使用多个catch,不要试图处理所有可能出现的异常。
还有要尽量避免把大量的代码放入单个try块,这不是好习惯。这种现象是因为程序员图省事,不愿花时间分析一大块代码中哪几行代码会抛出异常、异常的具体类型是什么。把大量的语句装入单个巨大的try块就像是出门旅游时把所有日常用品塞入一个大箱子,虽然东西是带上了,但要找出来可不容易。把大量的代码放入单个try块,然后再在catch语句中声明Exception,而不是分离各个可能出现异常的段落并分别捕获其异常。这种做法为分析程序抛出异常的原因带来了困难,因为一大段代码中有太多的地方可能抛出Exception。
1.4.5 PHP与MySQL数据库
MySQL作为PHP最密切的数据库,PHP提供了非常多的函数来提供对MySQL数据库的操作,就连MySQL应用最广的管理软件phpMyadm都是用PHP来编写的。
PHP提供的MySQL数据库操作函数有:
mysql_affected_rows——取得前一次MySQL操作所影响的记录行数
mysql_change_user——改变活动连接中登录的用户
mysql_client_encoding——返回字符集的名称
mysql_close——关闭MySQL 连接
mysql_connect——打开一个到MySQL服务器的连接
mysql_create_db——新建一个MySQL数据库
mysql_data_seek——移动内部结果的指针
mysql_db_name——取得结果数据
mysql_db_query——发送一条MySQL查询
mysql_drop_db——丢弃(删除)一个MySQL数据库
mysql_errno——返回上一个MySQL操作中的错误信息的数字编码
mysql_error——返回上一个MySQL操作产生的文本错误信息
mysql_escape_string——转义一个字符串用于mysql_query
mysql_fetch_array——从结果集中取得一行作为关联数组,或数字数组,或二者兼有
mysql_fetch_assoc——从结果集中取得一行作为关联数组
mysql_fetch_field——从结果集中取得列信息并作为对象返回
mysql_fetch_lengths——取得结果集中每个输出的长度
mysql_fetch_object——从结果集中取得一行作为对象
mysql_fetch_row——从结果集中取得一行作为枚举数组
mysql_field_flags——从结果中取得和指定字段关联的标志
mysql_field_len——返回指定字段的长度
mysql_field_name——取得结果中指定字段的字段名
mysql_field_seek——将结果集中的指针设定为制定的字段偏移量
mysql_field_table——取得指定字段所在的表名
mysql_field_type——取得结果集中指定字段的类型
mysql_free_result——释放结果内存
mysql_get_client_info——取得MySQL 客户端信息
mysql_get_host_info——取得MySQL 主机信息
mysql_get_proto_info——取得MySQL 协议信息
mysql_get_server_info——取得MySQL服务器信息
mysql_info——取得最近一条查询的信息
mysql_insert_id——取得上一步INSERT操作产生的ID
mysql_list_dbs——列出MySQL服务器中所有的数据库
mysql_list_fields——列出MySQL结果中的字段
mysql_list_processes——列出MySQL进程
mysql_list_tables——列出MySQL数据库中的表
mysql_num_fields——取得结果集中字段的数目
mysql_num_rows——取得结果集中行的数目
mysql_pconnect——打开一个到MySQL服务器的持久连接
mysql_ping——Ping 一个服务器连接,如果没有连接则重新连接
mysql_query——发送一条MySQL查询
mysql_real_escape_string——转义SQL语句中使用的字符串中的特殊字符,并考虑到连接的当前字符集
mysql_result——取得结果数据
mysql_select_db——选择MySQL数据库
mysql_set_charset——Sets the client character set
mysql_stat——取得当前系统状态
mysql_tablename——取得表名
mysql_thread_id——返回当前线程的ID
mysql_unbuffered_query——向MySQL 发送一条SQL查询,并不获取和缓存结果的行
1.4.6 构建PHP动态网页
掌握了PHP的语法和面向对象的编程知识后,我们就可以综合运用来编写PHP动态网页了。
如下面我们给出一个连接MySQL数据库查询其中数据显示出来的的PHP脚本演示。
<?php //MySQL服务器地址 $host = "localhost:3306"; //MySQL用户名 $user = "root"; //MySQL密码 $pass = ""; //要使用的数据库 $dbname = "phpbook"; //建立和数据库的连接 $id = mysql_connect($host, $user, $pass); //使用GBK编码 mysql_query("set names gbk"); //选择数据库 mysql_select_db($dbname); //执行SQL查询,读出用户表 $sql = "select * from users where user_id > 0 order by user_id"; $result = mysql_query($sql); echo "<table><tr><td>用户代码</td><td>用户名</td><td>电子邮件</td><td>头像 地址</td><td>手机号码</td></tr>"; while($row = mysql_fetch_array($result)) { echo "<tr><td>" . $row['user_id'] . "</td><td>" . $row['user_name'] . "</td><td>" . $row['email'] . "</td><td>" . $row['img'] . "</td><td>" . $row['mobile_phone'] . "</td></tr>"; } echo "</table>"; ?>
我们将此代码存储为demo1.php,在浏览器中访问该地址如图1-28所示。
图1-28 PHP代码运行实例