PHP与MySQL权威指南
上QQ阅读APP看书,第一时间看更新

第二部分 PHP篇

第3章 PHP基础

3.1 PHP的工作原理

PHP(Hypertext Preprocessor)是当下最受欢迎的Web开发语言之一。PHP最初由Rasmus Lerdorf创建于1995年,而现在,PHP的标准由PHP Group和开放源代码社区负责维护。PHP以PHP License作为许可协议,因为该协议限制了PHP名称的使用,所以和开放源代码许可协议GPL不兼容。

PHP的应用范围相当广泛,尤其是Web应用。一般来说,PHP大多在服务器端执行,通过执行PHP代码来产生用户浏览的页面。此外,还可以用来开发命令行脚本程序和客户端的GUI应用程序。PHP可以在多种不同的服务器和操作系统平台上执行,也可以和多种类型的数据库系统结合使用,其中的最佳搭档是MySQL。PHP是完全免费的,官方组织PHP Group提供了完整的程序源代码,允许用户修改、编译和扩展。根据2010年4月的统计资料显示,PHP已经被安装在超过4000万个网站和300万台服务器上。

PHP的工作原理如图3-1所示。

图3-1 PHP的工作原理示意图

3.2 PHP的版本变迁

经过近15年的发展,PHP在不断发展和成熟的过程中经历了从1.0到5.0的多个版本,为了使得初学者对PHP有一个全面的认识,本书特将PHP的版本变化历程详尽地呈现了出来,如表3-1所示,其中不仅包含了各个版本的现有状态和发布时间,更重要的是介绍了各个版本在功能特性上所做的重要改进和更新。其中,从PHP 1.0.0到PHP 5.1.0为旧版本,官方已经停止支持;从PHP 5.2.0到PHP 5.2.9也为旧版本,但官方仍在维护中;PHP 5.3.6为当前最新的版本;PHP 6.0则是下一个即将发布的重大版本。

表3-1 PHP的版本变化历程

3.3 PHP的特性

在学会使用PHP之前,我们先来看看PHP具有哪些特性,具体如下所示。

❑PHP完全免费和开源,升级快,同时有很多成熟的框架支持,如ZendFramework、ThinkPHP、FleaPHP、CakePHP等。

❑支持模板化开发,实现程序逻辑与用户界面的完全分离,开发周期短、效率高。

❑PHP的便捷性:程序开发快,运行快,易于学习。

❑具有良好的跨平台性:由于PHP是运行在服务器端的脚本,支持UNIX、Linux、Windows、FreeBSD、OS2等多种操作系统平台。

❑同目前主流的技术相兼容,如WebService、Ajax、XML等技术都支持PHP。

❑简单的语言:PHP坚持以脚本语言为主,与Java和C++不同。

❑支持所有的主流与非主流数据库,支持JDBC,提供MySQL、Oracle、Sybase和SQL Server等多种数据库的访问接口。

❑面向对象:在PHP4和PHP5中,面向对象方面都有很大的改进,现在PHP完全可以用来开发大型的商业程序。

❑相对于其他语言,PHP的编辑简单,实用性强,更适合初学者。

3.4 PHP的应用范围

PHP几乎可以做任何事情。由于PHP是服务器端的脚本语言,所以其他CGI程序能做到的事情它同样也能做到,如表单提交的数据、生成动态网页、接/发cookie,而且PHP还可以做得更多。

PHP脚本主要应用于以下三个领域:服务器端脚本、命令行脚本、编写桌面应用程序。直至今日,PHP已经可以支持绝大多数的Web服务器,如Apache、IIS、Nginx、PWS、Netscape、iPlant server、Xitami等。

由此可见,PHP可以任意选择操作系统和Web服务器。而且在开发PHP项目的时候可以选择使用面向过程或面向对象的程序设计方法,或二者并用。PHP 5包括新的对象模型,拥有更多新的功能、更快的处理速度、代码质量更高、企业项目的开发更容易等优点。

3.5 PHP的基本语法

3.5.1 PHP标记

