第19章 使用PHP扩展与应用库(PEAR)加速开发
在PHP网站开发中,PEAR不得不提,其是PHP的扩展和应用程序库,涵盖很多有用的类库,而PEAR的安装也非常方便,下面来和大家分享在Windows系统下PEAR的安装与使用方法。
19.1 PEAR介绍与安装
PEAR是PHP的官方开源类库,是PHP Extension and Application Repository的缩写。PEAR将PHP程序开发过程中常用的功能编写成类库,涵盖了页面呈面、数据库访问、文件操作、数据结构、缓存操作、网络协议等许多方面,用户可以很方便地使用。它是一个PHP扩展及应用的一个代码仓库,简单地说,PEAR就是有组织的类的集合。
使用PEAR能带来的好处如下。
- PEAR按照一定的分类来管理PEAR应用代码库,所以读者可以将自己的PEAR代码组织到其中适当的目录中,那么其他的人就可以方便地检索并分享到你的成果。
- PEAR不仅仅是一个代码仓库,它同时也是一个标准,使用这个标准来书写PHP代码,将会增强程序的可读性,复用性,减小出错的几率。
- PEAR通过提供2个类为使用者搭建了一个框架,实现了诸如析构函数、错误捕获功能,使用者只需通过继承就可以使用这些功能。
在了解了什么是PEAR以后,就来介绍如何安装它。
注意 通常PHP版本在大于4.3.0的情况下,是自带有PEAR包并默认安装的。如果使用的PHP版本比较早,或者因为特殊原因没有安装PEAR包,那么可以使用如下方式安装。
(1)首先介绍在Windows系统中的安装方法,当下载和安装完成PHP以后,进入PHP的安装目录,找到“go-pear.bat”这个批处理文件,双击执行。会出现一个命令行窗口,如图19.1所示。
图19.1 PEAR安装命令行窗口
(2)提示是需要安装整个系统都可用的PEAR还是一个本地的拷贝。这里默认的是system,直接按回车键,出现如图19.2所示的窗口。
图19.2 PEAR安装信息
(3)显示关于PEAR安装的一些信息,这里默认即可。继续按回车键,首先会显示一些安装的过程,最后出现如图19.3所示的安装成功结果。
图19.3 PEAR安装成功
安装成功以后,会提示需要注册相关路径的环境变量。很方便的是,执行这个批处理程序后,它会自动在PHP目录下生成一个“PEAR_ENV.reg”的注册文件,只需双击它就可以。之后就可以使用命令行窗口进入PEAR的安装目录来运行PEAR这个命令。
如果需要升级PEAR,可以使用浏览器访问http://pear.php.net/go-pear,之后将这个页面的内容另存为本地文件,命名为“go-pear.php”。在命令行窗口中,使用如下命令来更新PEAR库。
php go-pear.php
如果需要安装某个特定的类库,比如安装MDB2,可以使用如下语句:
pear install MDB2
有些类库还需要安装特定的子类,比如MDB2就有很多数据库子类。下面的代码演示了如何给MDB2安装mysql的驱动:
pear install MDB2#mysql
最后说一下在UNIX/Linux/BSD系统中PEAR的安装方法。其实很简单,只要执行一个语句,如下所示:
$ lynx -source http://pear.php.net/go-pear | php
19.2 用PEAR快速创建表单
通过上一个小节的介绍,相信大家都知道什么是PEAR,而PEAR::HTML_QuickForm是PEAR中的一个非常实用的类库。使用它,可以动态地创建、验证和显示HTML表单。本节就来介绍如何使用HTML_QuickForm这个类来快速创建表单。
在使用HTML_QuickForm类之前,需要引入这个类。使用如下语句:
require_once 'HTML/QuickForm.php';
QuickForm.php是这个类的主文件,它在PEAR安装目录的“HTML”目录下。之后就可以创建该类的对象,类似如下语句:
$form = new HTML_QuickForm('quickForm');
创建了一个HTML_QuickForm的对象,并且它的name属性为“quickForm”。因为没有给其他参数赋值,所以其他的表单属性将会使用默认的值。比如method方式默认为“POST”,target属性默认为当前页面等。
在创建表单对象后,使用它的成员函数addElement为其添加各种表单元素,addElemment()的三个参数分别表示类型、名称、显示的文字。
$form->addElement('header', 'header', '请登录'); $form->addElement('text', 'name', '用户名:'); $form->addElement('password', 'password', '密码:'); $form->addElement('submit', 'submit', '提交');
第1行代码添加的并不是一个“真的”表单元素,它在这里的作用是显示这个表单的标题。第2行和第3行代码分别为表单添加一个文本框和密码输入框。第4行则创建一个提交按钮,用于表单的提交。此时这个HTML_QuickForm对象已经有了表单需要的所有必要元素,可以使用如下语句输出这个表单。
$form->display();
但显然这不是使用QuickForm的主要原因,因为使用一些可视化的工具来创建表单会更快一些。
QuickForm的主要功能不是在使用PHP创建表单上,而是创建完成以后自带对表单的验证功能,而且可以在客户端验证也可以在服务器端验证。表19.1所示是PEAR::HTML_QuickForm自带的验证规则。
表19.1 PEAR::HTML_QuickForm自带的验证规则
接下来就来对用户名和密码加验证,指定用户名为英文字符,而且长度不能少于6个,密码需要在6~12个字符之间。下面是添加相应验证规则的语句。
$form->addRule('name','用户名不能为空!', 'required'); $form->addRule('name','用户名必须为字母或数字!', 'alphanumeric'); $form->addRule('name','用户名必须为6位以上字母或数字', 'minlength', 6); $form->addRule('password','密码不能为空!', 'required'); $form->addRule('password','密码必须为6位以上!', 'minlength', 6); $form->addRule('password','密码不能超过12位!', 'maxlength', 12);
以上代码是服务器端加的验证,如果需要在客户端加验证,只需在此基础上,追加一个参数设置为“client”即可。例如需要在客户端验证用户名,并规定不能为空的代码如下:
$form->addRule('name','用户名不能为空!', 'required', ‘client’);
最后使用QuickForm对象的validate方法来对这个表单进行验证,使用如下语句:
$form->validate();
至此一个表单的验证结束。验证成功之后,还需对表单进行处理。比如登录成功之后会出现友好的提示信息等。这时需要用到的是QuickForm对象的process方法。代码19-1是使用QuickForm做的一个快速表单创建与验证的例子,如下所示。
代码19-1 用PEAR快速创建表单
<span class="kindle-cn-bold">用PEAR快速创建表单</span><hr /> <?php require_once 'HTML/QuickForm.php'; //载入HTML_QuickForm类 $form = new HTML_QuickForm('quickForm'); //创建HTML_QuickForm对象 $form->addElement('header', 'header', '请登录'); //添加表单标题 $form->addElement('text', 'name', '用户名:'); //添加用户名输入框 $form->addElement('password', 'password', '密码:'); //添加密码输入框 $form->addElement('submit', 'submit', '提交'); //添加提交按钮 $form->addRule('name','用户名不能为空!', 'required'); //设置用户名不能为空 $form->addRule('name','用户名必须为字母或数字!', 'alphanumeric'); //用户名必须为字母和数字 $form->addRule('name','用户名必须为6位以上字母或数字', 'minlength', 6); //6位以上字母或数字 $form->addRule('password','密码不能为空!', 'required'); //必填项 $form->addRule('password','密码必须为6位以上!', 'minlength', 6); //6位以上 $form->addRule('password','密码不能超过12位!', 'maxlength', 12); //12位以下 if ($form->validate()) { //服务器端验证表单 $form->process('pass_hello'); //成功后执行处理函数 } else { $form->display(); //显示表单 } function pass_hello($data) { //验证成功后调用的处理函数 print '你好, ' . $data['name']; //输出用户名 print '<br />'; //换行 print '你输入的密码是 '.$data['password']; //输出密码 } ?>
以上代码的具体实现步骤已经做了讲解,需要注意的是最后的验证处理函数。该函数接收一个数据输入参数,当表单提交并被验证成功后,此参数就包含有表单提交的数据。运行代码后,出现如图19.4所示的初始页面。如果输入的用户名和密码不符合验证要求,就会出现相应的提示信息,如图19.5所示。如果验证成功,就调用处理函数,得到的结果如图19.6所示。
图19.4 快速表单初始页面 | 图19.5 验证失败 |
图19.6 验证成功
19.3 用PEAR轻松实现身份验证
几乎所有的Web程序都有用户的身份验证的功能,而身份验证的方式也有很多种。比如,数据库身份验证、LDAP身份验证、POP3身份验证、IMAP身份验证等。而PEAR的Auth类提供对几乎所有验证方式的支持。本节就来讲解使用PEAR来实现最常用的数据库身份验证的方法。
开始前需要导入Auth类,使用语句如下:
require_once ('Auth.php');
下一步需要定义一个函数来创建一个登录表单。这个函数在将一个没有被认证的用户访问页面时被调用。这个表单需要使用POST方式传输数据,并且需要有两个文本输入框,其name值分别为username和password。
这时,对于基于数据库的身份验证,需要在选项数组中创建一个连接数据库用的“DSN”字符串。这个字符串包括需要使用的数据库类型、登录数据库用的用户名和密码及所在主机地址等。可能的代码如下所示:
$options = array('dsn' => 'mysql://username:password@localhost/databasename');
现在已经有两个事物被定义,创建登录表单的函数和连接数据库的DSN,这时就可以创建一个Auth类型的对象。创建这个对象需要3个参数:身份验证的类型(比如数据库、文件等),关于身份验证的相关选项和登录函数的函数名。如下所示:
$auth = new Auth('DB', $options, 'login_form_function_name');
第一个参数的设置为“DB”,用来告诉PEAR验证时需要使用DB包。如果想使用文件系统来替换验证方式,则需要替换第一个参数为“File”,且要将第二个参数设置为文件的目录。
可以使用如下语句来开启身份验证:
$auth->start();
此后,就可以调用身份验证对象的checkAuth()方法来对身份进行验证,代码如下:
if ($auth->checkAuth()) { //验证通过后的处理 }
以上是使用PEAR实现身份验证的简单步骤。结合以上所学的知识,就可以做一个基于数据库的身份验证实例。在此之前,需要在数据库中创建身份验证所使用的数据表并填充用户数据。创建的表结构和插入的数据如下SQL语句所示:
CREATE TABLE `auth` ( `user_id` int(11) NOT NULL auto_increment, `username` varchar(50) NOT NULL, `password` varchar(50) NOT NULL, PRIMARY KEY (`user_id`) ) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; INSERT INTO `auth` VALUES ('1', 'test', '098f6bcd4621d373cade4e832627b4f6'); INSERT INTO `auth` VALUES ('2', 'demo', 'fe01ce2a7fbac8fafaed7c982a04e229');
注意 在插入用户数据时,使用的密码是经过md5加密后的字符串,因为Auth的密码认证方式码是默认md5加密的。
代码19-2是实现这个验证过程的一个例子,如下所示:
代码19-2 用PEAR轻松实现身份验证
<?php require_once ('Auth.php'); //载入Auth类 function show_login_form() { //创建登录表单的函数 echo '<span class="kindle-cn-bold">用PEAR轻松实现身份验证</span><hr />'; echo '<form method="post">'; echo '<p>用户名:<input type="text" name="username" /></p>'; echo '<p>密 码:<input type="password" name="password" /></p>'; echo '<input type="submit" value="登录" />'; echo '</form><br />'; } $options = array('dsn' => 'mysql://root:@localhost/demo'); //设置连接数据库的DSN $auth = new Auth('DB', $options, 'show_login_form'); //创建Auth对象 $auth->start(); //开启身份验证 if ($auth->checkAuth()) { //如果验证成功 echo '<span class="kindle-cn-bold">用PEAR轻松实现身份验证</span><hr />'; echo '<p>你已经成功登录,并可以访问本页面了!</p>'; } else { //验证失败 echo '<p>你需要登录后才能访问本页。</p>'; } ?>
以上代码的具体步骤如前面介绍的一样,这里就不多做讲解。运行后,首先出现如图19.7所示的登录表单。输入用户名和密码后(这里都为demo),出现如图19.8所示的欢迎信息。
图19.7 身份验证表单 | 图19.8 身份验证成功 |
在这个示例代码中,只需要按照步骤一步一步做下来,并不需要对数据做其他额外的操作。这个就是使用PEAR的Auth类来实现身份验证的方便之处。在使用这个类创建用户验证时,需要做的只是在数据库中插入用户数据。
19.4 用PEAR实现数据库接口统一
用于存储数据的数据库很多,比如MySQL、MSSQL、PostgreSQL、Oracle、SQLite等。可能开始时使用的是一种数据库,可是到后来因为某些原因需要使用另外一种数据库,或者多种数据库并存的现象,这时如果先前对数据库操作的代码只支持一种的话,那么导致的后果是直接重写代码。所以,市场上已经有了对多种数据库操作都支持的类,比如PHP的PDO类,还有ADODB等都是很好的解决方案。
而PEAR也为PHP开发者提供了MDB2这个类来解决这个问题。MDB2的前身是PEAR的DB类,从使用的代码中会发现,它们有很多相似的地方,但是现在已经被弃用。而MDB2则为数据库操作提供了更好的支持和新特性,所以本节就来讲解如何使用MDB2来操作数据库。
当脚本使用PEAR的MDB2接口访问MySQL的时候,通常需要经过下列步骤。
(1)引用MDB2.php文件以便访问PEAR的MDB2模块。
(2)通过调用connect()连接到MySQL服务器,并获得一个连接对象。
(3)使用这个连接对象提交SQL语句,并取得生成的对象。
(4)使用结果对象检索语句返回的信息。
(5)当连接对象不再需要的时候,关闭服务器连接。
与使用其他的PEAR类一样,开始前都需要引入相应的类库。引入MDB2库的语句如下所示:
require_once 'MDB2.php';
MDB2提供两种连接方式:DSN和Socket,首选DSN。另外提供3个连接函数:factory()、connect()、singleton(),分别表示Efficient、Eager、Available连接。如果使用factory()函数,在调用的时候它并没有去连接数据库,只有在发送query请求的时候才会连接;connect()调用时立即连接数据库;而singleton(),顾名思义“单独”,即为一个进程建立一个单独的连接。
如果没有特殊情况,都使用connect()方式来连接相关数据库,连接的示例代码如下:
$dsn = 'mysql://someuser:apasswd@localhost/thedb'; $mdb2 =& MDB2::connect($dsn); if (PEAR::isError($mdb2)) { die($mdb2->getMessage()); }
以上的第1行代码是建立连接所需的数据源名称(DSN)字符串,定义连接所需的数据库类型、登录数据库用的用户名和密码及所在主机地址等。第2行代码就是使用MDB2类的connect方法来建立一个数据库的MDB2对象。在第3行判断数据库连接是否成功,不成功则输出相应的出错信息。
创建完成MDB2对象之后就可以使用它的方法来对数据进行查询。MDB2对象提供的两种查询方法分别是query()和exec()。使用它们分别产生两种结果:成功时返回执行结果和失败时返回MDB2_Error对象。但它们又有不同,query()是请求并取值,它一般用于SELECT、SHOW等,返回符合条件的数据;而exec()是执行的意思,所以它一般用于INSERT、UPDATE或DELETE,返回语句成功执行后所影响的行数。
下面是对数据查询的示例代码,假设已经建立MDB2对象$mdb2。
$res =& $mdb2->query('SELECT * FROM clients'); if (PEAR::isError($res)) { die($res->getMessage()); }
注意 当使用$mdb2->query()后得到的并不是数组矩阵,而是$mdb2对象,需要使用fetchOne()、fetchRow()、fetchCol()或fetchAll()来获得想要的值。
上面说到使用query()函数得到的返回值是MDB2对象而不是需要的数组格式数据,那怎样获得存储的数据内容呢?MDB2提供了取得数据的4种方法:fetchOne()、fetchRow()、fetchCol()和fetchAll()。分别表示:取一个,取一行,取一列,取所有(比如一个数组矩阵)。配合setFetchMode()方法使用,可以获取想要的数据形式。如需获得所有查询得到的数据,可以使用如下语句:
$data = $res->fetchAll();
最后,当连接对象不再需要的时候,关闭服务器连接。使用语句如下:
$mdb2->disconnect();
以上是使用PEAR的MDB2类来访问数据库操作的简单步骤。对于这个类库还有很多知识点没有讲解到,比如查询时变量的转义和使用预处理查询等。如果有兴趣更深入了解的朋友,可以到官方网站进一步深入学习。代码19-3是对以上步骤总结后的一个实例。
代码19-3 用PEAR实现数据库接口统一
<span class="kindle-cn-bold">用PEAR实现数据库接口统一</span><hr /> <?php require_once 'MDB2.php'; //引入MDB2类库 $dsn = 'mysql://root:@localhost/cdcol'; //定义DSN数据库连接字符串 $mdb2 =& MDB2::connect($dsn); //创建MDB2对象 if (PEAR::isError($mdb2)) { //判断是否出错 die($mdb2->getMessage()); //输出错误信息 } $sql = "SELECT * FROM cds"; //查询语句 $res =& $mdb2->query($sql); //开始查询 if (PEAR::isError($res)) //判断查询结果是否出错 { exit($res->getMessage()); //输出错误信息 } $data= $res->fetchAll(); //得到全部查询结果 if (PEAR::isError($res)) //判断是否出错 { die($res->getMessage()); //输出错误信息 } else { echo '<pre>'; print_r($data); //输出结果 echo '</pre>'; } $mdb2->disconnect(); ?>
以上示例代码是对使用PEAR的MDB2类的一个简单总结,具体步骤与前面所讲解的一致。运行后,会打印出查询得到的结果,如图19.9所示。
图19.9 用PEAR实现数据库接口统一
19.5 用PEAR简化数据验证
数据验证简单说就是对数据进行检查,看是否符合一定的模式,通常用于表单数据。可以用它来确保一些元素非空、某个值必须是数字,以及确保E-mail地址中包含@字符。数据的验证既可在服务器方执行,也可在客户方执行。PHP用于服务器方的数据验证,而JavaScript及其他一些脚本语言可执行客户方的数据验证。因为这些任务很常见,所以PHP为此提供了一个名为Validate的PEAR包,除了完成上述验证任务,它还能完成许多其他的验证任务,还可以安装额外的规则来验证本地化数据的语法,例如一个澳大利亚电话号码。
PEAR提供的数据验证主要功能如下。
- 验证各种不同的日期格式。
- 验证数字(最小/最大,是否是十进制数)。
- email验证(正规语法验证,check domain name 是否存在,RFC822验证)。
- 字串验证(正规语法验证,是否包含数字英文字母,可输入最长或最短)。
- url验证(遵从RFC2396规定)。
- 多重栏位(multiple data)验证(可以同时验证上述功能)。
对于使用PEAR的Validate验证很简单,只要知道相应的验证函数和入参。下面就直接通过实例来进行讲述。代码19-4是使用这些验证的例子。
代码19-4 用PEAR简化数据验证
<span class="kindle-cn-bold">用PEAR简化数据验证</span><hr /> <?php require_once 'Validate.php'; //引入Validate验证类 $values = "2009-10-03"; //需要验证的日期 $opts = array( 'format'=> "%Y-%m-%d", //设置验证日期格式为年-月-日 'min' => array('02','10','2009'), //最小为2009-10-02 'max' => array('05','10','2009') //最大为2009-10-05 ); $result = Validate::date($values, $opts); //验证日期开始 if($result) { echo $result; //日期验证成功的输出结果 } else { echo "error"; //日期验证失败的输出结果 } echo "<br />"; $values = "hejunbin@yahoo.com.cn"; //需要验证的电子邮件地址 $options = array( 'check_domain' => true, //是否验证域名 //'fullTLDValidation' => true, //此选项如果为true,总是会返回false,可能是这个类的一个BUG 'use_rfc822' => true, //是否符合RFC822标准 'VALIDATE_GTLD_EMAILS' => false, 'VALIDATE_CCTLD_EMAILS' => false, 'VALIDATE_ITLD_EMAILS' => false, ); $result = Validate::email($values, $options); //验证电子邮件 if($result) { echo $result; //电子邮件验证成功的输出结果 } else { echo "error"; //电子邮件验证失败的输出结果 } echo "<br />"; $values = "12300,45"; //需要验证数字 $options = array( 'decimal' => ',', //允许数字间的分隔符 'dec_prec' => '2', //允许分隔符的数量为2个 'min' => '1000', //最小数值为1000 ); $result = Validate::number($values, $options); //验证数字 if($result) { echo $result; //验证数字成功后的输出 } else { echo "error"; //验证数字失败后的输出 } echo "<br />"; $values = "love php"; //需要验证的字符串 $options = array( 'format' => VALIDATE_NUM, //规定字符串的性质 'min_length' => '2', //最小长度为2 'max_length' => '1000', //最大长度为1000 ); $result = Validate::number($values, $options); //验证数字 if($result) { echo $result; //如果字符串验证成功后的输出 } else { echo "error"; //验证字符串失败后的输出 } echo "<br />"; $options = array( 'check_domain'=>true, //验证域名 'allowed_schemes' => array('http','https'), //允许的前缀 'strict' => ';/?:@$,' //允许的特殊字符 ); var_dump(Validate::uri('http://www.php.com/', $options)); //验证结果 //以下是多重栏位的验证 $values = array( 'amount'=> '13234,344343', 'name' => 'foo@example.com', 'mail' => 'foo@example.com', 'mystring' => 'ABCDEabcde' ); $opts = array( 'amount'=> array('type'=>'number','decimal'=>',.','dec_prec'=>null,'min'=>1,'max'=>32000), 'name' => array('type'=>'email','check_domain'=>false), 'mail' => array('type'=>'email'), 'mystring' => array('type'=>'string',array('format'=>VALIDATE_ALPHA, 'min_length'=>3)) ); $result = Validate::multiple($values, $opts); echo '<pre>'; print_r($result); echo '</pre>'; ?>
以上的代码中已经对PEAR的Validate所有验证方式给出参数说明和相应的示例。运行以上代码后得到的相应验证结果如图19.10所示。
图19.10 用PEAR简化数据验证结果
19.6 用PEAR缓存提升程序性能
对于频繁被访问的数据或者页面,是很有必要使用缓存来提升程序性能的。因为此类数据和页面被访问的次数越多,所消耗的系统资源越多。如果使用缓存技术来存取,那么下次就直接访问缓存中的数据就行。PEAR提供Cache组件来实现对数据和页面的缓存。具体的步骤如下。
首先与使用PEAR的其他类一样,需要引入相关类库。引入Cache类库的语句如下:
require_once 'Cache/Output.php';
然后需要设置缓存所保存的目录:
$cacheDir = './pear_cache';
请确认这个目录是可写的。Cache数据将会写入这个目录的子目录中。
设定完参数以后,就可以建立一个输出缓存对象:
$cache = new Cache_Output('file',array('cache_dir' => $cacheDir));
其中第一个参数表示我们使用基于“文件”方式的缓存,第二个参数是一个与缓存目录相关联的数组。
为了要区别请求的不同返回不同的缓存,还需要产生一个唯一的cacheID:
$cache_id = $cache->generateID(array('url' => $_REQUEST,'post' =>$_POST,'cookies' => $HTTP_COOKIE_VARS));
这里通过$cache对象的generateID()方法提供一个信息数组(URL,HTTP POST data和HTTP cookie)来独一无二地标识这个请求,与其他请求区分开来。
然后,还需要增加一个逻辑判断语句看对应于cacheID的缓存数据是否已经存在,如果存在,获取数据并结束脚本。
if ($content = $cache->start($cache_id)) { echo $content; exit(); }
最后将产生内容的代码放在以上逻辑语句之后,并结束使用cache对象。
echo $cache->end();
至此就是使用PEAR的Cache来对程序进行缓存的整个过程。下面分别使用一个无缓存的页面和一个有缓存的页面来进行一下对比,看看使用PEAR的缓存是否能提高性能。两个页面的代码分别如代码19-5和代码19-6所示。
代码19-5 没有使用缓存的页面
<span class="kindle-cn-bold">用PEAR缓存提升程序性能 - 不使用缓存</span><hr /> <?php echo "<p>这是用于演示的时间内容。</p>"; echo "当前时间是" . date('Y-m-d H:i:s') . "<br />"; //显示当前时间 ?>
以上代码为了演示,输出当前的系统时间。因为没有使用缓存每次刷新时间都会变化。首次运行后的效果如图19.11所示。刷新该页面后,显示的系统时间会随之变化,如图19.12所示。
图19.11 没有使用缓存的状态1 | 图19.12 没有使用缓存的状态2 |
由图19.11和图19.12可以知道这段程序并没有把页面数据缓存,而是把当前数据实时输出而已。
代码19-6 使用了缓存的页面
<span class="kindle-cn-bold">用PEAR缓存提升程序性能 - 使用缓存</span><hr /> <?php require_once 'Cache/Output.php'; //引用Cache_Output类 $cacheDir = './pear_cache'; //设置缓存目录,必须是可写的 //根据参数创建Cache_Output对象 $cache = new Cache_Output('file',array('cache_dir' => $cacheDir)); if (empty($_REQUEST['nocache'])) //如果nocache变量为空,使用缓存中的内容 { $cache_id = $cache->generateID(array('url'=>$_REQUEST,'post'=>$_POST,'cookies'=> $HTTP_ COOKIE_VARS)); //建立一个唯一的cache标识 } else { $cache_id = null; //想获得最新的内容,ID为空 } if ($content = $cache->start($cache_id)) //看cache ID对应的缓存内容是否可用 { echo $content; //缓存已存在,直接输出,并结束脚本 exit(); } echo "<p>这是用于演示的时间内容。</p>"; // 缓存中不存在该内容,生成新内容并写入缓存 echo "当前时间是" . date('Y-m-d H:i:s') . "<br />"; echo $cache->end(); // 把内容写入缓存 ?>
以上代码在实现本节所讲的所存页面所需要的步骤外,还添加了一个判断是否需要缓存最新内容的功能。当传递的参数“nocache”为空时,使用以前的缓存结果来显示。如果为非空,则显示最新的内容并缓存入文件中。该代码运行和刷新后的页面效果如图19.13所示。
图19.13 使用缓存的状态
19.7 典型实例
【实例19-1】用PEAR支持多个邮件后台接口。
在本书的第13章中已经介绍了使用系统自带的sendmail函数发送邮件,以及通过开源的PHPMailer类来发送SMTP和带附件的电子邮件的方法。同样地,PEAR也提供一个Mail邮件类,供选择使用。
PEAR的Mail支持不同类型的后台接口来发送电子邮件。但是其中有两个步骤是必不可少的。
(1)使用factory()方法创建一个指定的Mail后台类。
(2)使用send()方法发送邮件。
支持3种形式的邮件后台接口。
- mail,通过PHP内置的mail函数发送邮件。
- sendmail,通过sendmail程序发送邮件。
- smtp,直接通过smtp服务器发送邮件。
以下是一个使用SMTP来发送HTML格式邮件的例子,如代码19-7所示。
代码19-7 使用SMTP来发送HTML格式邮件
<?php require_once('Mail.php'); //引入Mail类 require_once('Mail/mime.php'); //引入发送HTML格式所需的mime类 $text = '不支持HTML时,显示的内容'; $html = '<html><body>这个是HTML内容!</body></html>'; $file = '/home/php/example.txt'; $crlf = "\n"; $hdrs = array( 'From'=> 'you@yourdomain.com', //收件时显示的邮箱地址 'Subject' => '测试HTML邮件' //邮件标题 ); $mime = new Mail_mime($crlf); //创建邮件所需的mime对象并设置换行符 $mime->setTXTBody($text); //设置文本内容 $mime->setHTMLBody($html); //设置HTML内容 $mime->addAttachment($file, 'text/plain'); //设置附件格式 $body = $mime->get(); //取得需要发送邮件的内容 $hdrs = $mime->headers($hdrs); //设置邮件的头信息 $conf = array( 'host'=> 'xx.xx.xx.xx', //smtp服务器地址,可以用IP地址或者域名 'auth'=> true, //true表示smtp服务器需要验证,false代码不需要 'username' => 'tester', //用户名 'password' => 'retset' //密码 ); $mail =& Mail::factory('smtp', $conf); //使用类的工厂函数创建mail对象 $mail->send('postmaster@localhost', $hdrs, $body); //发送HTML格式邮件 ?>
首先引入两个文件,其中“Mail.php”是发送邮件必须的类,“Mail/mime.php”发送HTML格式所需的mime类。
【实例19-2】用PEAR进行单元测试。
一个函数、一个类编写完成后,到底能不能正确工作呢?又怎么测试它?PHP 单元测试是个好办法,它提供了自动化测试的方法,使敏捷开发的自动化测试成为可能。
在PHP下进行单元测试,需要用到PHP单元测试的一个框架。这个单元测试框架随PEAR即PHP扩展库一起分发,所以需要首先安装PEAR的PHP单元测试扩展库。安装是通过网络从有关的站点实时安装的,所以安装的机器必须连接到互联网上。对于PHP来说,单元测试框架是PHPUnit2。可以使用PEAR命令行作为一个PEAR模块来安装这个系统:
pear channel-discover pear.phpunit.de pear install --alldeps PHPUnit2
在安装这个框架之后,可以通过创建派生于PHPUnit2_Framework_TestCase的测试类来编写单元测试。开始单元测试最好的地方是在应用程序的业务逻辑模块中。这里使用了一个简单的例子:实现对两个数字进行求和的函数的测试。为了开始测试,首先编写测试代码,如代码19-8所示。
代码19-8 用PEAR进行单元测试
<?php require_once 'PHPUnit2/Framework/TestCase.php'; //引入相应的测试类 function add( $a, $b ) { return 0; } //用于测试的函数 //测试类,继承自PHPUnit2_Framework_TestCase class TestAdd extends PHPUnit2_Framework_TestCase { function test1() { $this->assertTrue( add( 1, 2 ) == 3 ); } //断言 function test2() { $this->assertTrue( add( 1, 1 ) == 2 ); } //断言 } ?>
以上代码有很多特殊的地方,首先文件名要与测试类的类名一致,测试类都需要从PHPUnit2_ Framework_TestCase类派生,另外测试类中的测试函数名需要以“test”开头。在这段代码中定义一个函数add(),被调用时返回都是0。还有一个测试类,包含两个函数来测试这个add()函数。
在命令行下,使用如下代码执行测试:
phpunit TestAdd.php
因为add()函数得出的结果都是0,与实际想要的结果不同,所以测试失败,如图19.14所示。
图19.14 单元测试失败
现在把add()函数改成如下:
function add( $a, $b ) { return $a+$b; }
再次测试这个程序后,得到的结果如图19.15所示,表示测试成功。
图19.15 单元测试成功
19.8 小结
本章介绍了PHP的一个大类库PEAR,包括快速创建表单、轻松实现身份验证、实现数据库接口统一、简化数据验证、缓存提升程序性能等内容。PEAR是一个很优秀的类库,聚集了编程过程中常使用到的功能类库。熟练掌握这些类的使用方法,能很大程度地提高Web制作的速度和性能。
19.9 习题
1. 浏览PEAR的官方网站,了解一下现在PEAR都有哪些类库。
2. 简述使用PEAR有哪些好处。