Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5120114
  • 博文数量: 921
  • 博客积分: 16037
  • 博客等级: 上将
  • 技术积分: 8469
  • 用 户 组: 普通用户
  • 注册时间: 2006-04-05 02:08
文章分类

全部博文(921)

文章存档

2020年(1)

2019年(3)

2018年(3)

2017年(6)

2016年(47)

2015年(72)

2014年(25)

2013年(72)

2012年(125)

2011年(182)

2010年(42)

2009年(14)

2008年(85)

2007年(89)

2006年(155)

分类:

2006-11-19 14:16:06

什么是PEAR?(第五篇)

第四章 如何使用套件

从第一章与第二章,大致上大家应该了解PEAR的意义,从第三章,也知道了PEAR基本套件与指令的安装方法。我们好不容易,搞定了使用PEAR套件的前置工作,接下来就可以一步步来感受PEAR的強大威力,相信大家已经迫不及待了。

使用PEAR,大致上只需三个步骤,第一步是安装套件,第二步是引用套件,第三步是使用套件。

▓ 安装您需要的套件

各位还记得第二章我曾经介绍一个Benchmark套件的show.php范例档吗?那是一个计算网页执行时间的范例程式。笔者再呈现一次原始码如下,借由该原始码来說明如何使用PEAR套件,並为了方便我来解說,特別在程式码前加上行号:





短短11行的程式码,除了第6行与第10行我用echo( )函式显示「Hello World」字串与「本页执行时间为秒」字串外,其余的程式码都是与Benchmark套件有相关性的。

假设已经安装好了PEAR的基本套件,但卻尚未安装Benchmark套件,若直接执行show.php的话,会出现以下画面:






執行結果告訴我們,執行的過程中,發生了錯誤,並有兩個警告訊息:

● 第1個警告訊息是程式執行到show.php檔的第二行時發生錯誤,錯誤的原因是無法開啟Benchmark/Timer.php檔。

● 第2個警告訊息是說在include_path的路徑下找不到Benchmark/Timer.php檔。

這兩個錯誤訊息其實所指的是同一件事情,當程式碼的第二行要引用Benchmark資料夾中的Timer.php檔時,系統會先在show.php檔的同一路徑下找尋Benchmark資料夾,若找不到,再轉到php.ini檔中,include_path所指的路徑中去尋找Benchamrk資料夾。

錯誤訊息告訴了我們,在以上兩個地方都找不到Benchmark資料夾與Timer.php檔,這是當然的,因為我們尚未安裝Benchmark套件,系統找不到是必然的。

所以我们用指令安裝的方法來安裝Benchmark套件,只要使用:





这个指令,就可以了,安装画面如下:






最后一行出现install ok代表安装成功了。大家来重新整理一次show.php档的执行结果,出现如下画面。







这一次沒有出现错误讯息了,因为系统会在include_path所指定的路径中顺利地找到Benchamrk资料夹与Timer.php档。这两者都是刚才安装Benchmark套件时被安装上去的。

由执行结果可看出我们已经成功执行Benchmark套件中的时间计算功能了。这可是本书第一个使用PEAR套件完成的php档。

请注意,若前一章所提的php.ini档中的include_path的值若沒有设定正确的话,仍然会出现错误讯息喔,而且windows系统与Unix系统的路径写法是不同的,请不要混淆。

若您真的不会修改include_path,也可以用手动的方式,将Benchamrk套件下载,解压缩后将Benchmark资料夹放置到与show.php相同的路径处,这樣也是可以达到引用套件的效果,不过这不是一个好方法,尽量使用「套件管理指令」与修改include_path的方法吧,才不枉PEAR团队想帮开发者节省时间的一番苦心。



▓ 引用套件

第一个步骤安装套件完成后,第二个步骤就是引用程式库,笔者所谓的引用,就是某一个php档?与其他的档案结合的意思,例如上述的例子,show.php虽然只是单一个php档?,但程式码中因为有第2行的





将使得show.php档执行时会在第2行插入並执行Timer.php档的內容。

Php引用其他档案的方法是利用4个內建函式,分別是:

● Include( )

● Require( )

● include_once( )

● require_once( )

这4个函式可以互相取代,也就是說show.php的第2行也可以改写为:

















这4种写法,程式执行的结果是一樣的,差別在於include_once( )和require_once( )函式若发现某一个档案已经在其他引用档中被引用过了,将不会再次引用,也就是可以避免重复引用同一个档案,这樣子可以节省系统资源以及防止错误发生。因此笔者撰写php时若有需要引用其他档案,都使用include_once( )或require_once( ),而不用include( )或require( )。



这4种引用的方式,会先从档案本身所在位置去寻找被引用档,若以show.php范例档来說,当系统执行第2行的程式码时会先在show.php档所在位置寻找是否有一个资料夹名为Benchmark,且资料夹中是否有一个名为Timer.php的档。