多数情况下,PHP代码都是与HTML代码混在一起的。当包含了PHP程序的页面被请求时,Web服务器会自动编译、处理页面中“<?php”标记和“?>”标记之间的代码,并将处理后的结果以HTML的形式发送到页面中,从而在页面中显示处理结果。

要想让Web服务器能够区分PHP代码与普通的HTML代码,就要将PHP代码放在特殊标记内,PHP一共提供了4种不同的标记风格供我们使用,如下所示:

(1)<?php...?>

官方推荐风格,标记之间的代码将被自动解释为PHP脚本语言。

(2)<?...?>

短标记风格,使用这种标记之前须在配置文件php.ini中将short+open_tag设置为开启,不推荐这种风格。

(3)<%...%>

ASP风格,使用这种标记之前须在配置文件php.ini中将asp_tags设置为开启。

(4)<script language="php"> ...</script>

JavaScript标记的风格,这种标记风格是最长的,如果读者使用过JavaScript或VBScript,就会熟悉这种风格。如果你所使用的HTML编辑器无法支持其他标记风格,则可以使用它。这种风格在任何环境下都是可以用的,只是我们并不常使用。

3.5.2 PHP中的注释

为代码添加注释是一种良好的编程习惯,不仅可以使程序更清晰,也更利于团队开发。PHP提供的注释主要有两种类型:单行注释和多行注释,这两种注释的语法和示例如下所示。

(1)单行注释

❑C++风格的单行注释

注释通常不会超过一行。因为这种注释很简短,所以没必要界定注释的结束。PHP支持C++的单行注释语法,在某一行代码中,//符号后面的所有内容均被视为注释,如下所示:

        //这里写注释内容

❑shell风格的单行注释

PHP还支持另一种C++风格的单行注释,称为shell风格,它以#号开头。在某一行代码中,#符号后面的所有内容均被视为注释,如下所示:

        #这里写注释内容

(2)多行注释

代码中通常要有一些详细的功能描述或其他的解释内容,这些说明可能有多行。虽然可以在每行的前面都加上C++或shell风格的注释符,但PHP还支持一种多行注释的形式,同时标注注释的开始和结束。多行注释以/*符号开头,以*/符号结束,在这两个符号之间可以写入多行注释,如下所示:

        /*
        *这里写注释内容
        */

3.5.3 编写你的第一个PHP应用

前面已经搭建好了PHP的开发环境,现在来学习究竟如何编写PHP应用,让我们先从一个简单的“Hello World!”应用开始吧。先新建一个helloworld.php文件,输入以下的代码,并将该文件放入www文件夹内,在浏览器中输入http://127.0.0.1:80/helloworld.php,你将看到如图3-2所示的结果。

图3-2 “Hello World!”运行结果图

        <html>
            <body>
            <h1><?php echo "Hello World!"; ?></h1>
            </body>
        </html>

3.6 PHP中的变量与常量

3.6.1 变量

最好的理解是把变量想象为存储数据的容器。PHP中的变量本质上是灵活多变的:可以为一个变量赋值、在变量中检索数据(而不影响变量的值)、为变量赋新的值,以及在需要的时候进行循环。但是PHP中的变量也是临时的,它们只存在于一个脚本的执行期间,也就是说,它们只有在此时才有一个值。当用户单击一个链接或者提交表单时,将获得一个新的页面,同时这些变量也将不复存在。除非使用特殊的方法改变他们的生存期。

1. 变量声明

我们已经对变量有了一个初步的了解,在掌握了正确的语法后,就可以自己创建变量。变量总是以美元符号$开头,然后是变量名。声明变量时必须遵循如下规则:

❑所有的变量名必须以美元符号($)开头。

❑美元符号后的第一个字符必须为字母(A~Z,a~z)或者下划线(_)(不能使用数字)。

❑变量名剩下的部分可以是任何数量的字母、数字和下划线组合。

❑变量名中不能出现空格(通常使用下划线进行字符分隔)。

❑变量名是区分大小写的,这就意味着$phpchina和$PHPChina是截然不同的变量,因此将两个变量进行如此相似的命名是非常不明智的。

这些变量是合法的:$phpchina、$phpchina_zend、$_phpchina。

注意

