第3章 PHP基本语法详解
PHP的语法与C语言很相似,如果有C语言编程经验,很容易上手。本章将详细介绍PHP的基本语法,内容涵盖了最基本的数据类型、变量、操作符、数组、字符串操作和流程控制语句。
3.1 在HTML中嵌入PHP
大多数PHP代码被嵌入HTML或XML文件中,为了识别PHP代码的执行区域和非PHP源代码,PHP提供了以下4种方法:
1. PHP代码段以<? php开始,以?>结束。
<? php //PHP代码 ?>
2.可以使用缩写的<?开始,以?>结束。
<? //PHP代码 ?>
3.使用script标记
<script language="php"> //PHP代码 </script>
从HTML中区分PHP代码块的方法是使用一个<script>标签来允许在HTML页面中进行PHP编程,PHP代码被嵌入JavaScirpt的标签中,只需简单地指定 "PHP" 作为标签属性language的值:
<script language=”php" > echo "hello" ; </script>
4.可以使用<%作为开始,以%>结束.
<% //PHP代码 %>
1. 和2. 是最常见的用法。3. 是类似JavaScript的编写方式。
对于从Windows平台的ASP投向PHP的使用者来说,4. 似曾相似,只要用PHP 3.0.4版本以后的服务器都可以用<%作为开始,以%>作为结束PHP的区段;但运用4. 的使用者別忘了在php.ini加入asp_tags,或是在编译PHP时加入--enable-asp-tags的选项,才能使4. 有效。建议少用4.,当PHP与ASP源代码混在一起时就麻烦了。
优先选用的方式为1.<? php...? >,在XML或者XHTML中嵌入PHP代码,需要使用<? php...? >形式的标记以适应XML的标准。
PHP代码每条简单语句以分号结尾。复合语句用大括号来标记代码块,在右括号后面不要用分号。和其他语言不一样的地方是,右括号前的分号是必须的,例如:
If ($IsValue == TRUE) { echo "true" ; //这里要求有分号 } //这里不要求有分号
PHP结束标签前的分号是可选的:
<? PHP echo "hello" // PHP结束标签前不要求有分号 ?>
包含可选分号是好的编程习惯,这样做使得以后更容易添加代码。不推荐省略分号,因为这有可能在修改代码时导致出错。
PHP插入注释时使用符号“//”,例:
echo "hello" // PHP结束标签前不要求有分号 使用/*和*/可插入注释块: /* 这是一个Cookie函数 */
下面是一个完整的在HTML中嵌入PHP的例子:
<! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <TITLE> HTML中嵌入PHP的例子</TITLE> </HEAD> <BODY> <p>我最喜欢的颜色: <? php echo “红色”; ? > </p> </BODY> </HTML>
运行结果如图3-1所示:
图3-1 HTML中嵌入PHP
当用户访问此页面并且查看源代码时,看到的是:
<! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <TITLE> HTML中嵌入PHP的例子</TITLE> </HEAD> <BODY> <p>我最喜欢的颜色:红色</p> </BODY> </HTML>
在此页面的源代码中,看不到PHP代码踪迹,用户看到的是PHP代码的输出结果。PHP代码可以放在文件的任何地方,甚至是有效的HTML标签中。例如:
<INPUT TYPE="text" NAME="FileName" value=”<? php echo “文件名”? >”>
也可以插入到JavaScript代码中,以达到PHP给JavaScript变量赋值的效果:
<SCRIPT LANGUAGE="JavaScript"> <! - Var FileName = ‘<? php echo “文件名”? >' ; //--> </SCRIPT>
上面这段代码等效于:
<SCRIPT LANGUAGE="JavaScript"> <! - Var FileName = ‘文件名’; //--> </SCRIPT>
3.2 PHP5.0的变量
3.2.1 常量
常量是一个简单值的标识符,在脚本执行期间其值是不能改变的。常量默认为大小写敏感。按照惯例,常量标识符总是大写的。
常量名和其他任何PHP标签遵循同样的命名规则,合法的常量名以字母或下划线开始,后面跟着任何字母,数字或下划线。常量的范围是全局的,不用管作用域就可以在脚本的任何地方访问常量。
常量使用define ()函数来定义,一旦被定义,就不能再改变或者取消定义。
常量只能包含标量数据(boolean, integer, float和string)。
可以简单地通过指定其名字来取得常量的值,不要在常量前面加上$符号。如果常量名是动态的,也可以用函数constant ()来读取常量的值。用get_defined_constants ()可以获得所有已定义的常量列表。
注意:常量和(全局)变量在不同的名字空间中。这意味着例如TRUE和$TRUE是不同的。
如果使用了一个未定义的常量,PHP假定想要的是该常量本身的名字,如同用字符串调用它一样(CONSTANT对应"CONSTANT")。此时将发出一个E_NOTICE级的错误。如果只想检查是否定义了某常量,可以用defined ()函数来查看。
常量和变量的不同:
● 常量前面没有美元符号($);
● 常量只能用define ()函数定义,而不能通过赋值语句;
● 常量可以不用理会变量范围的规则而在任何地方定义和访问;
● 常量一旦定义就不能被重新定义或者取消定义;
● 常量的值只能是标量。
定义常量例子:
<? php define ("CONSTANT", "Hello world."); echo CONSTANT; // 输出 "Hello world." ?>
PHP提供了大量的预定义常量。不过很多常量都是由不同的扩展库定义的,只有在加载了这些扩展库时才会出现,可以是动态加载,或者在编译时就已经包括进去了。
有四个魔术常量根据它们使用的位置而改变。例如__LINE__的值就依赖于它在脚本中所处的行来决定。这些特殊的常量不区分大小写,如表3-1所示。
表3-1 php的魔术变量
3.2.2 初始化变量
PHP中一个美元符号后面跟上一个变量名称,即表示一个变量。变量的名称是对大小写敏感的。变量名与PHP中其他的标签一样遵循相同的命名规则。变量命名规则有:
● 第一个符号必须为字母或是一下划线。
● 变量可以只包含字母以及下划线。
● 变量要是包含多个字意的话,应该使用下划线来隔开。
例如:$var = “0”; // 定义一个变量 $hello $hello_value $InValue $_int
上面都是正确的变量名,下面是一些非法的变量名:
$hello value //变量名不能包含空格 $' //变量名不能包含特殊字符 $3hello //变量不能以数字开头
变量名区别大小写,下面这些变量是不相同的。
$inData $INDATA $INdata
PHP4.0提供了另外一种给变量赋值的方式:传地址赋值。这意味着新的变量简单地引用了原始变量。改动新的变量将影响到原始变量,反之亦然。这同样意味着其中没有执行复制操作;因而,这种赋值操作更加快速。
使用传地址赋值,简单地追加一个(&)符号到将要赋值的变量前(源变量)。例如,下列代码片断两次输出‘My name is Bob' :
<? php $foo = ' Bob' ; // 赋值 ’ Bob’ 给变量 $foo $bar = &$foo; // 把变量 $foo的地址赋值给变量 $bar. $bar = "My name is $bar"; // 使用$bar变量 echo $bar; // 显示变量$bar的值为Bob echo $foo; // 显示变量$bar的值为Bob ?>
运行结果如图3-2所示:
图3-2 初始化变量
需要注意的是只有命名变量才可以传地址赋值,这一点非常重要。
<? php $foo = 25; $bar = &$foo; // 把变量 $foo的地址赋值给变量 $bar. $bar = &(24 * 7); // 错误用法,只有命名变量才可以传地址赋值 function test () { return 25; } $bar = &test (); // 错误的用法 ?>
变量可以存放任何类型的值,可以用另一个不同类型的值取代变量的值:
$inData = "hello, word" ; $inData = 100; $inData = Array (1,2,3,4);
在PHP中没有显示的语法来声明变量,在第一次设置变量值时,变量就被创建了。一个没有设置值的变量,其值为NULL。
3.2.3 类型的转换和变化
PHP在变量定义中不需要明确的类型定义;变量类型是根据使用该变量的上下文所决定的。也就是说,如果把一个字符串值赋给变量$var, $var的值就成了一个字符串。如果又把一个整型值赋给$var,那它的值就成了一个整数。
PHP自动类型转换的一个例子是加号“+”。如果任何一个运算数是浮点数,则所有的运算数都被当成浮点数,结果也是浮点数。否则运算数会被解释为整数,结果也是整数。注意这并没有改变这些运算数本身的类型;改变的仅是这些运算数如何被求值。
<? php $foo = "0"; // $foo为字符串(ASCII 48) $foo += 2; // $foo为整型(2) $foo = $foo + 1.3; // $foo为浮点数(3.3) $foo = 5 + "10 Little Piggies"; // $foo为整型(15) $foo = 5 + "10 Small Pigs"; // $foo为整型(15) ?>
PHP支持通过偏移量进行的字符串索引,这和数组索引的语法一样,下面是这种使用方法的例子:
<? php $a = "abc"; // $a为一个字符串 $a{1} = "f"; // $a目前为 "afc" ?>
PHP中的类型强制转换和C中的非常类似:在要转换的变量之前加上用括号括起来的目标类型。
下面是演示PHP类型强制转换的例子:
<? php $foo = 10; // $foo为整型 $bar = (boolean) $foo; // $bar为布尔型 ?>
允许的强制转换有:
(int),(integer)——转换成整型
(bool),(boolean)——转换成布尔型
(float),(double),(real)——转换成浮点型
(string)——转换成字符串
(array)——转换成数组
(object)——转换成对象
注意:在括号内允许有空格和制表符,所以下面两个例子功能相同:
<? php $foo = (int) $bar; $foo = (int) $bar; ?>
注意:为了将一个变量还原为字符串,可以将变量放置在双引号中。
<? php $foo = 1; // $foo为整型 $str = "$foo"; // $str为字符串 $fst = (string) $foo; // $fst强制转变为字符串 // 输出 "使用双引号还原成字符串" if ($fst == $str) { echo "使用双引号还原成字符串"; } ?>
3.2.4 获取或设置变量类型
可以使用gettype函数来获取变量类型。
gettype:获取变量类型。
返回的字符串的可能值为:
● "boolean" (从PHP 4.2.0起)
● "integer"
● "double" (由于历史原因,如果是float则返回 "double",而不是 "float")
● "string"
● "array"
● "object"
● "resource"(从PHP 4.2.0起)
● "NULL" (从PHP 4.2.0起)
● "unknown type"
注意:一般不建议使用gettype函数来测试某种变量类型,因为其返回的字符串在未来的版本中可能需要改变。此外,由于包含了字符串的比较,其运行效率也是较慢的。建议使用is_array ()、is_bool ()、is_float ()、is_integer ()、is_null ()、is_numeric ()、is_object ()、is_resource ()、is_scalar () 、is_string ()函数代替。
PHP使用settype函数来设置变量的类型:
bool settype (mixed var, string type)
将变量var的类型设置成type。
type的可能值为:
● "boolean" (或为 "bool",从PHP 4.2.0起)
● "integer" (或为 "int",从PHP 4.2.0起)
● "float" (只在PHP 4.2.0之后可以使用)
● "string"
● "array"
● "object"
● "null" (从PHP 4.2.0起)
如果成功则返回TRUE,失败则返回FALSE。
settype ()函数示例:
<? php $foo = "1hello"; // $foo为字符串 $bar = true; //$bar为布尔型 settype ($foo, "integer"); // $foo现在是 5 (integer) settype ($bar, "string"); // $bar现在是 "1" (string) ?>
3.3 运算符及其优先级
3.3.1 算术运算符
表3-2 算术运算符
3.3.2 赋值运算符
表3-3 赋值运算符
3.3.3 位运算符
表3-4 位运算符
3.3.4 逻辑运算符
表3-5 逻辑运算符
3.3.5 比较运算符
表3-6 比较运算符
3.3.6 执行运算符
PHP支持一个执行运算符:反引号(``)。PHP尝试将反引号中的内容作为外壳命令来执行,并返回其输出信息。使用反引号运算符“`”的效果与函数shell_exec ()相同。
<? php $output = `ls -al`; echo "<pre>$output</pre>"; ?>
注意:反引号运算符在安全模式下或者关闭了shell_exec ()时是无效的。
3.3.7 字符串运算符
有两个字符串运算符。第一个是连接运算符(“.”),它返回其左右参数连接后的字符串。第二个是连接赋值运算符(“.=”),它将右边参数附加到左边的参数后。
$a = "Hello "; $b = $a ."World! "; // 变量$b的值为"Hello World! " $a = "Hello "; $a .= "World! "; // 变量$a的值为"Hello World! "
3.3.8 错误控制运算符
PHP支持一个错误控制运算符:@。当将其放置在一个PHP表达式之前,该表达式可能产生的任何错误信息都将被忽略掉。
如果激活了track_errors特性,表达式所产生的任何错误信息都被存放在变量$php_errormsg中。此变量在每次出错时都会被覆盖,如果想用它的错误信息可以对它进行检查。
<? php /*文件错误信息*/ $my_file = @file (' non_existent_file') or die ("打开文件失败:错误为:' $php_errormsg' "); // $value = @$cache[$key]; ?>
注意:@ 运算符只对表达式有效。例如,可以把它放在变量、函数和include ()调用、常量等等之前,不能把它放在函数或类的定义之前,也不能用于条件结构,例如if和foreach等。
3.4 流程控制
3.4.1 if..else条件控制
if结构是很多语言包括PHP在内的重要特性之一,它允许按照条件执行代码片段。PHP的if结构和C语言相似:
if (expr) statement
expr按照布尔求值。如果expr的值为TRUE, PHP将执行statement;如果值为FALSE,将忽略statement。
如果$a大于$b,则以下例子将显示$a大于$b:
<? php if ($a > $b) echo "$a大于$b"; ?>
经常需要按照条件执行不止一条语句,当然并不需要给每条语句都加上一个if子句。可以将这些语句放入语句组中。例如,如果$a大于$b,以下代码将显示$a大于$b,并且将$a的值赋给$b:
<? php if ($a > $b) { echo "$a大于 $b"; $b = $a; } ?>
if语句可以无限层地嵌套在其他if语句中。经常需要在满足某个条件时执行一条语句,而在不满足该条件时执行其他语句,可以使用else的功能。else延伸了if语句,可以在if语句中的表达式的值为FALSE时执行语句。例如以下代码在$a大于$b时显示$a大于$b,反之则显示$a小于$b:
<? php if ($a > $b) { echo "$a大于 $b"; } else { echo "$a小于 $b"; } ?>
else语句仅在if以及elseif(如果有的话)语句中的表达式的值为FALSE时执行。
elseif,和此名称暗示的一样,是if和else的组合。和else一样,它延伸了if语句,可以在原来的if表达式值为FALSE时执行不同语句。但是和else不一样的是,它仅在elseif的条件表达式值为TRUE时执行语句。例如以下代码将根据条件分别显示$a大于$b, $a等于$b或者$a小于$b:
<? php if ($a > $b) { echo "$a大于$b"; } elseif ($a == $b) { echo "$a等于 $b"; } else { echo "$a小于 $b"; } ?>
在同一个if结构中可以有多个elseif语句。第一个表达式值为TRUE的elseif语句将会执行。在PHP中,也可以写成 "else if",它和 "elseif" 的行为完全一样。elseif的语句仅在之前的if或elseif的表达式值为FALSE时执行,而当前的elseif表达式值要为TRUE时执行。
3.4.2 switch条件控制
switch语句和具有同样表达式的一系列的IF语句相似。在需要时把同一个变量或表达式与很多不同的值比较,并根据它等于哪个值来执行不同代码时可以使用switch语句。
下面两个例子使用两种不同方法实现同样的功能,一个用一系列的if语句,另一个用switch语句:
<? php //使用if ..elseif语句的代码 if ($i == 0) { echo "i等于 0"; } elseif ($i == 1) { echo "i等于 1"; } elseif ($i == 2) { echo "i等于 2"; } //使用switch的代码,等效于上面的代码 switch ($i) { case 0: echo "i等于 0"; break; case 1: echo "i等于 1"; break; case 2: echo "i等于 2"; break; } ?>
switch语句一行接一行地执行,开始时没有代码被执行,仅当一个case语句中的值和switch表达式的值匹配时PHP才开始执行语句,直到switch的程序段结束或者遇到第一个break语句为止。如果不在case的语句段最后写上break的话,PHP将继续执行下一个case中的语句段。例如:
<? php switch ($i) { case 0: echo "i等于 0"; case 1: echo "i等于 1"; case 2: echo "i等于 2"; } ?>
在上面的例子中,如果$i等于0, PHP将执行所有的echo语句。如果$i等于1, PHP将执行后面两条echo语句。只有当$i等于2时,才得到“预期”的结果——只显示 "i等于2”。所以,别忘了break语句就很重要。
在switch语句中条件只求值一次并用来和每个case语句比较,而在elseif语句中条件会再次求值。如果条件比一个简单的比较要复杂得多或者在一个很多次的循环中,那么用switch语句可能会快一些。
在一个case中的语句也可以为空,这样只不过将控制转移到了下一个case中的语句。
<? php switch ($i) { case 0: case 1: case 2: echo "i不等于3"; break; case 3: print "i等于3"; } ?>
还可以在switch语句中添加default,当条件和case都不匹配的情况时就执行default后的语句,default语句应该放在最后一条case语句后面。例如:
<? php switch ($i) { case 0: echo "i等于 0"; break; case 1: echo "i等于1"; break; case 2: echo "i等于2"; break; default: echo "i不等于 0、 1或者2"; } ?>
case表达式可以是任何求值为简单类型的表达式,即整型或浮点数以及字符串。不能用数组或对象,除非它们被解除了到简单类型的引用。
switch支持转换替代的流程控制。例如:
<? php switch ($i): case 0: echo "i等于 0"; break; case 1: echo "i等于1"; break; case 2: echo "i等于2"; break; default: echo "i不等于 0、 1或者2"; endswitch; ?>
注意:与其他语言不同,continue语句作用到switch上的作用类似于break。如果在循环中有一个switch并希望continue到外层循环中的下一个轮回,用continue 2。
下面是在switch语句中使用continue的例子:
<? php $i = 1; while ($i <= 10) { switch ($i) { case 0: echo "i等于 0"; break; case 1: echo "i等于1"; break; case 2: echo "i等于2"; continue 2; //跳出while循环 default: echo "i不等于 0、 1或者2"; } } ?>
3.4.3 for循环
for循环是PHP中最复杂的循环结构,它的行为和C语言的相似。for循环的语法是:
for (expr1; expr2; expr3) statement
expr1:在循环开始前无条件求值一次。
expr2:在每次循环开始前求值。如果值为TRUE,则继续循环,执行嵌套的循环语句。如果值为FALSE,则终止循环。
expr3:在每次循环之后被求值执行。
每个表达式都可以为空。expr2为空意味着将无限循环下去,PHP默认其值为TRUE。这可能不如想像中那样没有用,因为经常会希望用break语句来结束循环而不是用for的表达式真值判断。
以下的例子它们都显示数字1到10:
<? php /* 例1 */ for ($i = 1; $i <= 10; $i++) { echo $i; } /* 例2 */ for ($i = 1; ; $i++) { if ($i > 10) { break; //如果$i>10则跳出for循环 } echo $i; } /* 例3 */ $i = 1; for (; ;) { if ($i > 10) { break; //如果$i>10则跳出for循环 } echo $i; //输出$i $i++; //$i自增1 } /* 例4 */ for ($i = 1; $i <= 10; echo $i, $i++); ?>
输出结果都是:12345678910
第一个例子和第四个例子最常用,但有的时候for循环中用空的表达式会很方便。
PHP也支持用冒号的for循环的替代语法。
for (expr1; expr2; expr3): statement; ...; endfor;
例如:
<? php /* 例1 */ for ($i = 1; $i <= 10; $i++) : echo $i; endfor ?>
3.4.4 while循环
while循环是PHP中最简单的循环类型,它和C语言中的while的用法一样。while语句的基本格式是:
while (expr) statement
while语句的含意很简单,只要while表达式的值为TRUE就重复执行嵌套中的循环语句。表达式的值在每次开始循环时检查,所以即使这个值在循环语句中改变了,语句也不会停止执行,直到本次循环结束。有时候如果while表达式的值一开始就是FALSE,则循环语句一次都不会执行。
和if语句一样,可以在while循环中用花括号括起一个语句组,或者用替代语法:
while (expr): statement ...endwhile;
下面两个例子完全一样,都显示数字1到10:
<? php /* 例子1 */ $i = 1; while ($i <= 10) { echo $i++; /* 输出$i*/ } /* 例子 2 */ $i = 1; while ($i <= 10): echo $i; //输出$i $i++; //$i=$i+1 endwhile; ?>
3.4.5 do…while循环
do..while和while循环非常相似,区别在于表达式的值是在每次循环结束时检查而不是在开始时。和正规的while循环相比主要的区别是do..while的循环语句保证会执行一次,表达式的真值在每次循环结束后检查,然而在正规的while循环中就不一定了,表达式真值在循环开始时检查,如果一开始就为FALSE则整个循环立即终止。
do..while循环只有一种语法:
do{ statement }while (expr)
下面是一个使用do..while的例子:
<? php $i = 0; do { echo $i; //输出$i $i++; //$i=$i+1 } while ($i > 0); ?>
以上循环将正好运行一次,因为经过第一次循环后,当检查表达式的真值时,其值为FALSE($i不大于0)而导致循环终止。
熟悉C语言的用户可能熟悉另一种不同的do..while循环用法,把语句放在do..while (0)之中,在循环内部用break语句来结束执行循环。
以下代码示范了此方法:
<? php $i=10; do { if ($i < 5) { echo "i小于5"; break; } $i--; } while (0); ?>
3.4.6 foreach循环
PHP 4包括了foreach结构,和Perl以及其他语言很像,这只是一种遍历数组简便方法。foreach仅能用于数组,当试图将其用于其他数据类型或者一个未初始化的变量时会产生错误。语法如下:
foreach (array_expression as $value) statement foreach (array_expression as $key => $value) statement
第一种格式遍历给定的array_expression数组。每次循环中,当前单元的值被赋给$value并且数组内部的指针向前移一步,下一次循环中将会得到下一个单元。
第二种格式实现同样的功能,当前单元的键值在每次循环中被赋给变量$key。
注意:当foreach开始执行时,数组内部的指针会自动指向第一个单元,这意味着不需要在foreach循环之前调用reset ()。
foreach操作的是指定数组的一个拷贝,而不是该数组本身。因此即使有each ()的构造,原数组指针也没有变,数组单元的值也不受影响。
注意:foreach不支持用“@”来禁止错误信息的能力。
以下的代码功能完全相同:
<? php $arr = array ("英格兰", "巴西", "意大利"); //定义一个数字索引从 0开始的数组 //将数组的内部指针指向第一个单元 reset ($arr); /* 使用while语句遍历数组 list函数:把数组中的值赋给一些变量 each函数:返回数组中当前的键/值对并将数组指针向前移动一步 */ while (list (, $value) = each ($arr)) { echo "值:$value<br>\n"; //显示数组值 } //使用foreach语句遍历数组 foreach ($arr as $value) { echo "值:$value<br>\n"; //显示数组值 } ?>
再来看一个例子,以下的代码功能完全相同:
<? php $arr = array ("英格兰", "巴西", "意大利"); reset ($arr); //使用while语句遍历数组 while (list ($key, $value) = each ($arr)) { echo "Key: $key; Value: $value<br>\n"; //显示键及键值 } //使用foreach语句遍历数组 foreach ($arr as $key => $value) { echo "Key: $key; Value: $value<br>\n"; //显示键及键值 } ?>
输出结果如图3-3所示:
图3-3 foreach循环
下面是foreach用法的一些范例:
<? php /* foreach例子1*/ $a = array (1, 2, 3, 17); foreach ($a as $v) { echo " 值为:$v\n "; } /* 输出结果为:值:1值:2值:3值:17*/ /* foreach例子2 */ $a = array (1, 2, 3, 17); $i = 0; /* 数字索引*/ foreach ($a as $v) { echo " [$i] => $v\n"; //使用数组下标 $i++; } /* 输出结果为:[0] => 1 [1] => 2 [2] => 3 [3] => 17 */ /* foreach例子 3 */ $a = array ( "one" => 1, "two" => 2, "three" => 3, "seventeen" => 17 ); foreach ($a as $k => $v) { echo "[$k] => $v\n"; //显示键及键值 } /* 输出结果为:[one] => 1 [two] => 2 [three] => 3 [seventeen] => 17 */ /* foreach例子 4,遍历一个二维数组 */ $a[0][0] = "a"; $a[0][1] = "b"; $a[1][0] = "y"; $a[1][1] = "z"; // foreach嵌套的例子 foreach ($a as $v1) { foreach ($v1 as $v2) { echo "$v2\n"; } } /* 输出结果为:a b y z */ /* foreach例子 5 */ foreach (array (1, 2, 3, 4, 5) as $v) { echo "$v\n"; } /* 输出结果为:1 2 3 4 5 */ ?>
3.4.7 跳转语句
break结束当前for, foreach, while, do..while或者switch结构的执行。break可以接受一个可选的数字参数来决定跳出几重循环。
<? php $arr = array (' one' , ' two' , ' three' , ' four' , ' stop' , ' five'); //使用while循环遍历数组 while (list (, $val) = each ($arr)) { if ($val == ' stop') { break; /* 跳出while循环,默认break 1.*/ } echo "$val<br>\n"; } /* 演示在while循环中跳出switch的例子. */ $i = 0; while (++$i) { switch ($i) { case 5: echo "At 5<br>\n"; break 1; /* 跳出switch循环. */ case 10: echo "At 10; quitting<br>\n"; break 2; /* 跳出switch语句和while循环. */ default: break; } } ?>
输出如图3-4所示:
图3-4 break跳转语句
continue在循环结构中用来跳过本次循环剩余的代码,并开始执行下一次循环。
注意:在PHP中switch语句被认为是作为continue目的的循环结构。
continue接受一个可选的数字参数来决定跳过几重循环到循环结尾。
<? php //跳出while循环 while (list ($key, $value) = each ($arr)) { if (! ($key % 2)) { //跳过奇数 continue; } } /* 下面是在while循环中跳出switch的代码. */ $i = 0; while ($i++ < 5) { while (1) { echo "第二层循环<br>\n"; while (1) { echo "第三层循环<br>\n"; continue 3; } echo "第二层循环结束.<br>\n"; } echo "第一层循环结束.<br>\n"; } /*输出结果为: 第二层循环 第三层循环 第二层循环 第三层循环 第二层循环 第三层循环 第二层循环 第三层循环 第二层循环 第三层循环*/ ?>
3.5 数组
3.5.1 初始化数组
数组可以使用下述两种方法来进行赋值:
● 使用一系列连续数值;
● 使用array ()函数构造。
函数array ():新建一个数组。array的语法为 "index => values",用逗号分开,定义了索引和值,索引可以是字符串或数字。如果省略了索引,会自动产生从0开始的整数索引。如果索引是整数,则下一个产生的索引将是目前最大的整数索引+1。注意如果定义了两个完全一样的索引,则后面一个会覆盖前一个。
例如:$color_arr = array (“红色”, ”蓝色”, ”黑色”);
要将连续的数值加进数组,只需将要赋值赋给不带下标的数组变量,该值会作为数组的最后元素加进数组中。
例:
$color_arr[]="红色"; //$color_arr[0]="红色" $color_arr[]="黑色"; //$color_arr[1]="黑色"
3.5.2 获得数组的大小
PHP中可以使用函数count ()和sizeof ()函数获得数组的元素数。
count ()函数原型为:int count (mixed var [, int mode]),返回var中的单元数目。可选的mode参数设为COUNT_RECURSIVE(或1), count ()将递归地对数组计数。对计算多维数组的所有单元尤其有用。mode的默认值是0。
下面是通过count ()函数递归得到数组大小例子:
<? php $color_arr = array (' color1' => array (‘红色’, ’ 绿色’, ’蓝色’), 'color2' => array (’黑色’, ’白色’)); // count递归 echo count ($color_arr, COUNT_RECURSIVE); // 输出 7 // count echo count ($color_arr); // 输出 2 ?>
sizeof ()函数是count ()函数的别名,用法和count ()函数相同
3.5.3 对数组进行排序操作
排序改变数组中元素的内部顺序,并且通过重新写键来反映这个新顺序。PHP提供三种方法来对数组进行排序操作,分别为:键排序、值排序不改变键值和值排序改变键值。每一种排序可以是升序、降序和由用户自定义函数定义的顺序。
PHP提供的排序函数如表3-7所示。
表3-7 PHP排序数组函数
下面的代码实现的是按字母升序排序颜色:
<? php $color_arr = array ("blue", "aliceblue", "gold", "yellow"); //升序 sort ($color_arr); //排序的结果为:aliceblue、blue、gold、yellow ?>
如果要获取降序的结果只需要使用rsort ()替换sort ()函数即可。
如果需要对那些单元顺序很重要的结合数组进行排序可以使用arsort ()函数,例如:
<? php $color_arr = array ("b"=>" blue ", "a"=>" aliceblue ", "g"=>" gold ", "y"=>" yellow "); arsort ($color_arr); //排序 reset ($color_arr); //将数组的内部指针指向第一个单元 while (list ($key, $val) = each ($color_arr)) { echo "$key = $val<br>\n"; //输出数组 } ?>
上面的例子输出的结果为:
a = yellow d = gold b = blue c = aliceblue
如果用户需要按照自己特殊的标准进行排序,可以使用自定义的比较函数对数组进行排序。下面是一个使用用户提供的比较函数对数组中的键名进行排序的例子:
<? php /* 比较函数 */ function cmp ($a, $b) { if ($a == $b) return 0; return ($a > $b) ? -1 : 1; } $a = array (4 => "four", 3 => "three", 20 => "twenty", 10 => "ten"); uksort ($a, "cmp"); //对键名排序 while (list ($key, $value) = each ($a)) { echo "$key: $value\n"; //显示排序结果 } ?>
上面的例子将显示:
20: twenty 10: ten 4: four 3: three
如果需要对多个数组或多维数组进行排序,可以使用array_multisort ()函数。该函数排序时保留原有的键名关联。函数原型为:
bool array_multisort (array ar1 [, mixed arg [, mixed ...[, array ...]]])
第一个参数ar1必须是一个数组,后面的每个参数可以是数组或者是下面列出的排序标志。
排序顺序标志:
● SORT_ASC - 按照升序排序
● SORT_DESC - 按照降序排序
排序类型标志:
● SORT_REGULAR - 将项目按照通常方法比较
● SORT_NUMERIC - 将项目按照数值比较
● SORT_STRING - 将项目按照字符串比较
每个数组之后不能指定两个同类的排序标志。每个数组后指定的排序标志仅对该数组有效,在此之前为默认值SORT_ASC和SORT_REGULAR。
如果成功则返回TRUE,失败则返回FALSE。
例:对多个数组排序
<? php $ar1 = array ("10", 100, 100, "a"); //数组1 $ar2 = array (1, 3, "2", 1); //数组2 array_multisort ($ar1, $ar2); //排序 ?>
本例中经过排序后,第一个数组将包含"10", "a",100,100。第二个数组将包含1, 1, "2",3。第二个数组中的项目顺序完全和第一个数组中相应的项目(100和100)顺序一致。
例:对多维数组排序
<? php //定义一个多维数组 $arr = array (array ("10", 100, 100, "a"), array (1, 3, "2", 1)); //对多维数组进行排序 array_multisort ($arr[0], SORT_ASC, SORT_STRING, $arr[1], SORT_NUMERIC, SORT_DESC); //输出第一个数组的各元素: echo $arr[0][0]."<br>"; echo $arr[0][1]."<br>"; echo $arr[0][2]."<br>"; echo $arr[0][3]."<br>"; //输出第二个数组的各元素: echo $arr[1][0]."<br>"; echo $arr[1][1]."<br>"; echo $arr[1][2]."<br>"; echo $arr[1][3]; ?>
本例中经过排序后,第一个数组将包含"10",100,100, "a"(作为字符串升序排序),第二个数组将包含1,3, "2",1(作为数值降序排序)。
3.5.4 搜索数组中的元素
搜索数组中的元素可以使用array_search ()函数。array_search ()函数在数组中搜索给定的值,如果成功则返回相应的键名。函数原型如下:
mixed array_search (mixed needle, array haystack [, bool strict])
在haystack中搜索needle参数并在找到的情况下返回键名,否则返回FALSE。
如果可选的第三个参数strict为TRUE,则array_search ()还将在haystack中检查needle的类型。
下面是一个使用array_search ()函数的例子:
<? php $code = array ("a", "b", "a", "c", "a", "b", "b"); $key1=array_search ("b", $code); //值为1-> $code[1]拥有b echo $key1; echo $code[1]; $key2=array_search ("c", $code); //值为 3-> $code[3]拥有c echo $key2; echo $code[3]; $key3=array_search ("X", $code); //返回false或空值即’’ echo $key3; ?>
3.6 字符串操作
在编程过程中遇到最多的就是与字符串相关的操作,PHP提供了大量的字符串操作函数,功能强大,使用也比较简单。PHP是弱类型语言,所以其他类型的数据一般可以直接应用于字符串操作函数,自动转换成字符串类型进行处理,如:
echo substr ("1234567", 1, 3);
和
echo substr (123456,1, 3);
输出的结果是一样的。
3.6.1 定义字符串
在PHP中一般用双引号或单引号标识一个字符串。比如:
$str = "i love u"; $str = ' i love u' ;
上述两种方法是有一些区别的:后者将单引号内的所有内容都当作字符处理;前者则不然。比如:
$test = "iwind"; $str = "i love $test"; $str1 = ' i love $test' ; echo $str; //将得到i love iwind echo $str1; //将得到i love $test
同样,以下两个例子的结果也是不一样的:
echo "i love \test"; // 将得到i love est,已经将\t视为转义 echo ' i love \test' ; // 将得到i love \test
用双引号括起来的字符串替换变量并且扩展许多PHP转义序列,表3.8列出了PHP的双引号字符串里的转义序列。
表3-8 PHP转义序列
如果在一个双引号括起来的字符串里发现了一个未知转义序列,则该序列将被忽视略。例如:
$str = "i love \d test。”; echo $str; //显示的结果为:i love \d test。
3.6.2 字符串输出
PHP里的输出最常用的是echo, print,它们两者都不是真正的函数,而是语言构造,所以调用时不必用双括号(比如echo ("test"); print ("test"))。在输出的时候两者都可以实现赋值:
echo $str="test"; //一方面输出test,一方面把"test"赋给字符串变量 $str print $str="test";
两者除了名字不一样外,还存在以下的区别:print具有返回值,一直返回1,而echo没有,所以echo比print要快一些:
$return = print "test"; echo $return; // 输出1
也正因为这个原因,print能应用于复合语句中,而echo则不能。
isset ($str) or print "str变量未定义"; // 将输出"str变量未定义" isset ($str) or echo "str变量未定义"; // 将提示分析错误
echo一次可输出多个字符串,而print则不可以:
echo "i ", "love ", "iwind"; // 将输出 "i love iwind" print "i ", "love ", "iwind"; // 将提示错误
echo, print还可以输出被称作“文档句法”的字符串,句法如:
echo <<< 标签名称 ... 字符串内容 ... 标签名称;
比如:
echo <<< test i love iwind test;
注意:语句开始和结束的两个标签名称是一样的,且后一个标签名称前不能有空白,即要顶格写。文档句法输出的内容识别变量名称和常用符号,大致形同双引号的作用。
输出除echo, print外,PHP还提供了一些格式化字符串的函数,比如printf, sprintf, vprintf, vsprintf。
函数printf ()将一个通过替换值建立的字符串输出到格式字符串中,其函数原型为:
void printf (string format [, mixed args])
第一个参数是格式字符串,剩下的参数是将要替换进来的值,格式字符串里的字符%指出一个替换标记。
格式字符串中的每一个替换标记都由一个百分号(%)组成,后面可能跟有下面列出的修饰符,并以类型说明符结尾(用’%%’在输出中得到单个百分字符)。修饰符必须按下面列出的次序出现:
● 一个填充字符,表明该字符用于填充结果,使结果为适当大小的字符串。规定其为0、一个空格或任何以一个单引号为前缀的字符,默认情况下用空格填充。
● 一个对齐方式字符。符号对字符串和数字有不同的作用。对于字符串,减号(-)使该字符串右对齐(默认为左对齐),对于数字,加号(+)使正数在输出的时候以一个加号开头。
● 字段宽度。如果结果少于这个字符串,符号和填充说明符将决定如何填充到这个长度。
● 对于浮点数,一个精确说明符由一个句点和一个数字组成;该说明符规定显示几位十进制数。对于非双精度类型的类型,这个说明符将被忽略。
类型说明符告诉printf ()什么类型的数据将被替换,这决定了对前面列出的修饰符的解释,一共有十二种类型,如表3-9所示。
表3-9 printf ()类型说明符
下面是一些使用printf ()函数进行输出的例子:
printf (‘%.2f' ,30.123); // 将一个浮点数转换成只有两位小数的数 printf (‘%d' ,888); // 输出一个十进制 printf (‘%x' ,888); //输出一个十六进制 printf (‘%100d' ,1); // 将一个整数填充成四位十进制 printf (‘%04d/%02d/%02d' ,2006,2,2); // 格式化一个日期 printf (‘%.2f%%' ,1.3); // 输出一个百分数
函数sprintf ()所带的参数和printf ()函数一样,但是返回的是内置的字符串而不是输出,使得可以在变量中存储字符串供以后使用,例如:
$isodate = sprintf ("%04d-%02d-%02d", $year, $month, $day);
函数vprintf ()允许在格式后面用数组作为参数,用法和printf ()函数基本相同。
计算字符串长度:
PHP提供strlen函数来计算字符串的长度:
$str = "test"; echo strlen ($str); // 将输出 4
strlen将中、日等汉字以及全角字符都当作两个或四个长度来计算。好在mbstring或icon两个函数可以帮助解决这个问题,比如:
$len = iconv_strlen ($str, "GBK"); $len = mb_strlen ($str, "GBK");
注意:mbstring模块提供了大量对含有多字节字符的字符串的处理函数,推荐多加应用,由于本章讲的是字符串入门,所以不打算详细解说。
3.6.3 裁剪
一个字符串首和尾,可能存在不想要的空白符,就可以用trim, rtrim, ltrim等函数,分别去除一个字符串两端的空白符,一个是字符串尾部空白符,另一个是字符串首部空白符。函数原型如下:
trim (string str [, string charlist]) ltrim (string str [, string charlist]) rtrim (string str [, string charlist])
可选参数charlist是一个字符串,该字符串指定所要删除的字符。默认情况下删除如表3-10中字符。
表3-10 trim ()、ltrim ()和rtrim ()的默认删除字符
echo trim (" i love you "); // 将得到 "i love you" echo rtrim (" i love you "); // 将得到 " i love you" echo ltrim (" i love you "); // 将得到 "i love you "
裁剪第二个参数指定的字符,如:
echo trim (",10,22,35,44, ", ", "); // 将得到 10,22,35,44两端的", "号被裁掉了。
3.6.4 大小写
对于英文字母来说,可以用strtoupper, strtolower将其转变成大写或小写。
strtoupper (str); strtolower (str);
下面是转换字符串字母大小的例子:
echo strtoupper ("Mary Had A Little Lamb "); // 输出MARY HAD A LITTLE LAMB echo strtolower ("Mary Had A Little Lamb "); // 将得到mary had a little lamb
3.6.5 比较
一般可以用!=, = =比较两个对象是否相等,只所以说是两个对象,是因为它们不一定全部为字符串,也可以为整型,等等。比如:
$a = "l love"; $b = "you"; if ($a ! = $b) { echo "不相等"; } else { echo "相等"; }
如果用 ! = =, == =(可以看到多了一个等号)比较的话,两个对象的类型要严格相等才能返回true;否则用= =, ! =则会将字符串自动转换成相应的类型,以便进行比较。
22 == "22"; // 返回true 22 === "22"; // 返回false
正因为这样,所以时常会发生一些想不到的“意外”:
0 == "我爱你"; // 返回true 1 == "1我爱你"; // 返回true
PHP里还有这样一组用于字符串比较的函数:strcmp, strcasecmp, strncasecmp (), strncmp (),如果前者比后者大,则它们都是返回大于0的整数;如果前者比后者小,则返回小于0的整数;如果两者相等,则返回0。它们比较的原理与其他语言的规则都是一样的。
strcmp是用于区分大小写(即大小写敏感)的字符串比较:
echo strcmp ("abcdd", "aBcde"); // 返回 1 (>0),比较的是 "b"和"B"
strcasecmp用于不区分大小写的字符串比较:
echo strcasecmp ("abcdd", "aBcde"); // 返回 -1 (<0),比较的是"d"和"e"
strncmp用于比较字符串的一部分,从字符串的开头开始比较,第三个参数,为要比较的长度:
echo strncmp ("abcdd", "aBcde", 3); // 返回 1 (>0),比较了abc和aBc。
strncasecmp用于不区分大小写的比较字符串的一部分,从字符串的开头开始比较,第三个参数,为要比较的长度:
echo strncasecmp ("abcdd", "aBcde", 3); // 返回 0
比较了abc和aBc,由于不区分大小写,所以两者是相同的。
还有一种情况是单单比较字符串大小还达不到我们预定的要求,比如按一般情况10.gif会比5.gif大,但如果应用上面几个函数,就会返回 -1,即表示10.gif比5.gif小,针对这种情况,PHP提供了两个自然对比的函数strnatcmp, strnatcasecmp:
echo strnatcmp ("10.gif", "5.gif"); // 返回 1 (>0) echo strnatcasecmp ("10.GIF", "5.gif"); // 返回 1 (>0)
3.6.6 替换
替换的意义在于将一个字符串的一部分进行改变,使之成为一个新的字符串,以满足新的要求。PHP里通常用str_replace ()函数进行替换,其函数原型为:
str_replace (search, replace, subject [, int &count])
下面是使用str_replace ()函数的例子:
echo str_replace ("%body%", "black", "<body text=' %body%' >"); //输出"<body text=' black' > "
即将原字符串中的所有"%body%"都替换成了" black "。
str_replace ()函数对大小写敏感,还可以实现多对一,多对多的替换,但无法实现一对多的替换:
$vowels = array ("a", "e", "i", "o", "u", "A", "E", "I", "O", "U"); echo str_replace ($vowels, "", "Hello World of PHP");
将会输出
Hll Wrld f PHP
$phrase = "You should eat fruits, vegetables, and fiber every day."; $healthy = array ("fruits", "vegetables", "fiber"); $yummy = array ("pizza", "beer", "ice cream"); echo str_replace ($healthy, $yummy, $phrase);
将输出You should eat pizza, beer, and ice cream every day。也就是说第一个数组中的元素被第二个数组中的相对应的元素替换掉了,如果有一个数组比另一个数组元素数要少,那么不足的部分都会当作空来处理。
此外,PHP还提供了substr_replace函数用来实现替换字符串的一部分,具体语法如下:
substr_replace (str, replacement, start [, int length])
参数str为原字符串,参数replacement为要替换的字符串,参数start为开始替换位置,参数length为替换的长度。
其中,开始替换的位置从0开始计算,应该小于原字符串的长度。要替换的长度是可选的。
echo substr_replace ("abcdefgh", "DEF", 3); // 将输出 "abcDEF" echo substr_replace ("abcdefgh", "DEF", 3, 2); // 将输出 "abcDEFfgh"
第一个例子中,从第三个位置(即"d")开始替换,从而把 "defgh"都替换成了 "DEF"。
第二个例子中,也是从第三个位置(即"d")开始替换,但只能替换2个长度,即到e,所以就把"de"替换成了"DEF"。
PHP还提供了preg_replace, preg_replace_callback, ereg_replace, eregi_replace等函数应用正则表达式来完成字符串替换。
3.6.7 查找与匹配
PHP里用于查找、匹配或者定位的函数非常多,它们都有不同的意义。这里只讲述用得比较多的strstr与stristr,它们两者的功能、返回值都一样,只是不区分大小写。
strstr ()函数用来查找子字符串在母字符串中第一次出现的位置,并返回母字符串中从子字符串开始到母字符串结束的部分。语法如下:
strstr (haystack, needle)
其中haystack为母字符串,needle为子字符串。
比如:
echo strstr ("abcdefg", "e"); //将输出 "efg"
如果找不到子字符串,则返回空。因为可以用来判断一个字符串中是否含有另外一个字符串:
$needle = "you"; $str = "i love you"; if (strstr ($str, $needle)) { echo "里面有you"; } else { echo "里面没有you"; }
将会输出"里面有you"。
3.6.8 HTML相关
1.htmlspecialchars($string)
函数htmlspecialchars ()将特殊字符转成HTML的字符串格式,该函数转换的特殊字符为:
● &(和)转成 &
● "(双引号)转成 "
● <(小于)转成 <
● >(大于)转成 >
具体语法如下:
htmlspecialchars (str [, quote_style [, charset]])
参数str为需要转换的字符串。quote_style的值为:ENT_COMPAT、ENT_NOQUOTES和ENT_QUOTES。参数charsets的值为:ISO-8859-1、ISO-8859-15、UTF-8、cp866、cp1251、cp1252、KOI8-R、BIG5、GB2312、BIG5-HKSCS、Shift_JIS或EUC-JP。
例如:
<? php echo htmlspecialchars ("<a href=' test' >Test</a>", ENT_QUOTES); ?>
将会输出:
< a href=' test' > Test< /a>
2.htmlentities($string)
将所有能转换成实体形式的字符都转换成实体形式。例如:
<? php $str = "A ' quote' is <b>bold</b>"; echo htmlentities ($str); //输出结果为:A ' quote' is < b> bold< /b> echo htmlentities ($str, ENT_QUOTES); //输出结果为:A ' quote' is < b> bold< /b> ?>
3.html_entity_decode($string);
PHP4.3.0以后加入的具有与htmlentities($string)相反功能的函数html_entity_decode。例如:
<? php $orig = "I' ll \"walk\" the <b>dog</b> now"; $a = htmlentities ($orig); $b = html_entity_decode ($a); echo $a; //输出:I' ll " walk" the < b> dog< /b> now echo $b; //输出:I' ll "walk" the <b>dog</b> now // 还原htmlentities函数 function unhtmlentities ($string) { //获取htmlspecialchars ()和htmlentities ()內部使用的转换表格,类型为 HTML_ENTITIES和HTMLSPECIALCHARS $trans_tbl = get_html_translation_table (HTML_ENTITIES); $trans_tbl = array_flip ($trans_tbl); //交换数组中的键和值 return strtr ($string, $trans_tbl); } $c = unhtmlentities ($a); echo $c; //输出I' ll "walk" the <b>dog</b> now ?>
4. nl2br($string)
该函数的功能是将字符串中的所有换行符转变成<br>换行符,例如:
<? php echo nl2br ("foo isn' t\n bar"); ?>
将会输出:
foo isn' t<br /> bar
3.6.9 加密
PHP还提供了crypt ()函数完成加密功能:
string crypt (string input_string [, string salt])
这一函数完成被称作单向加密的功能,也就是说,它可以加密一些明码,但不能够将密码转换为原来的明码。单向加密的口令一旦落入第三方人的手里,由于不能被还原为明文,因此也没有什么大用处。在验证用户输入的口令时,用户输入采用的也是单向算法,如果输入与存储的经加密后的口令相匹配,则输入的口令一定是正确的。
这个函数的input_string参数是需要加密的字符串,第二个参数salt是一个位字串,它能够影响加密的暗码,进一步地排除被称作预计算攻击的可能性。默认情况下,PHP使用一个2个字符的DES干扰串,如果你的系统使用的是MD5,它会使用一个12个字符的干扰串。
crypt ()支持四种算法,下面是它支持的算法和相应的salt参数的长度:
● CRYPT_STD_DES 2个字符(默认)
● CRYPT_EXT_DES 9个字符
● CRYPT_MD5 12个字符
● CRYPT_BLOWFISH 16个字符
例如:
<? php $password = crypt ("My1sTpassword"); //加密密码 if (crypt ($user_input, $password) == $password) { echo "密码正确!"; } ?>
在默认状态下使用的crypt ()并不是最安全的,所以如果需要较高的安全性能,就需要其他更好的算法,比如md5(),这一函数使用MD5散列算法,它将一个字符串转换成一个长32位的唯一的字符串。
echo md5("apple"); // 将输出 "1f3870be274f6c49b3e31a0c6728957f"
PHP5.0给md5加了第二个参数,从而使它可以输出16位的加密后的字符串。
3.6.10 字符串操作函数
常用的字符串操作函数如表3-11所示。
表3-11 字符串操作函数
续表
续表
续表
3.7 小结
为了回顾本章节的内容,下面来看一个典型的数组运算例子,里面包含了本章节的大部分内容,请读者细心揣摩。
要求:用以下给出的数组对数组进行排序,升序降序都可以,但不能用系统附带的函数来实现。
PHP : $array = array (' one' =>200, ' three' =>150, ' four' =>100, ' two' =>230);
● 解法一,用do…while解决
<? php $array = array (' one' =>200, ' three' =>150, ' four' =>100, ' two' =>230); $values = array_values ($array); do { $cur = min ($values); #$cur = max ($values); $key = array_search ($cur, $array); if ($key === false) { break; } $result[$key] = $cur; unset ($array[$key]); unset ($values[array_search ($cur, $values)]); } while (count ($values)>0); print_r ($result); ?>
● 解法二
<? php $array = array (' one' =>200, ' three' =>150, ' four' =>100, ' two' =>230); $ka=array_keys ($array); $count=count ($ka); for ($i=0; $i<$count-1; $i++){ for ($j=0; $j<$count-$i-1; $j++){ if ($array[$ka[$j]]>$array[$ka[$j+1]]){ $temp=$ka[$j]; $ka[$j]=$ka[$j+1]; $ka[$j+1]=$temp; } } } for ($i=0; $i<$count; $i++){ $asort["$ka[$i]"]=$array[$ka[$i]]; } print_r ($asort); ? >
● 解法三
<? //标准的递归函数 function BubbleSort ($str) { for ($i=0; $i<count ($str); $i++) { for ($j=count ($str)-2; $j>=$i; $j--) { if ($str[$j+1]<$str[$j]) { $tmp = $str[$j+1]; $str[$j+1]=$str[$j]; $str[$j]=$tmp; } } } return $str; } $array =array (' one' =>200, ' three' =>150, ' four' =>100, ' two' =>230); //将全部键值生成一个数组 $val_array=array_values ($array); //得到排序后的数组 $new_array=BubbleSort ($val_array); //替换排序后数组的键名 foreach ($new_array as $values){ $key=array_search ($values, $array); $final_array[$key]=$values; } print_r ($final_array); ?>
三个解法答案一样,输出结果如图3-5所示:
图3-5 运行结果