若寻找不到,将转而寻找php.ini档中所记载的include_path所指定的路径。若在include_path的路径下也找不到,PHP就会将错误讯息显示在浏览器上。

本例中,系统执行show.php档的第2行时,是在include_path所指定的路径下找到Benchmark资料夹与其中的Timer.php档。

所以若沒有正确地设定php.ini中的incluede_path的话,就必须用絕对路径来引用档案,也就是說在Windows系统中,第2行应改写为:





在Liunx中第二行应改写为:





在旧环境的FreeBSD中第二行应改为:





在新环境的FreeBSD中第二行应改为:





因为在前一章中,笔者的php.ini档有做正确的include_path设定,将路径指到PEAR套件安装后所在位置。也因此可以在引用档案时撰写较少的程式码,不用麻烦地使用絕对路径,而且,若有一天笔者要在这两种不同类型的系统中移转PHP档? 时只要修改php.ini档就可以了,不用改写路径的程式码,这就是设定php.ini档include_path值的好处。

▓ 剖析原始码

第3个步骤是使用套件,但在介绍如何使用套件內的程式库前,笔者必须先介绍一些PHP物件导向程式设计的基本概念,甚至於,我们必须进入程式库的原始码来了解一下程式库的真面目。


◆ 为何要閱读原始码

可能您会說,会用套件就好了,何必去了解原始码?看原始码总是让人头昏眼花。笔者认为,这话虽不错,套件的程式库通常是既強大又完整,您也许不用看原始码,透过閱读使用說明或范例程式,也可以将套件功能使用的很好。

但我认为,透过閱读原始码,除了可以学习php的程式撰写,提升使用者的php功力外,也可以了解套件的功能是如何作用与啟动的,最重要的是若使用套件的过程中发生问题,可以借由检视原始码来排除错误,另外,也可以将套件输出到网页的讯息中文化。

本章仅就使用套件所需要的概念作介绍,也就是說若您只想单纯的使用套件的程式库,並不想管程式码的运作方式,那麼以下的內容应该就足夠了。至於较完整的PHP物件导向程式设计,笔者留待下一章再来详谈。


◆ PEAR套件的程式码共同的特点

先前提过,PEAR团队订定了一些程式码的基本规则来让套件开发者遵守,也因此,PEAR套件有许多的共同点:

① 所有套件都採用物件导向的方式撰写程式码:我认为只有学习了PHP物件导向的原理,才能享用物件导向所带来的強大功能与方便性,而本章将带到一些php物件导向程式设计的概念,若您对php的物件导向程式设计已经非常了解,或者你只想单纯当个套件使用者,不想观看原始码的话,以下內容可以跳过,直接去看第五章吧。

② 所有套件中php程式的撰写都有一定的格式:在PEAR官方网站中的使用手冊有针对php的撰写格式订定一定的规范,若要参与套件开发的程式开发者,都必须遵守此规范。我举个例子:开发者撰写php程式若需要缩排,一律须缩排四个空白,诸如此类。其他还有许多规则,请有心者自行参閱PEAR官方网站。这樣做对使用者最大的好处是:让程式码整齐有条理,閱读起来较不费力。

③ 所有套件中每一段程式码前都有详细的註解:更重要的是註解也有一定的格式,因为PEAR中有一个phpDocumentor套件,可将註解从程式中抽离出来加以解析,並自动编制成使用說明文件或使用說明网页,让开发者不用额外撰写使用指南。这个套件希望在我另外的文章中能夠介绍。


◆ 套件的程式码內容

套件中的程式码大致上可分为四个部份;


1. 註解

2. 引入其他PEAR套件档

3. 类別

4. 属性与方法

笔者将在以下子单元加以說明:

▲ 註解

下面我以Timer.php档为例来說明,这个档存在於Benchmark套件中,我在自行撰写的范例挡show.php中曾被加以引用。Time.php档前1-16行:






除了第1行的“< ?php”代表PHP程式的起始外,每一行前面都加上双斜線“/ /”符号,代表这16行都是註解。

PEAR套件中的php档有个特色,一开始都会对套件作版权宣告,並註明开发者姓名、E-mail Address、套件的官方网站网址、开发日期等资讯,这16行就是在說明这些,读者有兴趣者可自行閱读。

接著17-48行,开始用註解对Timer.php中的內容做整体性的說明,这些註解都放在「/*」与「*/」中间,每一行前面另外加上「*」,这是phpDocumentor?这个用来解析註解与產生文件的套件所要求的规定。反正,还是註解就对了。有趣的是,註解中还有范例程式,作者真是有夠贴心的。






我为了說明上的方便把第一种註解称为「套件资讯註解」,第二种註解称为「使用說明註解」。以下都用这两个名词称呼之。


▲ 引入