与其他语言不同,PHP通常不需要在使用变量前声明或初始化变量。换句话说,可以在定义变量类型之前先引用。尽管如此,最好还是不要这样做,好的编程习惯是:所有的变量都应当在使用前进行声明,最好还要带有注释。

2. 变量赋值

声明变量之后,就可以为其赋值。变量赋值有两种方法:值赋值和引用赋值。所谓值赋值就是将赋值表达式的值复制到变量中,这是最常见的一类赋值。下面是几个例子:

        <?php
        $name_1='张三';
        $name_2 = $name_1;          //为$name_1的值创建一个副本,赋值给$name2
        $name_1='李四';             //改变$name_1的值
        echo $name_2;               //结果会输出“张三”,$name_2的值不会因$name_1的改变而改变
        ?>

如果希望两个变量指向一个值的同一个副本,则需要通过引用赋值,下面将介绍引用赋值。

PHP4提供了一种新的方式给变量赋值,这就是引用赋值。引用赋值同样也是使用“=”将一个变量的值赋给另一个变量,但是需要在等号右边的变量前加上一个“&”符号。实际上这种赋值方式并不是真正意义上的赋值,而是一个变量引用另一个变量。在使用引用赋值时,两个变量将会指向内存中的同一个存储空间。因此任何一个变量的变化都会引起另外一个变量的变化。使用引用赋值的示例如代码清单3-1所示:

代码清单3-1引用赋值示例

        <?php
        $name_1 = '张三';
        $name_2 = '李四';
        //这里将新变量$name_2指向$name_1;
        $name_2 = &$name_1;
        //改变$name_2的值
        $name_2 = 'Bob';
        $name_2 = 'My name is'.$name_2;
        //输出原始变量$name_1
        Echo $name_1;
        ?>

使用以上的引用赋值时将输出如图3-3所示的结果。

图3-3 引用赋值示例的结果

3. 可变变量

PHP支持对变量名称进行动态解析,也就是说,可以将变量名存储在另一个变量名中。如B变量存储了A变量的名称,通过对B变量的解析,即可得到A变量的值,如代码清单3-2所示。

代码清单3-2可变变量

        <?
        /*
        *$temp_2:变量A        $temp_1:变量B
        */
        $temp_1 = 'temp_2';                 //变量B存储了变量A的名称
        $temp_2 = "I'm temp_2";             //为变量A赋值
        echo $temp_1;                       //将输出I'm temp_2
        ?>

注意 因为可变变量会使代码变得难以阅读和理解,所以在项目开发中应尽量少用。

4. 变量作用域

总之无论怎样声明变量(按值或按引用),在PHP脚本的任何位置都可以声明变量。但是,声明的位置会大大影响变量的访问范围,这个可访问的范围称为作用域。PHP变量有4种作用域:

(1)局部变量

在函数中声明的变量被认为是局部变量,即它只能在该函数中引用。如果在函数外赋值,将被认为是完全不同的另一个变量。注意,退出声明变量的函数时,该变量及相应的值就会撤销。

局部变量的作用非常大,因为它消除了出现意外副作用的可能性,否则,这些副作用将导致全局访问的变量被有意或无意地修改。

(2)函数参数

PHP与其他很多编程语言一样,任何接收参数的函数都必须在函数的首部中声明这些参数。虽然这些参数接收函数外部的值,但退出函数后就无法再访问这些参数。

注意

虽然在声明参数的函数内部可以访问和处理这些参数,但当函数执行结束时,参数就会被撤销。

❑全局变量

与局部变量相反,全局变量可以在程序的任何地方访问。但是,为了修改一个全局变量,就必须在要修改该变量的函数中将其显式地声明为全局变量。这点很容易做到,只要在变量的前面加上关键字GLOBAL即可将其标识为全局变量。如果将GLOBAL关键字放在一个已有的变量的名称前面,则表示PHP要使用同名的变量。

注意

无论用何种方法将变量转换为全局变量,都要当心。全局变量一直以来都是困扰程序员的一个问题,因为草率使用会导致意外的结果。

❑静态变量

静态变量的作用域称为静态(static)作用域。函数参数的值在函数退出时会被撤销,与声明为函数参数的变量不同,静态变量在函数退出时不会丢失值,当再次调用此函数时还能保留这个值。在变量名前面加上关键字STATIC就可以声明一个静态变量。

5. 超级全局变量

PHP提供了很多有用的预定义变量,可以在执行脚本的任何位置访问,用于提供与环境有关的大量信息。可以通过这些变量获得关于当前用户的会话、用户操作环境和本地操作环境等详细信息。PHP会创建部分变量,而其他许多变量的可用性和值则取决于操作系统和Web服务器。PHP的全部超级全局变量如下所示:

❑$GLOBALS:包含所执行脚本内部全部可用的变量所组成的数组,数组的键即为变量的名称。

❑$_SERVER:包含正在执行的脚本的周边环境信息,例如服务器的名称和正在运行的页面的名称等。

❑$_GET和$_POST:包含可发送到服务器的变量。其中$_GET以url的形式传参,而POST则以包的形式传参。$_GET有字数限制(一般为2083B),且以url方式传参安全性不高,相对的,$_POST理论上没有字符限制,以HTTP包的形式传参,安全性更高。

❑$_SESSION和$_COOKIE:SESSION可以储存用户整个会话过程中的状态信息。COOKIE可设置并在本地保留明码信息。

❑$_REQUEST:用户输入的所有变量数组,包含$_POST、$_GET和$_SESSION数组。

3.6.2 常量

常量是指在程序执行中无法修改的值。当处理绝对不需要修改的值时,常量非常有用,例如π(3.141592)。常量一旦定义,就无法在程序的其他地方修改(或重新定义)。

1. 自定义常量

在PHP中使用define定义常量。常量一经定义就永远不能改变,如果要再次定义常量值,则会产生警告并且再次定义的值会被忽略。查看常量是否被定义可以使用函数defined,函数的返回值为布尔类型。其形式如下:

        boolean define(staring name,mixed value[, bool case_insensitive])

如果使用可选参数case_insensitive,并且这个参数的值为TRUE,那么后面对此常量的引用将不区分大小写。下面来看一个简单的示例:

        <?php
            define("PI", 3.141592);               //声明一个常量PI
            $pi2 = 2 * PI;                          //使用常量PI
            Print("PI doubled equals f%", $pi2);
        ?>

定义常量名称时不可用字符“$”开头,并且常量的值只能是特定的类型,如整数、浮点数、字符串和布尔值。

2. 魔术常量

PHP为它运行的任何脚本提供了大量的预定义常量。不过很多常量都是由不同的扩展库来定义的,只有在加载了这些扩展库时才会出现,或者动态加载后,或者在编译时已经包括进去了。有5个魔术常量需要根据它们使用的位置而改变,具体说明可参考表3-2。

表3-2 魔术常量参照表

最后要提醒大家,魔术常量的值会根据使用该常量的文件位置的改变而改变,这些特殊常量不区分大小写。

3.7 表达式

表达式是PHP最重要的组成元素,下面是几个例子:

        $a = 5;                      //将整数5赋予变量$a
        $a = '5';                    //将字符串5赋予变量$a
        $sum = 5 + $a;               //将5+$a的结果赋予变量$sum

3.7.1 表达式分类

下面来看一个简单的表达式:

        <?php
        $a = 100; //赋值语句,$a=100是最简单的表达式
        ?>

从这个表达式中可以看到只有一个操作数$a。因此根据运算数的个数,PHP表达式一般可以分成三类:

❑单目表达式:运算数只有一个,如$a或zhanglei等;

❑双目表达式:运算数有两个,如$a+$b,$a=100等;

❑三目表达式:运算数有三个,如$a ? $b:$c。

3.7.2 表达式的应用

下面先给出一个包含常量和变量的简单例子。当你写$a = 5时,即将值'5'赋给了$a(这种情况下,5是一个整型常量)。在此,你是希望把$a赋值成5,所以当你写$b = $a时,希望的结果就是$b = 5,即$a是一个值为5的表达式。复杂表达式多应用在函数部分。例如,以下函数:

        function foo() {
        return 5;
        }

如果你认为$c = foo()和$c = 5实际上是一样的,那么你是对的。函数是值为其返回值的表达式。因为foo()返回5,所以表达式foo()的值为5。