所有PEAR套件的原始码都会先来一段「套件资讯註解」与「使用說明註解」后,接著的才是真正会被系统执行的程式码,但请注意,每一段程式码之前,程式的作者通常还会附上一段註解来說明该段程式码的功用,这些註解笔者称为「细部功能註解」。

第50行是引入PEAR.php档,这个档是所有PEAR套件都要引用的档,因为一些广域变数(Global Variables)的设定都在这个档中,这些广域变数是所有套件都会用到的。

安装基本套件时会安装一个「名为PEAR的套件」,这个PEAR.php档就是当时被安装上的。

请读者注意,笔者通称「PEAR套件」时,是泛指所有PEAR的套件,目前共有272个,但这些套件中,有一个很特別的套件,这个套件的名称就叫做PEAR,这个套件是所有套件的根源,安装基本套件时,一定会安装这个套件。为了怕读者混淆,笔者称为这个套件为「一个名为PEAR的套件」用来与「PEAR套件」做区隔。




除了PEAR.php外,有些套件的php档会引入其他套件的php档,这就是所谓的「套件相依性」,若有这种现象,该套件安装前就需要先安装有引用到的档案的套件。例如Cache套件的原始档有引用到Auth_http套件的原始档,因此安装Cache套件前要先安装Auth_http套件。



▲ 类別

第52行开始进入程式的主要內容,首先用class这个关键?字宣告一个名为Benchmark_Timer的类別,后面接著的「extends PEAR」代表这个Benchmark_Timer类?別是「继承自PEAR类別」。

大多数PEAR套件內的PHP档,一个档只含一个类別,Timer.php就是一个例子,这个档的內容就是一个名为Benchmark_Timer的类別,沒有其他类別了,这樣的作法有个好处,就是可以将程式码做适当的区隔,方便管理与閱读。Benchmark_Timer类?別的架构如下:






大家可能会问,何谓「类别」?那来的「PEAR类別」?

「继承」是一个物件导向程式设计方面的专有名词,第五章笔者再详细的介绍,但可以简单地用比喻的方式来說明:Benchmark_Timer类?別就像PEAR类別生出来的小孩,PEAR类別拥有的特性,它都有,且除了继承PEAR的特性外还有属於自己的特性。

另外,PEAR类別在那儿呢?並沒有在档案中看到「class PEAR」?

PEAR类別是记载在PEAR.php档中,並不在Timer.php裡面,所以Timer.php需要先引用PEAR.php档,这个继承才会有效,若沒有引用PEAR.php档,浏览?器上会出现继承错误的讯息喔。

那什麼又是”类別”?

笔者把「类別」比喻成「工厂」,工厂是用来生產物品的地方,我们居住的现实世界拥有各式各樣的工厂,生產各种不同的物品,供人类使用。


请注意,生活中各种不同的物品都具有各自的外型与功能,例如铅笔与纸张就是外型与功能不相同的两种物品,他们也由不同的工厂所制造。同樣的,php的世界中程式开发者也可以建立各种生產不同產品的工厂,也就是不同的「类別」来生產各式各樣的「物件」供开发者使用。

每个类別都具有「属性」与「方法」,当透过「类別」生產「物件」时,每个「物件」都会拥有类別所指定的属性与方法。

笔者举个例子,假设有一个名为「钉书机」的类別,这个类別中註明它拥有「大小」、「顏色」与「材质」三个属性,另外,还註明它拥有「钉」这个方法。若用工厂的概念来說的话,钉书机工厂所生產的钉书机都会有大小、顏色与材质三个属性,它有可能生產小型黑色的钉书机,也可能生產大型白色的钉书机,另外,他可以生產铁制的钉书机,也可以生產塑胶的钉书机,但是不管哪一种钉书机,都可以将纸张「钉」在一起,也就是具有「钉」的功能。

开发者若要使用这个类別,可以自行決定「大小」、「顏色」与「材质」,例如「小」、「红色」与「铁」,在生產物件时,就可以產出无数个小型红色的金属订书机物件,且每个订书机物件都具有「钉」这个方法可以使用。

在第一个范例档show.php中的第3行:





这一行的new Benchmark_Timer( )就是一个「生產」Benchmark_Timer物件的方式,並将產生的物件放入$timer这个变数中,也就是由这个变数代表一个生產新的Benchmark_Timer物件,new关键字的意思就是宣告一个新的物件。

使用者可以一次生產出许多Benchmark_Timer物件,例如:





上例中,$timer1与$timer2都是Benchmark_Timer物件,但卻是互相独立的物件,彼此的运作並无相关性。就如同一家订书机工厂生產的两个外型与功能都相同的红色订书机,这两个订书机並无相关性,其中可能一个被某一个美女买去,另一个被某一个小学生买去,当美女使用订书机时並不会影响小学生使用订书机。
阅读(1203) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~