PHP的值当然不限于整型,且通常都不是。PHP支持三种类型的值:整型值、浮点值和字符串值。PHP还支持两种混合类型(non-scalar):数组和对象。这两种类型的值可以赋给变量或从函数中返回。PHP还是一种面向表达式的语言,所以几乎所有的东西都可成为表达式。考虑前面已经讨论过的例子$a = 5,很容易看出这里有两个值,整型常量5的值和已被赋为5的变量 $a的值。但是这里实际上还有一个附加的值,就是赋值语句本身的值。赋值语句本身的值就是被赋予的值,本例中为5。事实上,它意味着不考虑$a = 5要做什么,它就是一个值为5的表达式。这样,诸如$b = ($a = 5)的语句,就如同$a = 5; $b = 5;(每条语句末尾都有一个分号)。因为赋值的顺序可以从右向左,所以也可以写成$b= $a = 5。

最常见的表达式是比较表达式。这种表达式的计算结果是0或1,分别意味着false或是true。PHP支持 >(大于)、>=(大于等于)、==(等于)、<(小于)及 <=(小于等于)。这种表达式通常用于条件执行语句里,例如if语句。最后要讨论的表达式是混合赋值表达式。你已经知道如果要使 $a加1,则可以简单地写一句$a++或++$a。但是,如果要增加的值比1大,那该怎么办?例如要使它加3,你可以多写几次$a++,但这显然不是一种高效的或令人乐于接受的办法。另外一个通常的办法是写成$a = $a + 3。先计算$a + 3的值,再赋回到$a,这样$a就加上3了。在PHP中,你可以像在其他几种语言中(例如C)一样将它简写,这样更清晰和简洁易懂。把当前的变量$a加3可以写成$a += 3。这句话的意思是“取出$a的值,把它加3,再赋给$a”。这样写除了能使语句简短和清晰,还能使它执行得更快。表达式$a += 3的值和一个严格的赋值语句一样,是所赋的值。

注意

不是3,而是$a加3的值(这才是赋给$a的值)。任何双操作符都可以用于这种赋值操作模式,例如'$a -= 5'(变量$a减去5),'$b *= 7'(变量$b乘以7),等等。

最后值得一提的是表达式的真值。很多时候(主要是在条件执行和循环时),你并不关心表达式的特定值,而只是关注它代表true还是false(PHP没有专用的布尔类型)。PHP中使用类似Perl的方法来计算表达式的真值。任何非零的值为true,零则为false。请一定注意负数也是非零值,并被视为true。空字符串和字符串“0”为false,其他的字符串均为true。对于非数量值(数组和对象)—如果它的值不含任何元素,则为false,否则为true。

3.7.3 操作数

操作数是表达式的输入。下面是操作数的一些例子:

        $a++;                                          //$a是一个操作数
        $sun = $value1 + $value2;                      //$sum,$value1和$value2都是操作数

3.7.4 操作符

操作符是用来操作各种操作数的符号,只有理解各种操作符的用法,才能更高效地开发出PHP程序。PHP会根据操作符的类型自动进行类型转换,这在其他的编程语言中并不多见。

操作符根据功能特性可分为:算数操作符、赋值操作符、比较操作符、逻辑操作符和其他操作符。操作符的优先级和结合性是PHP语言特性中的重要部分,表3-3根据优先级从高到低的顺序详细介绍了PHP中的各种操作符。

表3-3 操作符优先级

对于表3-3所给的各个运算符的优先级,我们不必刻意全部记住。如果在开发过程中要使用复杂的表达式运算,可以通过添加“()”来限制各子表达式运算的优先级。

3.8 PHP中的数据类型

PHP提供了一个不断扩充的数据类型集合,可以将不同的数据保存在不同的数据类型中。但PHP语言是一种弱类型检查的语言,与其他语言不同的是,变量或常量的数据类型由程序的上下文来决定。在强类型语言中,变量要先指定类型,然后才可以存储对应的指定类型的数据。而PHP这种弱类型语言,变量的类型则是由数据决定的。

PHP中的数据类型可划分为三大类别:基本数据类型、复合数据类型和特殊数据类型。各种数据类型所包括的内容如表3-4所示。

表3-4 PHP数据类型分类

3.8.1 布尔型

布尔数据类型以数学家乔治·布尔的名字命名,他被认为是信息论的创始人之一。布尔变量表示真实性,布尔型是最简单的数据类型,表达式的值只有TURE和FALSE两个,不区分大小写。

注意 -1和其他非零值(不论正负)一样,被认为是TURE,而不是FALSE。

3.8.2 整型

整型就是一个不包含小数部分的数,整型值可以指定为十进制、十六进制或八进制,八进制数字前必须加上零(0),十六进制符号数字前必须加上0x。例如:

        $num_1 = 123    //一个十进制数
        $num_2 = 0123   //一个八进制数(等于十进制数中的83)
        $num_3 = 0x3A   //一个十六进制数(等于十进制数中的58)

因为PHP中不存在整除,所以,如果运算结果超出整型范围,则返回float,即整型的1/2等于float 0.5。

3.8.3 字符串

字符串就是一个连续的字符的序列。一般可通过以下两种方式指定一个字符串的值。

1. 单引号

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

        <?php echo 'this is a simple of string insingle-quoted.';?>

如果要在字符串中包含单引号,则需在它前面加上反斜线,这叫做字符的转义(escape),示例如下:

        <?php echo 'this is a simple of string insingle-quoted(\').';?>

如果要在字符串中包含反斜线,则需要对反斜线进行转义。示例如下:

        <?php echo 'this is a simple of string insingle-quoted(\\).';?>
2. 双引号

相对于单引号的字符串,PHP处理程序会剖析双引号括起的字符串,以便查找和替换特别的转义序列和变量。PHP转义序列如下所示:

        \n                   换行字符
        \r                   回车字符
        \t                   制表符
        \\                   反斜线字符
        \$                   美元符号
        \0                   值在0~255之间的字符,八进制表示法
        \x                   值在0~255之间的字符,十六进制表示法

3.8.4 数组

由多个数值以键值对的形式存储而成的数据集合称为数组,其中,键也称为索引。由于PHP中的数组结构没有固定的要求,所以非常灵活。PHP中数组的键不像Java那样只能是数字,也可以是字符串,而由于PHP弱语言的特性,数组的值也可以是各种数据类型。

注意

在开发PHP项目的时候,应尽量避免数组中存在类似'<abc'这样的值,浏览器在解析数组的值时,会将'<abc'解析为HTML标记,而由于标记不完整(没有表示结束的'>'),所以数组后面的值将不会解析出来,这样就会导致数据的丢失。

利用count()函数可以取得数组元素的个数。由于数组的值也可以是数组,所以在PHP中可以很轻松地创建多维数组。可使用print_r()将数组全部打印出来以便查看数组的结构。

数组排序

简单的数组排序是对一个数组元素的值进行排序,PHP的sort()和rsort()函数实现了这个功能。这两个函数既可以按照数字的大小排列,也可以按照字母的顺序进行排列,并且具有相同的参数列表。

sort()函数会按照数组元素的值进行排序,按照先数字后字母的顺序由小到大进行排序,排序后数组的索引将会重置。rsort()与sort()正好相反,它是按照由大到小的顺序对元素的值进行排序。

使用数组时,会根据键名对数组重新排序,ksort()和krsort()函数实现了这个功能。ksort()函数按照数组的键名(索引顺序)对数组进行由小到大的排序。krsort()函数和ksort()相反,是将数组进行由大到小的排序。

如果想使用数组中元素的值进行排序来取代键值排序,PHP也能满足你的要求。只需要使用asort()函数来代替先前提到的ksort()函数就可以了,如果按值从大到小排序,则可以使用arsort()函数。asort()与sort()的功能类似,唯一的区别在于执行asort()排序后的数组索引将不会重置,完全保留原数组键值的对应信息。

注意

使用sort()函数排序后的数值型数组是按数据值的大小进行排序的,字符型数组是按ASCII码的顺序进行排序的。如果一个数组的内容中同时包含英文字符、汉字字符和数字,使用sort()函数进行排序的顺序则依次为数字、英文字符和汉字字符。

3.8.5 对象

创建对象的过程称为实例化,当一个对象被创建后,就包含了三个方面的特性:句柄、属性和方法。在面向对象的程序设计中,对象是一个非常重要的核心概念。

1. 对象的句柄

对象被创建后,该对象就会获得一块存储空间,该控件的地址即为对象的标识,也就是对象的句柄。

2. 属性与方法

在面向对象编程中,模块被组织成一个个对象。这些对象拥有方法和属性,从抽象的角度来看,方法是一个对象所做的动作,而属性是对象的特性。从编程的角度来看,方法就是函数,而属性就是变量。在一个理想化的面向对象体系中,每个部分都是一个对象,体系由对象及对象间通过方法形成的联系所构成。

关于对象的具体应用,将在第8章详细介绍。

3.8.6 其他类型

除了上面讲到的类型,PHP在特定情况下会用到以下几种类型:

1. 资源

PHP有时会处理一些数据库连接或操作系统对象的句柄。它们是被称为资源(resource)的特殊变量。一般情况下,资源在函数之间传递,这些函数知道如何处理它们。当不再需要这些资源时,PHP就会自动释放它们。

2. NULL

NULL是PHP中的特殊类型和值,它代表“无值”。如果变量符合下列要求,则它们的值为NULL。

❑被设置为大小写敏感的关键字NULL。

❑从未被赋过值。

❑使用unset()方法后清除。

NULL、0、空字符的区别:NULL表示无值,0和空字符表示有值,值为0和空。

3.9 强制类型转换

在项目开发中,经常会用到类型转换,例如把商品的价格由整型转换为字符型,与别的信息连在一起组成一张价目表。

3.9.1 显式和隐式强制类型转换

1. 隐式强制类型转换

隐式强制类型转换是一种最常见的转换方式,也是由PHP语言引擎自动解析的转换方式。

最简单的例子是:将一个整数与一个浮点数进行数学运算,PHP会将整数转换成浮点数后再进行运算;又如,将一个字符串与一个整数进行数学运算,PHP会将字符串转换成整数后再进行运算。一些特定的方法和操作符也会将参数进行转换,例如,echo方法和print方法需要它们的参数为字符串,在执行操作时,PHP会尽可能地将非字符串变量转换为字符串。

2. 显式强制类型转换

有时,PHP引擎认为转换类型后的数据会改变或丢失,将不自动转换,在这种情况下,可以使用(type cast)的方式显式强制转换某变量的值。

❑(int)/(integer):转换为整数

❑(float)/(double)/(real):转换为浮点数

❑(string):转换为文本字符串

❑(bool)/(boolean):转换为布尔值

❑(array):转换为数组

❑(object):转换为对象

3.9.2 有用的强制类型转换函数

is_type():判断当前是否为某种类型的变量。

gettype:得到当前变量的类型。

settype:有两个参数为要转换的变量和要转换的类型,函数返回布尔值,表示转换成功。

3.10 PHP的语句

任何复杂的程序设计都离不开流程控制语句,这些语句决定了程序的走向。PHP中共包含了三种控制结构:顺序结构、分支结构和循环结构。

3.10.1 循环语句

程序中经常会有些代码块要被执行多次,虽然形式可能会有所不同,但是所有流行的编程语言中都必定有循环语句。这不奇怪,因为往往需要重复一段指令直到满足特定条件为止,这是程序中非常常见的,而循环机制为此提供了一种简单的方式。PHP为此提供了几种这样的循环机制,如果你熟悉其他编程语言,应该会很快掌握。

1. while循环

while语句制定了一个条件,在其嵌入的代码执行结束前,必须满足这个条件。其语句格式是:

        while(condition){    //条件
        statement;           //执行语句
        }

循环流程:condition返回值为true时,继续执行statement语句,之后接着检查condition条件。condition返回值为false时,直接跳出循环,不再执行statement语句。使用continue和break都可以跳出循环。区别在于,continue只跳出一次循环,跳出后继续检查condition条件,而break则直接跳到循环外。

2. do...while循环

do...while循环条件是while的一种变体,它在代码块的结束处验证循环条件,而不是在开始处。其语句格式是:

        do
        {
            statement
        }while(condition)

循环流程:首先执行一次statement语句,再检查condition条件,后面的流程与while循环一样。do...while循环与while循环的唯一区别在于while循环先检查条件,而do...while循环则先执行一次statement语句再检查条件。

3. for循环

for语句提供了比while语句更加复杂的循环机制。其语句格式是:

        for(expression1; expression2; expression3){
            循环体
        }

expression1的作用是初始化变量;expression2是一个循环控制语句,返回一个布尔值;expression3用于控制变量的递增或递减,即用于控制循环次数。

循环控制语句返回一个布尔值,为true时,继续执行下面括号中的循环体;为false时,停止循环。

使用PHP的for循环,需要记住以下几点规则:

❑第一个表达式expression1在第一次循环时自动进行运算。

❑第二个表达式expression2在每次循环时进行计算。这个表达式用来确定是否继续循环。

❑第三个表达式expression3在每次循环结束时进行计算。

❑任何一个表达式都可以为空,它们可以由for块内部的逻辑所取代。

3.10.2 条件判断语句

顺序结构的程序虽然能解决计算和输出等问题,但进行判断后就不能再选择了。对于要先做判断再做选择的问题就要使用分支结构,这种结构又称为选择结构或条件结构。分支结构的执行是依据一定的条件选择执行路径,而不是严格按照语句出现的物理顺序执行。分支结构程序设计方法的关键在于构造合适的分支条件和分析程序流程,根据不同的程序流程选择适当的分支语句。分支结构适合于带有逻辑或关系比较等条件判断的计算。即程序在执行过程中依照条件的结果来改变程序执行的顺序,满足条件时执行某一语句块,反之则执行另一语句块。

1. if语句

if、else和else if语句经常一起被使用,这3个语句中只有if可以单独使用,而else和else if语句则需要与if语句结合使用。

语句格式:

        if(condition)
        {
            statement
        }else if(condition){
            statement
        }else{
            statement
        }

else if语句在if的condition为false时,逐个往下执行,若condition为true时,则执行内部的statement;若没有,则继续向下查看else if语句。若所有else if的condition为false,有else语句则执行else语句内的statement,没有则继续往下执行。

if else语句内部仍可套用if else语句来做更细致的判断。可根据下面的代码来修改$num的值来查看判断的流程。

          <?php
          $num = 5;
          if($num>3){
              echo 'num>3<br/>';
              if($num<6){
                echo 'num<6<br/>';
              }else{
                echo 'num>=6<br/>';
              }
          }else if($num<3){
              echo 'num<3<br/>';
              if($num>-1){
                echo 'num>-1<br/>';
              }else if($num<-1){
                echo 'num<-1<br/>';
              }else{
                echo 'num=-1<br/>';
              }
          }else{
              echo 'num=3<br/>';
          }
          ?>
2. switch语句

对于条件判断结果很多的情况,如果使用if语句将会变得非常麻烦,这时可以使用switch选择语句。语句结构:

        switch($temp)
        {
            case 'value_1': statement; break;
            case 'value_2': statement ; break;
            case 'value_3': statement ; break;
                    ·
                    ·
            default: statement;
        }

执行流程:从第一个case开始判断,若$temp的值等于value_1,则执行case 'value_1'冒号后面的语句,若没有则继续向下执行。若执行语句后有break,则case找到对应的语句执行完后直接跳出switch语句;若没有break语句,则将后面所有case语句的statement都执行一遍,直到遇到break才跳出。default可写可不写,当遍历所有case后都没有与$temp对应的值时,则执行默认的default语句。

switch语句在多个值匹配一个变量的情况下非常管用,虽然if else语句也可以实现同样的效果,但switch语句执行起来更快捷、更简单,而且更稳定,遇到复杂的逻辑判断时语句结构也一目了然。

3.11 小结

本章介绍了PHP的工作原理及发展状况,并通过一些简单的示例对PHP基础语法、变量和常量、数据类型、数据类型之间的转换、表达式和运算符,以及流程控制语句等知识点进行了介绍。掌握这些基础知识将会为以后更好地掌握PHP打下坚实基础。