实战PEAR(下半部份)
时间:2009-04-09 来源:guoguo-beijing2008
什么是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物件,但卻是互相独立的物件,彼此的运作並无相关性。就如同一家订书机工厂生產的两个外型与功能都相同的红色订书机,这两个订书机並无相关性,其中可能一个被某一个美女买去,另一个被某一个小学生买去,当美女使用订书机时並不会影响小学生使用订书机。 ------------------------------------------------------------------------ 什么是PEAR?(第六篇)
▲ 类別的属性 从第52-76行包含在 class Benchmark_Timer后的大括号“{”与“}”中,用var关键字定义的变数,在类別中称之为属性,由程式码可知Benchmark_Timer类別拥有markers,auto,strlen_max三个属性,属性名称的等号后面不是变数的资料型态就是变数的预设值,在本例中,markers是一个阵列(array)型态的变数,而auto变数的预设值是false,strlen_max变数的预设值是“0”。 所谓预设值,就是当开发者沒有特別指定时,就把某个变数以预设值当作变数的值。 当使用者用new方法產生Benchmark_Timer物件时,每个物件都会拥有这三个属性,我将new出来的Benchmark_Timer物件称为「时钟物件」,因为该物件是用来计算程式执行时所使用的时间。 通常程式开发者帮属性命名时会以属性的意义当名称,方便使用者可以「望文生义」。例如:markers代表「标记」,意思是对时钟物件做个记号,请注意,可设定多个标记,用来检查每个标记间时间间隔的多寡。而auto代表是否一开始就自动啟动时钟物件。strlen_max代表字串长度的最大值,str就是字串(string), len代表长度(length),max代表最大值(maximum),稍后我会用范例加以說明这些属性的用法。 ▲ 方法 Timer.php中提供了许多的方法,我只用第161-212行的程式码来加以解說,大家可看到5个被包在class Benchmark_Timer中用function开头的段落。这5个function就代表类別的方法,也就是說,这里有5个方法,名称为display方法、start方法、stop方法、setMarker方法、timElapsed方法,而每个方法內大括号“{”与“}”中的內容就是方法实际运作的程式码。display方法是用来将时钟物件的执行结果显示出来,start方法是用来啟动时钟物件,由此类推,由字面的意思就可大致知道方法的意义。 在前例show.php档中的第4行,$timer这Benchmark_Timer物件使用了start方法。
在前例show.php档中的第4行,$timer这个Benchmark_Timer物件使用了start方法。
◆ example1.php范例 为了帮助大家了解,我再撰写一个名为example1.php的档案,內容一樣是使用Benchmark套件,且为了解說方便,在每一行前面我编上了行号。完整程式码如下: 首先,第2行引入Benchmark资料夹中的Timer.php档。
为了让大家了解类别与物件的关系,特別在第3行、4行產生两个Benchmark_Timer物件,並分別放入$timer1, $timer2变数中。也就是說產生了两个时钟物件,请注意,这两个物件虽然长的一模一樣,但使用上是互不相干的。 在第5行中,第一个时钟物件啟动,$timer1物件用start方法开始计时,请您想像有一个时钟按下开关开始计时。接着在第6行用php內建的sleep( )函式让程式的执行停顿一秒。 第7行接着啟动第二个时钟,请您想像第二个时钟按下开关开始计时。并在第8行让程式在停顿一秒钟。 第9行用setMarker方法,设定$timer1物件的marker属性,並将此时间鲇标记命名为mark1字串。其实在物件使用start方法与stop方法时,setMarker方法也会自动被执行,並将开始与结束的时间点标记名称设为「Start」与「Stop」。 第11行用timeElapsed方法计算$timer1时钟物件从啟动到mark1标记,程式执行所使用的时间,相当於计算第1行到第9行的执行时间,並用”秒”为单位将时间差显示出来。这个方法有两个参数,第一个代表开始计算时间的标记名称,第二个代表结束计算时间的标记名称,所以分別填入「Start」与「mark1」字串。 第13行再让程式休息一秒。 第15行用stop方法将第一个时钟物件停止,也就是结束第一个时钟的计时,並将时间的使用情形用display方法完整显示出来。 第18行用stop方法将第二个时钟物件停止,也就是结束第二个时钟的计时,並在第19行将时间的使用情形用display方法完整显示出来。 OK ! example1.php大功告成。 执行结果如下图:
让我们将执行结果对照一下程式码,在第5行时第一个时钟物件啟动,到第9行该物件设定一个名叫mark1的标记,中间经过了第6行与第8行两个sleep(1),所以从5-9行总共使用約2秒的时间,显示在网页上的结果是1.999727秒,嗯,果然符合预期。 接著对照第一个时钟物件在网页上display的结果。 您会发现Benchmark_Timer物件的display方法会将时钟物件的执行过程用一个表格做完整的呈现。 第一个表格最下面的总时间列total告诉我们,从开始到结束第一个时钟物件总共用掉2.999583秒,其中从啟动到mark1用掉了1.999727秒,mark1到停止用掉了0.999856秒,检视原始码第9行设定mark1到第15行计时停止中间第13行也有一个sleep(1),所以计时的结果是正确的。 第二个时钟物件的执行结果较为单纯,只有啟动与结束两种状況,由第二个表格可知总共用掉2.000141秒,对照原始码,从第7行的啟动到第18行的停止中间,第8与第13行各出现一个sleep(1),也就是約耗掉2秒钟,可见第二个时钟物件的执行结果也是正确的。 到目前为止,大家是否觉得PEAR套件超好用的呢,有了Benchmark套件,我们可以轻轻松松知道每个网页的执行时间。日后若发生了网页执行速度缓慢的情形,想知道问题出在何处,这可是一个很好用的工具喔!! 从第六章起,我们将逐一介绍几个常用的套件,这些套件的功能都是程式开发者使用率极高的,如资料库使用,表单的制作与验证?,翻页功能,简单的身分认证…等。虽然本文章无法将我所知道的套件全部介绍,但若能引起大家的回响,能够吸引更多人共同投入PEAR套件的研究。
◆ 寻求协助。 套件的使用,本人认为是先苦后甘,先要花时间了解套件的使用方法,这一段是「先苦」,但若学会了,以后自行撰写程式码可就轻松愉快了,这一段是「后甘」。 若使用或学习PEAR套件上遭遇了困难,该怎麼办呢?何处可寻求协助? 本人根据自身的经验,找出以下的管道供读者参考: ◆ 閱读本文章 閱读本文章当然是最佳选择了,目前PEAR的相关资料百分之九十九都是英文或其他语言,繁体? 中文或简体中文的资料真是少之又少。 我们计画将PEAR的研究心得继续在本网站里发布,目前因为中文PEAR的资料缺乏,希望尽己之力,为PEAR的內容多写一些介绍,同时继续研究和学习那PEAR中的272个套件,希望大家共同参与,并能够分享研究的成果。
◆ PEAR官方网站 在PEAR官方网站,您可以寻找套件,下载套件,閱读套件的简介,开发者姓名,說明文件等。这裡也有一些专家针对某些套件撰写的文章,或者您也可以察看套件被下载的次数统计等。总而言之,问题发生了,一定要试试来这裡找答案!!不过可惜的是,网站內容全是英文,閱读起来总是有些文化障碍。 详细內容请参閱PEAR官方网站介绍。
◆ mailing list 大家可在PEAR官方网站中加入使用者的mailing list,以我为例,每天E-mail信箱总会收到数十封标题有PEAR字樣的信,这些信的內容是全世界PEAR使用者将本身使用上发生的问题提问出来,借由mail来询问所有mailing list的成员,而热心的成员会对针这些问题加以解答並同樣mail给所有成员。 加入mailing list的缺点是,信箱必须夠大,因为信真的很多。 ◆ 套件內的說明与范例 有些套件很贴心的內附使用說明文件,甚至范例程式供使用者閱读与测试。这可让使用者节省许多探索套件用法的时间。 大家若要学习一个新套件,第一步总是会先到套件內寻找說明文件或范例。 ◆ 原始码 学习PEAR最直接的方法就是閱读原始码与註解。不过这真的有点困难,因为每个php档通常有数百行、甚至数千行的程式码与註解。幸好,物件导向的撰写方式让程式码「段落分明」,较易閱读,而且所有PEAR套件的註解都可以用phpDocumentor套件提供的指令将註解独立出来成为一份文件或网页,借由详细的註解来避免掉閱读大量的原始码。 ◆ Google
最后,若以上方法都找不到答案,我建议您使用史上最強的搜寻引擎-Google来找一找吧!
我也经常使用Google找到不少PEAR相关的文章或范例程式喔。 -------------------------------------------------------------------------- PEAR-像Google一样的分页功能(1) PHP/PEAR
Pager套件像Google一样的分页功能
介绍 读者应该行使用过Google这个超好用的搜寻引擎吧。每次搜寻后出现的资料数量总是多的令人吃一惊,有时甚至高达数千笔,数万笔。像如此多笔的数据是无法用一个网页来呈现的,Google的作法是将众多的搜寻结果以每页十笔、并在下方用页码超连结的方式来加以呈现,以下这个画面相信您一定不陌生:
这就是所谓的分页效果,当然资料数量庞大到无法用一个页面显示所有资料的时候,开发者往往会使用分页的功能来呈现数据。除了因为数据量大,无法用一页显示外,分页还可加快存取数据的速度,并让数据的排序显得井然有序。 在PEAR中,有一个专门针对「分页」功能来设计的套件,就是Pager套件。使用这个套件可让开发者用很简单的方式做到分页的效果,并且完全不必使用DB套件的1imitQuely() 方法来限制存取数据的范围,也不用撰写PHP来做翻页的超级链接。另外,套件内还提供许多设定项目让开发者根据本身的需求来调整分页的外观,更妙的是,可以在一个网页中放入多个分页效果。 安装 一开始安装PEAR的基本套件时,若读者是使用windows系统,就已经将Pager这个套件给安装起来了,也就是说,Pager是一个PEAR的必备套件。 若是使用Linux或FreeBSD系统,可能安装的基本套件中并不合Pager套件,这个时候请用“pear install pager”这个指令来安装。读者可以使用“pear list”指令来看看目前系统中是否已按装Pager套件,如下图:
以上图中笔者现有安装的套件为例,倒数第3个就是Pager套件,画面并显示版本编号为2.2.4,且stable版。若您曾经安装过的是旧版本,你可以升级现有最新的版本,请用“pager Upgrade pager”指令,将套件升级。本章提到许多功能需要在2.XX的版木环境下才可执行。 为了方便对「分页效果」作说明,笔者先将Pager套件所产生分页画面显示给读者观看。目前Pager提供两种分页的方式,一种称为「Jumping」另一种称为「Sliding」,请大家注意! 第一个字母都是大写。这两种方式的分页有一些些不同,底下笔者将对这两种方式的不同处做个比较,并针对各个分页的细部功能定义一些名词。
►Jumping方式 举例来说,要将某一个含有104笔数据录的数据表用每页5笔的方式显示在网页上,总共将会分成21页,每一页的页码会放在页面的最下方并设置超级链接连到各页面,每个页码间用一个「空白」来加以分隔。 另外,Jumping方式可以让开发者不用将2 I个页码全部显示出来,显示多少页可由开发者决定,例如,希望一次只显示10页,免得页码太多影响画面的美观。显示画面为下图:
请读者注意画面最下方,出现1个非超级链接与9个超链接的页码。一开始进入网页通常出现的是第1页的内容,所以第1页的页码并不需要有超链接。 页码的后方有一个Next>>的超链接,可让使用者查阅第10页以后的资料。若使用者按下2这个页码的超链接,画面会变成:
请先注意最上方的网址列,最后出现一个“?pageID=2”的字符串。它是代表当使用者在上一个画面中按下2时,会将一个名称为pagelD,变数值为2的变数,用get的方式传送到服务器端,用来作为让服务器判断要显示哪一个页码的资料。 另外,最下方的2变成没有超链结了,且页码的最前方出现了<
若浏览者想点阅第10页以后的页码,稍微麻烦的足,必须先按下10这个页码的超链接后,再按下Next>> 超链结才可进入第11页起到第20页的10个页码连结。 以下两个图显示了若要观看第10页以后的数据,需要有两个步骤: 1.先点选页码10来到第10页。 2.接着再点选Next>>,就可以进入第11页到第20页。
这就是Jumping方式的分页,也是Pager套件的预设分页方式,笔者觉得这个分页方式功能已经十分完整了,不过下一个介绍的Sliding方式在跳页的功能上比Jumping更优胜。 这个方式与Jumping方式最主要的不同点在于:被点选的页码,会出现在所有页码的正中间,也就是说Jumping方式下方的页码不会跳动,只有当按下最后一个页码后再按下Next>>超链结,页码才会变动,但Sliding方式会让被点选的页码跳至所有页码的中央位置。 另外,这个方式预设会用“|”符号作为页码的分隔,最后面还会有一个最末页的页码超链结,可让使用者立刻就跳至最后一页。 Sliding方式的分页如下图,当第1次进入网页时,会出现第1页。
若点选的页码一直往后增加,被点选的页码会出现在正中间,而且,最前面会出现第1页的页码,让使用者可以立刻回到第1页,另外页码前后还有<<与>>两个超链接可让读者往前翻与往后翻页。例如下图中,笔者点选第8页,8这个页码就会跑到所有页码的正中央,最前面会出现第1页的页码,最后面会出现最末页的页码: 这里要提醒读者注意一下,PEAR中有一个名为HTML Pager的套件.这个套件与Pager套件是不一样的,请不要装错。另外,很久以前,当Pager还是1.xx版时,Pager套件与Pager_Sliding套件分别代表Jumping与Sliding两种分页方式,但是当Pager套件发展到2.x.x时,这两种分页方式已经整合在一个套件内了。所以,若安装了Pager2.x.x以上版本的套件,就可以不用在安装Pager_Sliding套件了。 ▓1-4 简单范例 为了用范例来介绍套件的用法,笔者建立了一个名为Schoolnews的数据库,内含一个名为news的数据表,并在其中放入了104笔数据。 另外,笔者尝试用最简单的方法,尽量利用套件的预设设定来将数据表的104笔数据显示在网页上,并建立分页的效果,目的是让读者先了解最简单的Pager套件使用方式,范例档为example9-1.php,程序码如下:
首先,第2行与第3行分别引入DB的类别档与Pager的类别档,DB的类别档先查阅PHP PEAR的文章,这是用来做数据库连线与存取的套件。Pager的类别档是第1次引用,请大家注意引用方式。 第4行先利用DB类别的connect方法建立与schoolnews数据库的连线物件,第5行建立一段SQL叙述,内容是抓取所有news数据表中的所有数据,并依照日期由近到远来排序。 接着第6行再利用连线对象的getAll( )方法,将抓取的资料以阵列的形式放入变数$rows中。最后第7行将数据库连线关闭。 把数据表news中104笔数据全部抓出来并以阵列的形式放入$rows变数后,就可以开始进行分页的工作了。进行分页之前,需对分页功能的一些设定选项做设定。并把设定的结果放入一个阵列中。
第8行到第12行,就是一个简单的「分页设定项」所组成的阵列,在个范例中的设定项阵列设定了四个项目。分别是: ●mode : 设定分页的形式,设定值只可以是“Jumping”或“Slidhg”字符串,此范例先用Jumping方式。 ●perPage : 这个设定项目是设定每页出现的数据笔数,本范围设定每页显示5笔数据。 ●delta : 页面检索会出现的页码数量,本范围设定一次出现10个页码。 ●itemData : 要显示的数据所组成的阵列,此处指的就是$rows这个用连线物件的getAll()方法所取得的阵列。 事实上,分页相关的设定项目总共有32项,除了itemData这个项目是要设定的项目外,其它都可以用预设值。 有了$params这个阵列,就可以开始建立一个「Pager物件」了。方法一样是用new, 但是$params阵列必须当作建立物件的参数,如第13行。 pager物件建立完成后,笔者将该物件放入$pager变数中,也就是说,$pager变数就是一个依照$params阵列所指定的设定值来产生的Pager物件。 接着第14行用Pager物件提供的getPageData()方法,将网页浏览者点到选某页面时,属于该页面的数据全部抓出来,放入$datas变数中。例如网页第1次载入时的画面是第一页,getPageData ( )方法就会将第1页的5笔数据用阵列的形式放入$datas变数中,若是使用者点选第5页的页码,$datas变数的内容就是属于第5页的5笔数据所组成的阵列。 剩下的工作,就是使用者所点选的那一页的数据显示出来,整个范例就可以大功告成了。
可大功告成了 第19行, 利用foreach迥圈,将$datas阵列中的5笔数据一笔一笔地取出并放入$data变数中。 第2l行与第22行中,配合一些HTML标签,将每笔数据中第2、第4、第16个栏位的数据显示出来。 第27行,使用Pager物件的getLinks ( )方法来建立「页数检索」,这个方法会传回所有页码超连结的HTML标签,这些都是以阵列的形式放入$Links变数中,这个变数中有一个较为特殊的key叫做“all”,这个key的value的值其实是页码超连结的HTML标签合而成的。 第28行用echo的方法将$links变数中,key为“all”的value显示出来。 最后第32行用Pager物件的的numPages()方法与numltems()来取得总页数与总数据笔数,并用echo的方式显示给使用者知道。 执行结果如下: 可以清楚看到每页显示5笔数据,而且页码只出现1~10,完全符合笔者设定的$params阵列的值。 $links [‘all’]变数的内容就是画面中倒数第2行“页数检索:” 后面的那一大串页码的超连结。在最下方,可看到Pager物件的numPages()方法与numItems()方法分别取出的总页数为21与总数据笔数为104这两个字。 若笔者将上一个范例中$params阵列的mode设定项目改为“Sliding”字串,也就是分页的方式改为使用Sliding方式,另外将delta设定项目改为正整数5,其余程序码不变,此时delta代表的不是总共出现的页码,而是被点选的页码前后出现几个页码,则执行结果如下图,范例档名为example9-2.php: 页数检索的方式变成不一樣了,例如,当使用者点选页码8时,8会出现在页数检索的正中央,而且前后各有5个页码,符合delta的设定值,另外,前后各出现第1页与最未页的超连结,还有<<与>>这两个超连结让使用者翻页。 如果,使用者点选页码8后继续点选页码9,会变成页码9在所有页码的正中央,前后各5个页码,分页的方式就以这种方式一直滑下去(Sliding的意思就是「滑」),这种方式就称为Sliding。
综合以上说明,无论是Jumping还是Sliding的分页方式,可以将建立分页的基本流程分为以下几个步骤: 1.引用DB、Pager类別档。
2.用DB连线物件的getAll()方法取得所有数据录。
3.建立分页的设定项阵列。
4.建立符合设定项阵列的分页物件。
5.用分页物件的getPageData()方法取得某一页的数据录。
6.用foreach回圈将数据录内容显示出来。
7.显示所有页码的超连结。
8. 显示全部页数与全部数据录的笔数。 只要遵循以上8个步骤就可以建立一个基本的分页机制,至於更进阶的分页设定或分页物件的其他方法,后面笔者再进一步的逐一說明。
▓1-5设定项的设定 上一个范例中,笔者在$parmas阵列中设定了最基本的四个设定值,事实上,Pager物件的两种分页方式总共有32个设定项目可以设定,这32个项目除了itemData外都有预设值,若开发者没有在$params阵列中特别设定某些项目的值,Pager物件将会使用预设值。 为何要有这麼多的设定项? 因为无论是Jumping或Sliding,虽然都十分好用,但是有些开发者可能对分页的效果想要做细部调整,例如华人世界的开发者,想将分页中文化等。这些需求都可籍由设定项目的设定来修改分页的外观,以符合开发者的需求。 底下就经常会用到的设定项目分別加以說明: ►itemData、perPage、deIta 、以及mode等四个设定项 这四个设定项先前范例中已经有提到并說明之,所以笔者不再赘述。只将这些设定项的设定值的数据型态再加以补充。 ●itemData:设定值须为阵列,阵列內容就是所有要显示的数据录,这个项目是唯一沒有预设值的项目。 ●perPage:设定值须为大於0的正整数,代表每一页希望出现的数据笔数。 ●delta :设定值须为大於0的正整数,对Jumping模式而言,de!ta代表页数检索中出现页码的总数,对Sliding模式而言,delta代表被点选的页码前后出现的页码数目。 ●mode:设定值只可以是“Jumping”或“Sliding”两个字串,代表的意义是分页显示的模式。 ►currentPage设定项 这个设定项若要可以使用,Pager套件的版本需大于2.2.6版。设定值的型态须为大於0的正整数。这个设定项可让网页第1次载入时,出现的页面不是第1页,至於是第几页,则由设定值来決定。 例如,笔者希望网页一载入就出现第3页,沿用example9-2.php的范例档做說明,只要在$param阵列中多加入一行:
也就是说$params阵列变成:
其余的程式码完全一樣,修改后的网页存成范例档example9-3.php,执行结果如下图: 由上图可看出,第1次载入exeample9-3.php出现的不是第1页,而是第3页。
►urlVar设定项 这个设定项足用来更改分页的urlVar变数的名称。所谓urlVar变数,是一个用来放置网页浏览者所点选的页码,并供服务器判断该显示哪一页的一个变数,通常会附在url之后,urlVar预设的变数名称是pagelD。 例如,笔者将范例档example9-1.php 原封不动的拷贝成范例档example9-4.php,执行后当笔者点选页码3,网址列的url后面会出现“?PageID=3”,也就是說,点选超连结时,有一个名为$pageID的变数,其值等于3,会借由get的方式将变数与值送到服务器端,供服务器辨认浏览者点选的页码。 执行结果如下图:
若笔者修改example9-4.php档的原始码,在$params阵列加入一行设定,内容为: 这个设定的意思就是将预设的urlVal变数的名称由pageID改为mypageid,存档后重新执行example9-4.php,会发现url后面的变数名称已改变,如下图: 上图中可清楚看到,网址列后面的变数不是pagelD了,变成是mypageid。 对大家而言,可能会有一个疑问,改url的变数名称会用在什麼情況下呢?其实,这个设定项会需要修改大都是因为用在一个网页內有两个以上分页的情况。 若一个网页有两个以上的分页机制,而预设的urlVar名称都是pagelD.也就是沒有修改这个设定项的话,会造成分页时的混淆,若浏览者点选某一个分页的页码,其他分页也会跟著变动,所以若有两个以上的分页机制,则每个分页都必须将urlVar改为不同的名称,才不会造成这种现象。
►altPrev、altNext、以及altPage设定项 这三个设定项都是用来修改超连结的ALT属性內容,而且设定值的型态都必须是字串。 何谓「ATL属性」? 当使用者将鼠标指向网页內某一个超连结的瞬间,鼠标旁会出现小小的方框,內有该超连结的简单說明,这就是ALT属性。假设笔者将范例档example9-1.php拷贝成example9-5.php,执行后在页数检索中会出现三种ALT属性: ⒈ 当使用者鼠标移到< ⒉ 当鼠标移到页码的超连结时,滑鼠旁会出现“pageX”,其中X代表页码,如下图:
当鼠标到Next>>这个超连结时,鼠标旁会出现“next page”,如下图:
若开发者希望修改这三个ALT属性,只需要在$params中加入三个设定:
也就是example9-5.php的$params阵列改为:
其余程式码维持不变就可以了。 altPrev设定项代表的是<>这个超连结的ALT属性,altPage设定项代表的是页码连结的ALT属性。 Example9-5.php修改后存档,并重新执行的结果会如以下图形: 第1个图形.当鼠标移到<
● 第2个图形,当鼠标移到某个页码的超链结时,ALT属性变成“页X”。 ● 第3个图形,当鼠标移到Next >>这个超链结时,ALT属性变成了“后一页”。
虽然,有些网页设计者不太重视ALT属性,但却有一些设计者对网页的每个细节者要求要做到尽善尽美,这三个设定项设与不设,就由读者您自己决定吧。
►prevImg与nextImg设定项 这两个设定项对使用中文的开发者而言就很实用了。Jumping方式的分页范例叫页数搜索的前后各出现了<< Back 与Next >>两个超级链接,这两个字都是英文,比较不适合华人的网页浏览者,若开发者想要将这两个超级链接的文字改为中文,只要改这两个设定就可以了,另外,这两个设定也可以让开发者使用图形来取代文字。 设定值的型态都是字符串,只是修改文字与使用图形的字符串内容会有所不同。 若在example9-1.php的$params数组中加入两个设定如下,并转存成example9-6.php: prevImg设定项代表<>改变后的文字。执行结果如下图: 出现中文字了,这对华人开发者而言是不是有些感动呀。 若开发者想改用图案来取代文字的话,首先当然需要先制作两个图片,例如,我自制了两个很丑的图片( 让大家眼睛辛苦了),分别是pre.gif与next.gif,准备用来取代<> 将example9-6.php拷贝为example9-7.php当作范例文件,这两个图档放在与example9-7.php同一个路径下。 Example9-7.php的程序代码中$params数组的prevImg与nextImg设定项若更改如下: 这两个设定项的值是一行字 内容是插入图片的HTML标签。img代表图案的意思,src=的后面是图案的路径与文件名,border是图案的框线,预设为l个像素,笔者将范例中的框线改为0个像素宽。修改完成后存盘,执行结果如下图: 出现了,前后两个超级链接已经被自制的图档所取代。若您是一位非常会设计图案的读者,这两个可放入图案的设定项将可大大提升分页的美观度,让您的分页与众不同喔。 ►separator设定项 页码与页码之间需要有适度的分隔,页数搜索看起来才不会感觉拥挤。在Pager套件中,Jumping模式与Sliding模式页码间都有分隔,前者预设是使用空白,后者预设是使用“|”,若开发者想加入自己的创意,修改预设的分隔符,只要加入separator设定项就可以了。 这个设定项的值需为字符串,而字符串的内容除了符号或文字以外,也可以如同上一个范例般使用图片。 首先,笔者将范例example9-1.php,转存成example9-8.php,并在$params数组中加入一行设定如下:
这个设定的意思是说将分隔由空白改为“ * ”号,执行结果如下图: 页数搜索的分隔很轻易地就改变了。 若要将分隔改为图片的话,笔者第1步先将example9-8.php转存成example9-9.php当作范例文件,第2步我又做了一个好丑的图片(请见谅)名为sep.gif,同样放在范例文件相同路径下,第3步,修改程序代码中$params数组的separator设定项的值如下:
也就是将分隔符改为由sep.gif这个图档来取代。执行结果如下图: 这是笔者随手捡来的图案,作一个例子,相信读者应该可以设计出很美观的分隔图案,丰富您的网页内容。 ---------------------------------------------------------------------------- PEAR-像Google一样的分页功能(2)
第二篇PHP/PEAR
Pager套件像Google一样的分页功能
►spacesBeforeSeparator与spacesAfterSeparator设定项 这两个设定项目也是与分隔符号有关,spacesBeforeSeparator是设定分隔符号前需要有几个“空白”,SpcesAfterSeparator是设定分隔符后需要有几个空白。这两个设定项可拉大或缩小分隔的距离,让开发者随心所欲的调整分隔的宽度。设定值的型态都必须大于0的正整数,代表前后空白的数目。 范例文件名为example9-10.php,程序代码与范例文件example9-9.php唯一的不同在于$params数组中新增了两个设定,程序代码如下: 范例中假设了在分隔图案的前与后都增加了两个空白,执行结果如下图: 可以发现分隔图案与页码间的距离被拉开了,至于多少个空白才是最适当的,这就由读者自己做判断了。
►firstPagePre、firstPageText、firstPagePost与lastPagePre、lastPageText、lastPagePost设定项 先说明一下,这六个设定项目只可以用在Sliding模式的情况下,且设定值都需为字符串。 在sliding模式下,页数检索的最前方会出现第1页页码的超级链接,最后方会出现最后一页页码的超级链接。若开发者希望以不同形式来表现这两者的话。可以加入这六个选项来达到目的。 例如,若笔者希望执行的结果如下图:
第l页页码的超级链接改为{第1 页}文字型态的超级链接,最后页页码的超连结改为[ [最末页] ]文字型态的超连结。 程序代码中$params数组应该加入以下设定。范例文件名为eample9-11.php:
● 第1个设定项firstPagePre代表的是最前方文字左边外围的字符串,笔者范例是使用“{”符号放在文字的左方。 ● 第2个设定项firstPageText代表的是最前方的字符串,笔者范例使用“第1页”这个字符串。 ● 第3个设定项firstPagePost代表的是最前方文字右边外围的字符串,笔者范例是使用“}”符号放在文字的右方。 ● 第4个设定项1astPagePre代表的是最后方文字左边外围的字符串,笔者范例是使用“[[”符号放在文字的左方。 ● 第5个设定项lastPageText代表的是最后方的字符串,笔者范例使用“最末页”这个字符串。 ● 第6个设定项lastPagePost代表的是最后方文字右边外围的字符串,笔者范例是使用“]]”符号放在文字的右方。
这六个设定项目同样可以用图片来取代文字,假设笔者建立了四个图片文件,第1个图片名为left.gif,如图:
第2个图片名first.gif为,如图: 第3个图片名为right.gif为,如图: 第4个图片名为last.gif为,如图: 范例文件名为example9-12.php,四张图都放在范例文件相同路径下,与上一个范例档example9-11.php唯一的不同在于六个设定项改为: 也就是使用四个图档作为显示的内容,执行结果如下图: 是不是觉得很有趣呢? 这些设定可以让分页依照设计者独特的巧思来加
以改变,让分页与众不同。
►showAllText设定项 这个设定项需搭配Pager物件的getPerPageSelectBox ( )方法来使用,因此,这个设定项留待下一单元中介绍到getPerPageSelect( )方法时再来一并做说明。
►linkClass设定项 上面几个范例虽然可以更改许多分页的细部外观,可是视觉上仍稍嫌单调,若能套用CSS来改变页数搜索中超连结文字的字体,颜色,大小,将会使画面看起来更好看,这个设定项就是用来让超级链接套上CSS。 假设,笔者修改example9-1.php,在网页最上方加入了一段CSS,内容是建立了一个名为1ink的class,并希望“页数搜索”后面的超级链接能套用此CSS的class,来改变分页的外观。范例文件名为example9-14.php,程序代码如下:
第1行到第9行包在刁中间的设定就是所谓的CSS,其中定义了一个名为1illk的class(请注意,1ink前需要有一个“.”)。 第4行定义了这个class的文字大小为12像素,第5行定义了文字颜色为#663366,第6行定义了文字的背景色为 CCCCCC。 接下来的内容与范例文件example9-1.php完全一样,只有$params数组中多了一项设定,位于第22行。 这个设定项定义了页数搜索后面所有的超级链接文字都必须套用link这个class,套用的结果如下图: 所有超级链接文字都变成了紫色(##663366), 背景色变成了淡灰色(#CCCCCC),有超级链接的数字,数字大小都变成12像素,是不是感觉很炫啊? 但请注意,这个页码没有超级链接,所以不会套用CSS的设定。 ►curPageLinkClassName设定项 上一个设定项定义了超级链接的文字可套用哪一个CSS的Class。套用后的结果,虽然不错,但美中不足的是,被导点选的页码因为没有超级链接,因此没有套用到CSS,相对于其它页码就显得文字较大,较为突兀。 这个设定项就是用来修正这个问题,就是说,这个设定项也可指定一个CSS的class来让被点选的页码套用。 假设笔者在范例文件example9-14.php中新增一个CSS的class名为content,这个class同样需放在之间,程序代码如下:
它定义了文字字体为新细明体,文字大小与link相同为12像素,文字颜色为橘色#FF6600。 另外,在$params数组中多加了一列设定,如下:
定义了被点选的页码文字需套用content这个CSS的class,执行结果如下图,笔者将范例文件转存成example9-15.php:
被点选的页码3变成了与众不同的橘色了。请注意,CSS的class名称当作设定值,需要使用字符串的型态。 ►clearfVoid设定项 这个设定项的值需为布尔值,也就是设定值不是true,就是false,默认值是true意思是若数据项数少于一页,网页底下的“页数搜索”后面将不会出现页码。如下图:
若开发者希望全部资料不满一页时,页码搜索后面仍然出现1这归页码,只需将这个设定项放入$params数组中并设为false就可以了,程序代码如下:
范例文件为example9-16.php。执行结果如下图:
页数检索后面多了一个1,不会什么数字都没有,感觉有点空空洞洞的。
1-6 Pager物件的方法 Pager套件的使用方法,除了开发者可以更改设定项数组的值以外,当用new关键词建立一个Pager对象后,Pager物件也提供了许多的方法可以供开发者利用,底下笔者介绍比较常用的11个方法,这11个方法可弥补设定项的不足之处。
►getCurrentPageID方法 这个方法可传回目前所在页面的页码,回传值是个正整数。例如,浏览者正在阅读第3页,这个方法会传回正整数3。
►getNextPageID方法 这个方法可以传回目前页面后一页的页码,回传值是个正整数。例如,浏览者正在阅读第3页,这个方法会传回正整数4。若浏览者正阅读最后一页,这个方法会传回false。
►getPreviousPageID方法 这个方法可以传回目前页面前一页的页码,回传值是个正整数。例如,浏览者正在阅读第3页,这个方法会传回正整数2。若浏览者正阅读第l页,这个方法会传回false。
►numItems方法 这个方法可以传回Pager物件中所含数据的总项数,回传值是个正整数。列如,若数据的总项数是120项数据,这个方法会传回正整数120。
►numPages方法 这个方法可以传回Pager物件中的总页数,回传值是个正整数。例如,若数据总共被分为20页,这个方法会传回正整数20 。
►isFirstPage方法 这个方法可以侦测目前页面是否为第1页,回传值是个布尔值,若是第1页则传回true,其余传回false。
►isLastPage() 这个方法可以侦测目前页面是否为最后一页,回传值是个布尔值,若是最后一页则传回true,其余传回false。
►isLastPageComplete方法 这个方法可以侦测最后一页的数据项数是否刚好符合设定的每页数据项数,回传值是个布尔值,简单的讲,若每 需要显示5项数据,而最后一页刚好就是5项数据则传回true,其余传回false。 以上8个方法,笔者用一个范例文件example9-17.php来做说明,假设笔者共有105项数据,每页希望显示5项,换算成页数,应该会有21页,且最后一页刚好就是5项数据,另外,网页最下面的页码搜索希望每次出现10个页码。程序码如下: 这个范例文件第1行到第30行与example9-1.php完全相同,分页采用Jumping模式,并设定每页显示5项数据,每次出现10个页码。重点是从第32行到第40行,分别使用先前介绍的8种Pager物件的方法,将分页的讯息显示出来。 第1次加载网页的执行结果如下图: 读者可发现最下方「目前页码」为l,也就是使用者进入的画面是第1页。「下页页码」是2,「前页页码」没有显示,因为没有比1更少的页码了。「是第1页吗?」答案应该是传回true,这里要说明的是对PHP而言,若数据型态为布尔值,则1与true是相同意思的,所以图中的1并不是第1页.而是true的意思。「是最末页吗?」没有显示任何值,对PHP而言,若数据型态为布尔值I,则false与0或空值是相同意思的,所以此处是false的意思。「最未页刚好5项吗?」,侦测的结果同样是布尔值,出现1代表为true。 最下面一行再分别用numPages()方法侦测出总页数为21页,与numltems()方法侦测出总数据笔数为105笔。 若笔者点选第5页,结果如何呢? 与上图不同的地方在于「目前页码」变成5,「下页页码」变成6,「前页页码」变成4,「是第1页吗?」与」是最末页吗?」都传回false,其余皆相同。 若笔者点选最后一页,结果如下图:
与上图不同的地方在于「目前页码」变成21,「下页页码」变成没有值,因为第21页已经是最后一页了,「前页页码」变成20,「是第1页吗?」传回false,「是最末页吗?」传回true,其余相同。
GetLinks方法 这个方法在范例example9-1.php 中笔者就已经使用过,利用这个方法只要两行程序代码.就可以得到完整分页功能的超级链接。 用法是先执行getLinks()方法来取得由页码的超级链接与<>等超级链接的HTML标签所组成的数组。 比较特殊的是,当这个数组的key为“all”时,value将会是所有页码与<>超级链接所合成的的HTML标签。请回头复习一下范例exampie9-1.php的第27行与第28行: 第28行这一行所产生的HTML标签,可经由网页的原始码看到: 是不是很方便,一行程序代码就可以产生这么多的HTML标签,建立好所有分页的超级链接,节省了许多开发者撰写程序码的麻烦。
►getPageData方法 这个方法在范例example9-1.php中也使用过了,目的是用来抓取某页码的数据内容,并组成一个数组。例如,当浏览者点选页码5这个超级链接时,页码5内的所有数据都被抓取,并组成一个数组,如程序代码的第14行: 接着再用foreach循环,将数组中的所有数据,一笔一笔地数据显示出来,如程序代码的第19行到第23行: 第19行的foreach循环,会从$data 数组中每次抽取一笔数据,放入$data变数中,而$data也是一个数组型态的变数,key是由0开始起算的正整数,value是按顺序对应到字段的值,例如$data[1]代表该项数据录第2个字段的值。
►getPerPageSeclectBox方法 这个方法会提供一个Select组件,供使用者选择每页要显示的数据项数,也就是说,假设开发者原本设定每页显示5项数据,有了这个工具,使用者可以用select组件来更改为每一页显示l0项或20项数据。笔者直接使用范例文件exlmple9-13.php来说明,方便读者了解,程码如下:
先来看看执行的结果画面吧: 网页底下多了一个选单可让浏览者选择一页要显示几项资料,选好后按下送出钮就可以更改每页显示的项数了,若选择全部,则所有数据会全部放在一个网页中。 要让分页具有这种功能,首先,需要在设定项的数组中加入这一行 程序代码第13行的这个设定项目,在上个单元介绍常用的设定项时,笔者省略没有介绍,因为它必须搭配getPerPageSelectBox( )方法才有意义。 这个设定项主要的功能是设定选单中可以让浏览者选择显示所有资料于一页中的选项文字。例如,笔者若将showAllText这个设定项目设为“全部”这个字串,选单的最后一个选项就会出现“全部”这两个字,使用者若选择这个选项,所有数据将会全部显示于一个网页中。 除了这个设定外,接下来还必须建立一个表单,表单内至少要有Select组件与submit元件。程序代码从第34行到38行。 第34行是运用pager对象的getPerPageSelect()方法建立select组件的HTML标签,并放入$selectBox变数中。这个方法可以使用4个参数,第l个参数是起始直,也就是选单中第1个选项的数字;第2个参数是最末值,也就是选单中最后一个选项的数字;第3个参数是每个选项间相隔多少数;第4个参数是选单是否提供所有数据于一页的选项,若设为true,选单最后会出现showAllText设定项的文字,选择这个选项可以一页显示所有数据。 以笔者的范例而言,建立起来的选单会由10开始始,50结束,每个选项相隔20,并且是供所有数据显示于一页的选项,让浏览者点选。若这个方法没有设任何参数,则预设的起始值是5,最末值是30,每个选项值相隔5,也没有提供所有数据于一页让浏览者点选,所以说也没必要设showAllText这个设定项了,因为根本不会出现这个选项。 第35行用echo的方法显示表单的HTML标签,其中action的值为空,代表按下submit钮后数据的后端处理仍由表单所在的网页来进行。第36行会将$selectBox变数的内容显现出来,显现出来的原始码如下: 上值的原始码全部放在$SelectBox变量中,也就是说,$SelectBox变量内容是所有select组件的HTML标签。 第37行是建立submit组件,并将按钮上的文字设为“送出”。第38行是表单结束的HTML标签。 OK!大功告成了。细心的读者可能发现到了,除了以上程序代码外,这个范例档与example9-1.Php的程序代码都完全一样。
▓1-7一个纲页多个分工 同一个网页中可放人多个分页,是一个非常酷的功能,若开发者自行撰写PHP程序,难度会相当高,但对pager套件而言很简单就可以做到了。 需注意的地方只有四个,第1,先制造出多个pager物件,每个pager物件用不同的变数名称;第2,设定项数组的变数名称每个Pager物件须不同;第3,每倒Pager物件须有不同urlVar设定项;第4,放置不同分页数据的变数名称也要不同。这样就可以做到一个网页多个分页了。 为了举例给读者了解,笔者在范例的schoolnews数据库中,新建立一个名为anothernews的数据表,假设这个数据表的架构与范例news数据表完全一样。并将example9-1.php的程序代码全部复制一份放在原程序代码的下方,两段程式码中间加入一条水平线加以分隔(< hr >),经由稍微的修改就可以做出两个数据表的分页了。 范例文件名为example9-18.php,程序代码如下: 程序代码虽然看起来很多,但若加以区别的话,第4行到第36行是第1个分页第38行到第71行是第2个分页。 第1个分页中与范例文件example9-1.php较为不同的地方为第8行将原本设定项数组的$params变量名称改为$params1,并在第13行加入一个urlVar设定,改变预设的urlVar变量名称为pageID_1。 第15行建立第l个pager物件时,参数要改用$paramsl,并将建立的物件放$pager1变量中,第16行用物件的getPageData()方法将所抓取的数据数组放入$datasl的变数中。 第21行到第25行利用foreach 回圈将每项数据显示出来就完成了第1个分页,请注意,变数名称不可弄错。
最后要注意一下第29行,用pager物件的getLinks()方法得到所有分页超连结的HTML标签后,放入的变量名称也改为$links1了。 第2段的分页与第1段分页要修改的地方都一样,只是将变量名称后的“1”改为“2”藉以区别而已。 如第43行将设定项数组的变量名称改为$ params2,第48行将urlVar变数名称改为$pageID_2. 第50行建立另一个新的pager物件,并以$params2作为参数,产生的新物件放入$pager2变量中,接下来,若有使用pager物件的方法,物件名称要改用$pager2喔,如第51行同样使用getPageData()方法将每页所含的数据数组放入$datas2变数中。 用foreach循环,将第2个分页的$datas2 阵列中的数据一项项的抓出,并显示出来。请见第56行到第60行。
最俊也请不要忘getLinks()方法所得到的分页超级链接的HTML标签,要放入变数$links2中。请见第65行。 执行结果如下图:
出现了,两个不同的分页。若笔者分点选第l个分页的第5页与第2个分页的第2页,可看出网址列后面会出现一段字符串: 代表Pager套件会自动产生两个变数,而且这个网页会用两个不同的urlVar变数来控制两个分页,两个分页系统不会 因为同在一个网页而发生错乱。
▓1-8结论 这个套件介绍到此可以告一个段落了,除了少数几个较少用到的方法与设定项外,常用的设定项与Pager物件的方法,笔者几乎都有用范例文件加以说明。 最后有一点要注意的,就是若读者使用的是PHP5,在建立pager物件时,不可以使用new的方式了,如下程序代码:
请改用Pager类别的factory的方法来建立pager物件,也就是说上一行的程序码,请以底下这一行的程序代码来取代;
否则会发生错误喔,这是因为PHP5 与PH4的物件导向设计上有些不同,套件开发者只好另行用factory方法来取代new关键词来建立新物件。
全文完
第四章 如何使用套件 从第一章与第二章,大致上大家应该了解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物件,但卻是互相独立的物件,彼此的运作並无相关性。就如同一家订书机工厂生產的两个外型与功能都相同的红色订书机,这两个订书机並无相关性,其中可能一个被某一个美女买去,另一个被某一个小学生买去,当美女使用订书机时並不会影响小学生使用订书机。 ------------------------------------------------------------------------ 什么是PEAR?(第六篇)
▲ 类別的属性 从第52-76行包含在 class Benchmark_Timer后的大括号“{”与“}”中,用var关键字定义的变数,在类別中称之为属性,由程式码可知Benchmark_Timer类別拥有markers,auto,strlen_max三个属性,属性名称的等号后面不是变数的资料型态就是变数的预设值,在本例中,markers是一个阵列(array)型态的变数,而auto变数的预设值是false,strlen_max变数的预设值是“0”。 所谓预设值,就是当开发者沒有特別指定时,就把某个变数以预设值当作变数的值。 当使用者用new方法產生Benchmark_Timer物件时,每个物件都会拥有这三个属性,我将new出来的Benchmark_Timer物件称为「时钟物件」,因为该物件是用来计算程式执行时所使用的时间。 通常程式开发者帮属性命名时会以属性的意义当名称,方便使用者可以「望文生义」。例如:markers代表「标记」,意思是对时钟物件做个记号,请注意,可设定多个标记,用来检查每个标记间时间间隔的多寡。而auto代表是否一开始就自动啟动时钟物件。strlen_max代表字串长度的最大值,str就是字串(string), len代表长度(length),max代表最大值(maximum),稍后我会用范例加以說明这些属性的用法。 ▲ 方法 Timer.php中提供了许多的方法,我只用第161-212行的程式码来加以解說,大家可看到5个被包在class Benchmark_Timer中用function开头的段落。这5个function就代表类別的方法,也就是說,这里有5个方法,名称为display方法、start方法、stop方法、setMarker方法、timElapsed方法,而每个方法內大括号“{”与“}”中的內容就是方法实际运作的程式码。display方法是用来将时钟物件的执行结果显示出来,start方法是用来啟动时钟物件,由此类推,由字面的意思就可大致知道方法的意义。 在前例show.php档中的第4行,$timer这Benchmark_Timer物件使用了start方法。
在前例show.php档中的第4行,$timer这个Benchmark_Timer物件使用了start方法。
◆ example1.php范例 为了帮助大家了解,我再撰写一个名为example1.php的档案,內容一樣是使用Benchmark套件,且为了解說方便,在每一行前面我编上了行号。完整程式码如下: 首先,第2行引入Benchmark资料夹中的Timer.php档。
为了让大家了解类别与物件的关系,特別在第3行、4行產生两个Benchmark_Timer物件,並分別放入$timer1, $timer2变数中。也就是說產生了两个时钟物件,请注意,这两个物件虽然长的一模一樣,但使用上是互不相干的。 在第5行中,第一个时钟物件啟动,$timer1物件用start方法开始计时,请您想像有一个时钟按下开关开始计时。接着在第6行用php內建的sleep( )函式让程式的执行停顿一秒。 第7行接着啟动第二个时钟,请您想像第二个时钟按下开关开始计时。并在第8行让程式在停顿一秒钟。 第9行用setMarker方法,设定$timer1物件的marker属性,並将此时间鲇标记命名为mark1字串。其实在物件使用start方法与stop方法时,setMarker方法也会自动被执行,並将开始与结束的时间点标记名称设为「Start」与「Stop」。 第11行用timeElapsed方法计算$timer1时钟物件从啟动到mark1标记,程式执行所使用的时间,相当於计算第1行到第9行的执行时间,並用”秒”为单位将时间差显示出来。这个方法有两个参数,第一个代表开始计算时间的标记名称,第二个代表结束计算时间的标记名称,所以分別填入「Start」与「mark1」字串。 第13行再让程式休息一秒。 第15行用stop方法将第一个时钟物件停止,也就是结束第一个时钟的计时,並将时间的使用情形用display方法完整显示出来。 第18行用stop方法将第二个时钟物件停止,也就是结束第二个时钟的计时,並在第19行将时间的使用情形用display方法完整显示出来。 OK ! example1.php大功告成。 执行结果如下图:
让我们将执行结果对照一下程式码,在第5行时第一个时钟物件啟动,到第9行该物件设定一个名叫mark1的标记,中间经过了第6行与第8行两个sleep(1),所以从5-9行总共使用約2秒的时间,显示在网页上的结果是1.999727秒,嗯,果然符合预期。 接著对照第一个时钟物件在网页上display的结果。 您会发现Benchmark_Timer物件的display方法会将时钟物件的执行过程用一个表格做完整的呈现。 第一个表格最下面的总时间列total告诉我们,从开始到结束第一个时钟物件总共用掉2.999583秒,其中从啟动到mark1用掉了1.999727秒,mark1到停止用掉了0.999856秒,检视原始码第9行设定mark1到第15行计时停止中间第13行也有一个sleep(1),所以计时的结果是正确的。 第二个时钟物件的执行结果较为单纯,只有啟动与结束两种状況,由第二个表格可知总共用掉2.000141秒,对照原始码,从第7行的啟动到第18行的停止中间,第8与第13行各出现一个sleep(1),也就是約耗掉2秒钟,可见第二个时钟物件的执行结果也是正确的。 到目前为止,大家是否觉得PEAR套件超好用的呢,有了Benchmark套件,我们可以轻轻松松知道每个网页的执行时间。日后若发生了网页执行速度缓慢的情形,想知道问题出在何处,这可是一个很好用的工具喔!! 从第六章起,我们将逐一介绍几个常用的套件,这些套件的功能都是程式开发者使用率极高的,如资料库使用,表单的制作与验证?,翻页功能,简单的身分认证…等。虽然本文章无法将我所知道的套件全部介绍,但若能引起大家的回响,能够吸引更多人共同投入PEAR套件的研究。
◆ 寻求协助。 套件的使用,本人认为是先苦后甘,先要花时间了解套件的使用方法,这一段是「先苦」,但若学会了,以后自行撰写程式码可就轻松愉快了,这一段是「后甘」。 若使用或学习PEAR套件上遭遇了困难,该怎麼办呢?何处可寻求协助? 本人根据自身的经验,找出以下的管道供读者参考: ◆ 閱读本文章 閱读本文章当然是最佳选择了,目前PEAR的相关资料百分之九十九都是英文或其他语言,繁体? 中文或简体中文的资料真是少之又少。 我们计画将PEAR的研究心得继续在本网站里发布,目前因为中文PEAR的资料缺乏,希望尽己之力,为PEAR的內容多写一些介绍,同时继续研究和学习那PEAR中的272个套件,希望大家共同参与,并能够分享研究的成果。
◆ PEAR官方网站 在PEAR官方网站,您可以寻找套件,下载套件,閱读套件的简介,开发者姓名,說明文件等。这裡也有一些专家针对某些套件撰写的文章,或者您也可以察看套件被下载的次数统计等。总而言之,问题发生了,一定要试试来这裡找答案!!不过可惜的是,网站內容全是英文,閱读起来总是有些文化障碍。 详细內容请参閱PEAR官方网站介绍。
◆ mailing list 大家可在PEAR官方网站中加入使用者的mailing list,以我为例,每天E-mail信箱总会收到数十封标题有PEAR字樣的信,这些信的內容是全世界PEAR使用者将本身使用上发生的问题提问出来,借由mail来询问所有mailing list的成员,而热心的成员会对针这些问题加以解答並同樣mail给所有成员。 加入mailing list的缺点是,信箱必须夠大,因为信真的很多。 ◆ 套件內的說明与范例 有些套件很贴心的內附使用說明文件,甚至范例程式供使用者閱读与测试。这可让使用者节省许多探索套件用法的时间。 大家若要学习一个新套件,第一步总是会先到套件內寻找說明文件或范例。 ◆ 原始码 学习PEAR最直接的方法就是閱读原始码与註解。不过这真的有点困难,因为每个php档通常有数百行、甚至数千行的程式码与註解。幸好,物件导向的撰写方式让程式码「段落分明」,较易閱读,而且所有PEAR套件的註解都可以用phpDocumentor套件提供的指令将註解独立出来成为一份文件或网页,借由详细的註解来避免掉閱读大量的原始码。 ◆ Google
最后,若以上方法都找不到答案,我建议您使用史上最強的搜寻引擎-Google来找一找吧!
我也经常使用Google找到不少PEAR相关的文章或范例程式喔。 -------------------------------------------------------------------------- PEAR-像Google一样的分页功能(1) PHP/PEAR
Pager套件像Google一样的分页功能
介绍 读者应该行使用过Google这个超好用的搜寻引擎吧。每次搜寻后出现的资料数量总是多的令人吃一惊,有时甚至高达数千笔,数万笔。像如此多笔的数据是无法用一个网页来呈现的,Google的作法是将众多的搜寻结果以每页十笔、并在下方用页码超连结的方式来加以呈现,以下这个画面相信您一定不陌生:
这就是所谓的分页效果,当然资料数量庞大到无法用一个页面显示所有资料的时候,开发者往往会使用分页的功能来呈现数据。除了因为数据量大,无法用一页显示外,分页还可加快存取数据的速度,并让数据的排序显得井然有序。 在PEAR中,有一个专门针对「分页」功能来设计的套件,就是Pager套件。使用这个套件可让开发者用很简单的方式做到分页的效果,并且完全不必使用DB套件的1imitQuely() 方法来限制存取数据的范围,也不用撰写PHP来做翻页的超级链接。另外,套件内还提供许多设定项目让开发者根据本身的需求来调整分页的外观,更妙的是,可以在一个网页中放入多个分页效果。 安装 一开始安装PEAR的基本套件时,若读者是使用windows系统,就已经将Pager这个套件给安装起来了,也就是说,Pager是一个PEAR的必备套件。 若是使用Linux或FreeBSD系统,可能安装的基本套件中并不合Pager套件,这个时候请用“pear install pager”这个指令来安装。读者可以使用“pear list”指令来看看目前系统中是否已按装Pager套件,如下图:
以上图中笔者现有安装的套件为例,倒数第3个就是Pager套件,画面并显示版本编号为2.2.4,且stable版。若您曾经安装过的是旧版本,你可以升级现有最新的版本,请用“pager Upgrade pager”指令,将套件升级。本章提到许多功能需要在2.XX的版木环境下才可执行。 为了方便对「分页效果」作说明,笔者先将Pager套件所产生分页画面显示给读者观看。目前Pager提供两种分页的方式,一种称为「Jumping」另一种称为「Sliding」,请大家注意! 第一个字母都是大写。这两种方式的分页有一些些不同,底下笔者将对这两种方式的不同处做个比较,并针对各个分页的细部功能定义一些名词。
►Jumping方式 举例来说,要将某一个含有104笔数据录的数据表用每页5笔的方式显示在网页上,总共将会分成21页,每一页的页码会放在页面的最下方并设置超级链接连到各页面,每个页码间用一个「空白」来加以分隔。 另外,Jumping方式可以让开发者不用将2 I个页码全部显示出来,显示多少页可由开发者决定,例如,希望一次只显示10页,免得页码太多影响画面的美观。显示画面为下图:
请读者注意画面最下方,出现1个非超级链接与9个超链接的页码。一开始进入网页通常出现的是第1页的内容,所以第1页的页码并不需要有超链接。 页码的后方有一个Next>>的超链接,可让使用者查阅第10页以后的资料。若使用者按下2这个页码的超链接,画面会变成:
请先注意最上方的网址列,最后出现一个“?pageID=2”的字符串。它是代表当使用者在上一个画面中按下2时,会将一个名称为pagelD,变数值为2的变数,用get的方式传送到服务器端,用来作为让服务器判断要显示哪一个页码的资料。 另外,最下方的2变成没有超链结了,且页码的最前方出现了<
若浏览者想点阅第10页以后的页码,稍微麻烦的足,必须先按下10这个页码的超链接后,再按下Next>> 超链结才可进入第11页起到第20页的10个页码连结。 以下两个图显示了若要观看第10页以后的数据,需要有两个步骤: 1.先点选页码10来到第10页。 2.接着再点选Next>>,就可以进入第11页到第20页。
这就是Jumping方式的分页,也是Pager套件的预设分页方式,笔者觉得这个分页方式功能已经十分完整了,不过下一个介绍的Sliding方式在跳页的功能上比Jumping更优胜。 这个方式与Jumping方式最主要的不同点在于:被点选的页码,会出现在所有页码的正中间,也就是说Jumping方式下方的页码不会跳动,只有当按下最后一个页码后再按下Next>>超链结,页码才会变动,但Sliding方式会让被点选的页码跳至所有页码的中央位置。 另外,这个方式预设会用“|”符号作为页码的分隔,最后面还会有一个最末页的页码超链结,可让使用者立刻就跳至最后一页。 Sliding方式的分页如下图,当第1次进入网页时,会出现第1页。
若点选的页码一直往后增加,被点选的页码会出现在正中间,而且,最前面会出现第1页的页码,让使用者可以立刻回到第1页,另外页码前后还有<<与>>两个超链接可让读者往前翻与往后翻页。例如下图中,笔者点选第8页,8这个页码就会跑到所有页码的正中央,最前面会出现第1页的页码,最后面会出现最末页的页码: 这里要提醒读者注意一下,PEAR中有一个名为HTML Pager的套件.这个套件与Pager套件是不一样的,请不要装错。另外,很久以前,当Pager还是1.xx版时,Pager套件与Pager_Sliding套件分别代表Jumping与Sliding两种分页方式,但是当Pager套件发展到2.x.x时,这两种分页方式已经整合在一个套件内了。所以,若安装了Pager2.x.x以上版本的套件,就可以不用在安装Pager_Sliding套件了。 ▓1-4 简单范例 为了用范例来介绍套件的用法,笔者建立了一个名为Schoolnews的数据库,内含一个名为news的数据表,并在其中放入了104笔数据。 另外,笔者尝试用最简单的方法,尽量利用套件的预设设定来将数据表的104笔数据显示在网页上,并建立分页的效果,目的是让读者先了解最简单的Pager套件使用方式,范例档为example9-1.php,程序码如下:
首先,第2行与第3行分别引入DB的类别档与Pager的类别档,DB的类别档先查阅PHP PEAR的文章,这是用来做数据库连线与存取的套件。Pager的类别档是第1次引用,请大家注意引用方式。 第4行先利用DB类别的connect方法建立与schoolnews数据库的连线物件,第5行建立一段SQL叙述,内容是抓取所有news数据表中的所有数据,并依照日期由近到远来排序。 接着第6行再利用连线对象的getAll( )方法,将抓取的资料以阵列的形式放入变数$rows中。最后第7行将数据库连线关闭。 把数据表news中104笔数据全部抓出来并以阵列的形式放入$rows变数后,就可以开始进行分页的工作了。进行分页之前,需对分页功能的一些设定选项做设定。并把设定的结果放入一个阵列中。
第8行到第12行,就是一个简单的「分页设定项」所组成的阵列,在个范例中的设定项阵列设定了四个项目。分别是: ●mode : 设定分页的形式,设定值只可以是“Jumping”或“Slidhg”字符串,此范例先用Jumping方式。 ●perPage : 这个设定项目是设定每页出现的数据笔数,本范围设定每页显示5笔数据。 ●delta : 页面检索会出现的页码数量,本范围设定一次出现10个页码。 ●itemData : 要显示的数据所组成的阵列,此处指的就是$rows这个用连线物件的getAll()方法所取得的阵列。 事实上,分页相关的设定项目总共有32项,除了itemData这个项目是要设定的项目外,其它都可以用预设值。 有了$params这个阵列,就可以开始建立一个「Pager物件」了。方法一样是用new, 但是$params阵列必须当作建立物件的参数,如第13行。 pager物件建立完成后,笔者将该物件放入$pager变数中,也就是说,$pager变数就是一个依照$params阵列所指定的设定值来产生的Pager物件。 接着第14行用Pager物件提供的getPageData()方法,将网页浏览者点到选某页面时,属于该页面的数据全部抓出来,放入$datas变数中。例如网页第1次载入时的画面是第一页,getPageData ( )方法就会将第1页的5笔数据用阵列的形式放入$datas变数中,若是使用者点选第5页的页码,$datas变数的内容就是属于第5页的5笔数据所组成的阵列。 剩下的工作,就是使用者所点选的那一页的数据显示出来,整个范例就可以大功告成了。
可大功告成了 第19行, 利用foreach迥圈,将$datas阵列中的5笔数据一笔一笔地取出并放入$data变数中。 第2l行与第22行中,配合一些HTML标签,将每笔数据中第2、第4、第16个栏位的数据显示出来。 第27行,使用Pager物件的getLinks ( )方法来建立「页数检索」,这个方法会传回所有页码超连结的HTML标签,这些都是以阵列的形式放入$Links变数中,这个变数中有一个较为特殊的key叫做“all”,这个key的value的值其实是页码超连结的HTML标签合而成的。 第28行用echo的方法将$links变数中,key为“all”的value显示出来。 最后第32行用Pager物件的的numPages()方法与numltems()来取得总页数与总数据笔数,并用echo的方式显示给使用者知道。 执行结果如下: 可以清楚看到每页显示5笔数据,而且页码只出现1~10,完全符合笔者设定的$params阵列的值。 $links [‘all’]变数的内容就是画面中倒数第2行“页数检索:” 后面的那一大串页码的超连结。在最下方,可看到Pager物件的numPages()方法与numItems()方法分别取出的总页数为21与总数据笔数为104这两个字。 若笔者将上一个范例中$params阵列的mode设定项目改为“Sliding”字串,也就是分页的方式改为使用Sliding方式,另外将delta设定项目改为正整数5,其余程序码不变,此时delta代表的不是总共出现的页码,而是被点选的页码前后出现几个页码,则执行结果如下图,范例档名为example9-2.php: 页数检索的方式变成不一樣了,例如,当使用者点选页码8时,8会出现在页数检索的正中央,而且前后各有5个页码,符合delta的设定值,另外,前后各出现第1页与最未页的超连结,还有<<与>>这两个超连结让使用者翻页。 如果,使用者点选页码8后继续点选页码9,会变成页码9在所有页码的正中央,前后各5个页码,分页的方式就以这种方式一直滑下去(Sliding的意思就是「滑」),这种方式就称为Sliding。
综合以上说明,无论是Jumping还是Sliding的分页方式,可以将建立分页的基本流程分为以下几个步骤: 1.引用DB、Pager类別档。
2.用DB连线物件的getAll()方法取得所有数据录。
3.建立分页的设定项阵列。
4.建立符合设定项阵列的分页物件。
5.用分页物件的getPageData()方法取得某一页的数据录。
6.用foreach回圈将数据录内容显示出来。
7.显示所有页码的超连结。
8. 显示全部页数与全部数据录的笔数。 只要遵循以上8个步骤就可以建立一个基本的分页机制,至於更进阶的分页设定或分页物件的其他方法,后面笔者再进一步的逐一說明。
▓1-5设定项的设定 上一个范例中,笔者在$parmas阵列中设定了最基本的四个设定值,事实上,Pager物件的两种分页方式总共有32个设定项目可以设定,这32个项目除了itemData外都有预设值,若开发者没有在$params阵列中特别设定某些项目的值,Pager物件将会使用预设值。 为何要有这麼多的设定项? 因为无论是Jumping或Sliding,虽然都十分好用,但是有些开发者可能对分页的效果想要做细部调整,例如华人世界的开发者,想将分页中文化等。这些需求都可籍由设定项目的设定来修改分页的外观,以符合开发者的需求。 底下就经常会用到的设定项目分別加以說明: ►itemData、perPage、deIta 、以及mode等四个设定项 这四个设定项先前范例中已经有提到并說明之,所以笔者不再赘述。只将这些设定项的设定值的数据型态再加以补充。 ●itemData:设定值须为阵列,阵列內容就是所有要显示的数据录,这个项目是唯一沒有预设值的项目。 ●perPage:设定值须为大於0的正整数,代表每一页希望出现的数据笔数。 ●delta :设定值须为大於0的正整数,对Jumping模式而言,de!ta代表页数检索中出现页码的总数,对Sliding模式而言,delta代表被点选的页码前后出现的页码数目。 ●mode:设定值只可以是“Jumping”或“Sliding”两个字串,代表的意义是分页显示的模式。 ►currentPage设定项 这个设定项若要可以使用,Pager套件的版本需大于2.2.6版。设定值的型态须为大於0的正整数。这个设定项可让网页第1次载入时,出现的页面不是第1页,至於是第几页,则由设定值来決定。 例如,笔者希望网页一载入就出现第3页,沿用example9-2.php的范例档做說明,只要在$param阵列中多加入一行:
也就是说$params阵列变成:
其余的程式码完全一樣,修改后的网页存成范例档example9-3.php,执行结果如下图: 由上图可看出,第1次载入exeample9-3.php出现的不是第1页,而是第3页。
►urlVar设定项 这个设定项足用来更改分页的urlVar变数的名称。所谓urlVar变数,是一个用来放置网页浏览者所点选的页码,并供服务器判断该显示哪一页的一个变数,通常会附在url之后,urlVar预设的变数名称是pagelD。 例如,笔者将范例档example9-1.php 原封不动的拷贝成范例档example9-4.php,执行后当笔者点选页码3,网址列的url后面会出现“?PageID=3”,也就是說,点选超连结时,有一个名为$pageID的变数,其值等于3,会借由get的方式将变数与值送到服务器端,供服务器辨认浏览者点选的页码。 执行结果如下图:
若笔者修改example9-4.php档的原始码,在$params阵列加入一行设定,内容为: 这个设定的意思就是将预设的urlVal变数的名称由pageID改为mypageid,存档后重新执行example9-4.php,会发现url后面的变数名称已改变,如下图: 上图中可清楚看到,网址列后面的变数不是pagelD了,变成是mypageid。 对大家而言,可能会有一个疑问,改url的变数名称会用在什麼情況下呢?其实,这个设定项会需要修改大都是因为用在一个网页內有两个以上分页的情况。 若一个网页有两个以上的分页机制,而预设的urlVar名称都是pagelD.也就是沒有修改这个设定项的话,会造成分页时的混淆,若浏览者点选某一个分页的页码,其他分页也会跟著变动,所以若有两个以上的分页机制,则每个分页都必须将urlVar改为不同的名称,才不会造成这种现象。
►altPrev、altNext、以及altPage设定项 这三个设定项都是用来修改超连结的ALT属性內容,而且设定值的型态都必须是字串。 何谓「ATL属性」? 当使用者将鼠标指向网页內某一个超连结的瞬间,鼠标旁会出现小小的方框,內有该超连结的简单說明,这就是ALT属性。假设笔者将范例档example9-1.php拷贝成example9-5.php,执行后在页数检索中会出现三种ALT属性: ⒈ 当使用者鼠标移到< ⒉ 当鼠标移到页码的超连结时,滑鼠旁会出现“pageX”,其中X代表页码,如下图:
当鼠标到Next>>这个超连结时,鼠标旁会出现“next page”,如下图:
若开发者希望修改这三个ALT属性,只需要在$params中加入三个设定:
也就是example9-5.php的$params阵列改为:
其余程式码维持不变就可以了。 altPrev设定项代表的是<>这个超连结的ALT属性,altPage设定项代表的是页码连结的ALT属性。 Example9-5.php修改后存档,并重新执行的结果会如以下图形: 第1个图形.当鼠标移到<
● 第2个图形,当鼠标移到某个页码的超链结时,ALT属性变成“页X”。 ● 第3个图形,当鼠标移到Next >>这个超链结时,ALT属性变成了“后一页”。
虽然,有些网页设计者不太重视ALT属性,但却有一些设计者对网页的每个细节者要求要做到尽善尽美,这三个设定项设与不设,就由读者您自己决定吧。
►prevImg与nextImg设定项 这两个设定项对使用中文的开发者而言就很实用了。Jumping方式的分页范例叫页数搜索的前后各出现了<< Back 与Next >>两个超级链接,这两个字都是英文,比较不适合华人的网页浏览者,若开发者想要将这两个超级链接的文字改为中文,只要改这两个设定就可以了,另外,这两个设定也可以让开发者使用图形来取代文字。 设定值的型态都是字符串,只是修改文字与使用图形的字符串内容会有所不同。 若在example9-1.php的$params数组中加入两个设定如下,并转存成example9-6.php: prevImg设定项代表<>改变后的文字。执行结果如下图: 出现中文字了,这对华人开发者而言是不是有些感动呀。 若开发者想改用图案来取代文字的话,首先当然需要先制作两个图片,例如,我自制了两个很丑的图片( 让大家眼睛辛苦了),分别是pre.gif与next.gif,准备用来取代<> 将example9-6.php拷贝为example9-7.php当作范例文件,这两个图档放在与example9-7.php同一个路径下。 Example9-7.php的程序代码中$params数组的prevImg与nextImg设定项若更改如下: 这两个设定项的值是一行字 内容是插入图片的HTML标签。img代表图案的意思,src=的后面是图案的路径与文件名,border是图案的框线,预设为l个像素,笔者将范例中的框线改为0个像素宽。修改完成后存盘,执行结果如下图: 出现了,前后两个超级链接已经被自制的图档所取代。若您是一位非常会设计图案的读者,这两个可放入图案的设定项将可大大提升分页的美观度,让您的分页与众不同喔。 ►separator设定项 页码与页码之间需要有适度的分隔,页数搜索看起来才不会感觉拥挤。在Pager套件中,Jumping模式与Sliding模式页码间都有分隔,前者预设是使用空白,后者预设是使用“|”,若开发者想加入自己的创意,修改预设的分隔符,只要加入separator设定项就可以了。 这个设定项的值需为字符串,而字符串的内容除了符号或文字以外,也可以如同上一个范例般使用图片。 首先,笔者将范例example9-1.php,转存成example9-8.php,并在$params数组中加入一行设定如下:
这个设定的意思是说将分隔由空白改为“ * ”号,执行结果如下图: 页数搜索的分隔很轻易地就改变了。 若要将分隔改为图片的话,笔者第1步先将example9-8.php转存成example9-9.php当作范例文件,第2步我又做了一个好丑的图片(请见谅)名为sep.gif,同样放在范例文件相同路径下,第3步,修改程序代码中$params数组的separator设定项的值如下:
也就是将分隔符改为由sep.gif这个图档来取代。执行结果如下图: 这是笔者随手捡来的图案,作一个例子,相信读者应该可以设计出很美观的分隔图案,丰富您的网页内容。 ---------------------------------------------------------------------------- PEAR-像Google一样的分页功能(2)
第二篇PHP/PEAR
Pager套件像Google一样的分页功能
►spacesBeforeSeparator与spacesAfterSeparator设定项 这两个设定项目也是与分隔符号有关,spacesBeforeSeparator是设定分隔符号前需要有几个“空白”,SpcesAfterSeparator是设定分隔符后需要有几个空白。这两个设定项可拉大或缩小分隔的距离,让开发者随心所欲的调整分隔的宽度。设定值的型态都必须大于0的正整数,代表前后空白的数目。 范例文件名为example9-10.php,程序代码与范例文件example9-9.php唯一的不同在于$params数组中新增了两个设定,程序代码如下: 范例中假设了在分隔图案的前与后都增加了两个空白,执行结果如下图: 可以发现分隔图案与页码间的距离被拉开了,至于多少个空白才是最适当的,这就由读者自己做判断了。
►firstPagePre、firstPageText、firstPagePost与lastPagePre、lastPageText、lastPagePost设定项 先说明一下,这六个设定项目只可以用在Sliding模式的情况下,且设定值都需为字符串。 在sliding模式下,页数检索的最前方会出现第1页页码的超级链接,最后方会出现最后一页页码的超级链接。若开发者希望以不同形式来表现这两者的话。可以加入这六个选项来达到目的。 例如,若笔者希望执行的结果如下图:
第l页页码的超级链接改为{第1 页}文字型态的超级链接,最后页页码的超连结改为[ [最末页] ]文字型态的超连结。 程序代码中$params数组应该加入以下设定。范例文件名为eample9-11.php:
● 第1个设定项firstPagePre代表的是最前方文字左边外围的字符串,笔者范例是使用“{”符号放在文字的左方。 ● 第2个设定项firstPageText代表的是最前方的字符串,笔者范例使用“第1页”这个字符串。 ● 第3个设定项firstPagePost代表的是最前方文字右边外围的字符串,笔者范例是使用“}”符号放在文字的右方。 ● 第4个设定项1astPagePre代表的是最后方文字左边外围的字符串,笔者范例是使用“[[”符号放在文字的左方。 ● 第5个设定项lastPageText代表的是最后方的字符串,笔者范例使用“最末页”这个字符串。 ● 第6个设定项lastPagePost代表的是最后方文字右边外围的字符串,笔者范例是使用“]]”符号放在文字的右方。
这六个设定项目同样可以用图片来取代文字,假设笔者建立了四个图片文件,第1个图片名为left.gif,如图:
第2个图片名first.gif为,如图: 第3个图片名为right.gif为,如图: 第4个图片名为last.gif为,如图: 范例文件名为example9-12.php,四张图都放在范例文件相同路径下,与上一个范例档example9-11.php唯一的不同在于六个设定项改为: 也就是使用四个图档作为显示的内容,执行结果如下图: 是不是觉得很有趣呢? 这些设定可以让分页依照设计者独特的巧思来加
以改变,让分页与众不同。
►showAllText设定项 这个设定项需搭配Pager物件的getPerPageSelectBox ( )方法来使用,因此,这个设定项留待下一单元中介绍到getPerPageSelect( )方法时再来一并做说明。
►linkClass设定项 上面几个范例虽然可以更改许多分页的细部外观,可是视觉上仍稍嫌单调,若能套用CSS来改变页数搜索中超连结文字的字体,颜色,大小,将会使画面看起来更好看,这个设定项就是用来让超级链接套上CSS。 假设,笔者修改example9-1.php,在网页最上方加入了一段CSS,内容是建立了一个名为1ink的class,并希望“页数搜索”后面的超级链接能套用此CSS的class,来改变分页的外观。范例文件名为example9-14.php,程序代码如下:
第1行到第9行包在刁中间的设定就是所谓的CSS,其中定义了一个名为1illk的class(请注意,1ink前需要有一个“.”)。 第4行定义了这个class的文字大小为12像素,第5行定义了文字颜色为#663366,第6行定义了文字的背景色为 CCCCCC。 接下来的内容与范例文件example9-1.php完全一样,只有$params数组中多了一项设定,位于第22行。 这个设定项定义了页数搜索后面所有的超级链接文字都必须套用link这个class,套用的结果如下图: 所有超级链接文字都变成了紫色(##663366), 背景色变成了淡灰色(#CCCCCC),有超级链接的数字,数字大小都变成12像素,是不是感觉很炫啊? 但请注意,这个页码没有超级链接,所以不会套用CSS的设定。 ►curPageLinkClassName设定项 上一个设定项定义了超级链接的文字可套用哪一个CSS的Class。套用后的结果,虽然不错,但美中不足的是,被导点选的页码因为没有超级链接,因此没有套用到CSS,相对于其它页码就显得文字较大,较为突兀。 这个设定项就是用来修正这个问题,就是说,这个设定项也可指定一个CSS的class来让被点选的页码套用。 假设笔者在范例文件example9-14.php中新增一个CSS的class名为content,这个class同样需放在之间,程序代码如下:
它定义了文字字体为新细明体,文字大小与link相同为12像素,文字颜色为橘色#FF6600。 另外,在$params数组中多加了一列设定,如下:
定义了被点选的页码文字需套用content这个CSS的class,执行结果如下图,笔者将范例文件转存成example9-15.php:
被点选的页码3变成了与众不同的橘色了。请注意,CSS的class名称当作设定值,需要使用字符串的型态。 ►clearfVoid设定项 这个设定项的值需为布尔值,也就是设定值不是true,就是false,默认值是true意思是若数据项数少于一页,网页底下的“页数搜索”后面将不会出现页码。如下图:
若开发者希望全部资料不满一页时,页码搜索后面仍然出现1这归页码,只需将这个设定项放入$params数组中并设为false就可以了,程序代码如下:
范例文件为example9-16.php。执行结果如下图:
页数检索后面多了一个1,不会什么数字都没有,感觉有点空空洞洞的。
1-6 Pager物件的方法 Pager套件的使用方法,除了开发者可以更改设定项数组的值以外,当用new关键词建立一个Pager对象后,Pager物件也提供了许多的方法可以供开发者利用,底下笔者介绍比较常用的11个方法,这11个方法可弥补设定项的不足之处。
►getCurrentPageID方法 这个方法可传回目前所在页面的页码,回传值是个正整数。例如,浏览者正在阅读第3页,这个方法会传回正整数3。
►getNextPageID方法 这个方法可以传回目前页面后一页的页码,回传值是个正整数。例如,浏览者正在阅读第3页,这个方法会传回正整数4。若浏览者正阅读最后一页,这个方法会传回false。
►getPreviousPageID方法 这个方法可以传回目前页面前一页的页码,回传值是个正整数。例如,浏览者正在阅读第3页,这个方法会传回正整数2。若浏览者正阅读第l页,这个方法会传回false。
►numItems方法 这个方法可以传回Pager物件中所含数据的总项数,回传值是个正整数。列如,若数据的总项数是120项数据,这个方法会传回正整数120。
►numPages方法 这个方法可以传回Pager物件中的总页数,回传值是个正整数。例如,若数据总共被分为20页,这个方法会传回正整数20 。
►isFirstPage方法 这个方法可以侦测目前页面是否为第1页,回传值是个布尔值,若是第1页则传回true,其余传回false。
►isLastPage() 这个方法可以侦测目前页面是否为最后一页,回传值是个布尔值,若是最后一页则传回true,其余传回false。
►isLastPageComplete方法 这个方法可以侦测最后一页的数据项数是否刚好符合设定的每页数据项数,回传值是个布尔值,简单的讲,若每 需要显示5项数据,而最后一页刚好就是5项数据则传回true,其余传回false。 以上8个方法,笔者用一个范例文件example9-17.php来做说明,假设笔者共有105项数据,每页希望显示5项,换算成页数,应该会有21页,且最后一页刚好就是5项数据,另外,网页最下面的页码搜索希望每次出现10个页码。程序码如下: 这个范例文件第1行到第30行与example9-1.php完全相同,分页采用Jumping模式,并设定每页显示5项数据,每次出现10个页码。重点是从第32行到第40行,分别使用先前介绍的8种Pager物件的方法,将分页的讯息显示出来。 第1次加载网页的执行结果如下图: 读者可发现最下方「目前页码」为l,也就是使用者进入的画面是第1页。「下页页码」是2,「前页页码」没有显示,因为没有比1更少的页码了。「是第1页吗?」答案应该是传回true,这里要说明的是对PHP而言,若数据型态为布尔值,则1与true是相同意思的,所以图中的1并不是第1页.而是true的意思。「是最末页吗?」没有显示任何值,对PHP而言,若数据型态为布尔值I,则false与0或空值是相同意思的,所以此处是false的意思。「最未页刚好5项吗?」,侦测的结果同样是布尔值,出现1代表为true。 最下面一行再分别用numPages()方法侦测出总页数为21页,与numltems()方法侦测出总数据笔数为105笔。 若笔者点选第5页,结果如何呢? 与上图不同的地方在于「目前页码」变成5,「下页页码」变成6,「前页页码」变成4,「是第1页吗?」与」是最末页吗?」都传回false,其余皆相同。 若笔者点选最后一页,结果如下图:
与上图不同的地方在于「目前页码」变成21,「下页页码」变成没有值,因为第21页已经是最后一页了,「前页页码」变成20,「是第1页吗?」传回false,「是最末页吗?」传回true,其余相同。
GetLinks方法 这个方法在范例example9-1.php 中笔者就已经使用过,利用这个方法只要两行程序代码.就可以得到完整分页功能的超级链接。 用法是先执行getLinks()方法来取得由页码的超级链接与<>等超级链接的HTML标签所组成的数组。 比较特殊的是,当这个数组的key为“all”时,value将会是所有页码与<>超级链接所合成的的HTML标签。请回头复习一下范例exampie9-1.php的第27行与第28行: 第28行这一行所产生的HTML标签,可经由网页的原始码看到: 是不是很方便,一行程序代码就可以产生这么多的HTML标签,建立好所有分页的超级链接,节省了许多开发者撰写程序码的麻烦。
►getPageData方法 这个方法在范例example9-1.php中也使用过了,目的是用来抓取某页码的数据内容,并组成一个数组。例如,当浏览者点选页码5这个超级链接时,页码5内的所有数据都被抓取,并组成一个数组,如程序代码的第14行: 接着再用foreach循环,将数组中的所有数据,一笔一笔地数据显示出来,如程序代码的第19行到第23行: 第19行的foreach循环,会从$data 数组中每次抽取一笔数据,放入$data变数中,而$data也是一个数组型态的变数,key是由0开始起算的正整数,value是按顺序对应到字段的值,例如$data[1]代表该项数据录第2个字段的值。
►getPerPageSeclectBox方法 这个方法会提供一个Select组件,供使用者选择每页要显示的数据项数,也就是说,假设开发者原本设定每页显示5项数据,有了这个工具,使用者可以用select组件来更改为每一页显示l0项或20项数据。笔者直接使用范例文件exlmple9-13.php来说明,方便读者了解,程码如下:
先来看看执行的结果画面吧: 网页底下多了一个选单可让浏览者选择一页要显示几项资料,选好后按下送出钮就可以更改每页显示的项数了,若选择全部,则所有数据会全部放在一个网页中。 要让分页具有这种功能,首先,需要在设定项的数组中加入这一行 程序代码第13行的这个设定项目,在上个单元介绍常用的设定项时,笔者省略没有介绍,因为它必须搭配getPerPageSelectBox( )方法才有意义。 这个设定项主要的功能是设定选单中可以让浏览者选择显示所有资料于一页中的选项文字。例如,笔者若将showAllText这个设定项目设为“全部”这个字串,选单的最后一个选项就会出现“全部”这两个字,使用者若选择这个选项,所有数据将会全部显示于一个网页中。 除了这个设定外,接下来还必须建立一个表单,表单内至少要有Select组件与submit元件。程序代码从第34行到38行。 第34行是运用pager对象的getPerPageSelect()方法建立select组件的HTML标签,并放入$selectBox变数中。这个方法可以使用4个参数,第l个参数是起始直,也就是选单中第1个选项的数字;第2个参数是最末值,也就是选单中最后一个选项的数字;第3个参数是每个选项间相隔多少数;第4个参数是选单是否提供所有数据于一页的选项,若设为true,选单最后会出现showAllText设定项的文字,选择这个选项可以一页显示所有数据。 以笔者的范例而言,建立起来的选单会由10开始始,50结束,每个选项相隔20,并且是供所有数据显示于一页的选项,让浏览者点选。若这个方法没有设任何参数,则预设的起始值是5,最末值是30,每个选项值相隔5,也没有提供所有数据于一页让浏览者点选,所以说也没必要设showAllText这个设定项了,因为根本不会出现这个选项。 第35行用echo的方法显示表单的HTML标签,其中action的值为空,代表按下submit钮后数据的后端处理仍由表单所在的网页来进行。第36行会将$selectBox变数的内容显现出来,显现出来的原始码如下: 上值的原始码全部放在$SelectBox变量中,也就是说,$SelectBox变量内容是所有select组件的HTML标签。 第37行是建立submit组件,并将按钮上的文字设为“送出”。第38行是表单结束的HTML标签。 OK!大功告成了。细心的读者可能发现到了,除了以上程序代码外,这个范例档与example9-1.Php的程序代码都完全一样。
▓1-7一个纲页多个分工 同一个网页中可放人多个分页,是一个非常酷的功能,若开发者自行撰写PHP程序,难度会相当高,但对pager套件而言很简单就可以做到了。 需注意的地方只有四个,第1,先制造出多个pager物件,每个pager物件用不同的变数名称;第2,设定项数组的变数名称每个Pager物件须不同;第3,每倒Pager物件须有不同urlVar设定项;第4,放置不同分页数据的变数名称也要不同。这样就可以做到一个网页多个分页了。 为了举例给读者了解,笔者在范例的schoolnews数据库中,新建立一个名为anothernews的数据表,假设这个数据表的架构与范例news数据表完全一样。并将example9-1.php的程序代码全部复制一份放在原程序代码的下方,两段程式码中间加入一条水平线加以分隔(< hr >),经由稍微的修改就可以做出两个数据表的分页了。 范例文件名为example9-18.php,程序代码如下: 程序代码虽然看起来很多,但若加以区别的话,第4行到第36行是第1个分页第38行到第71行是第2个分页。 第1个分页中与范例文件example9-1.php较为不同的地方为第8行将原本设定项数组的$params变量名称改为$params1,并在第13行加入一个urlVar设定,改变预设的urlVar变量名称为pageID_1。 第15行建立第l个pager物件时,参数要改用$paramsl,并将建立的物件放$pager1变量中,第16行用物件的getPageData()方法将所抓取的数据数组放入$datasl的变数中。 第21行到第25行利用foreach 回圈将每项数据显示出来就完成了第1个分页,请注意,变数名称不可弄错。
最后要注意一下第29行,用pager物件的getLinks()方法得到所有分页超连结的HTML标签后,放入的变量名称也改为$links1了。 第2段的分页与第1段分页要修改的地方都一样,只是将变量名称后的“1”改为“2”藉以区别而已。 如第43行将设定项数组的变量名称改为$ params2,第48行将urlVar变数名称改为$pageID_2. 第50行建立另一个新的pager物件,并以$params2作为参数,产生的新物件放入$pager2变量中,接下来,若有使用pager物件的方法,物件名称要改用$pager2喔,如第51行同样使用getPageData()方法将每页所含的数据数组放入$datas2变数中。 用foreach循环,将第2个分页的$datas2 阵列中的数据一项项的抓出,并显示出来。请见第56行到第60行。
最俊也请不要忘getLinks()方法所得到的分页超级链接的HTML标签,要放入变数$links2中。请见第65行。 执行结果如下图:
出现了,两个不同的分页。若笔者分点选第l个分页的第5页与第2个分页的第2页,可看出网址列后面会出现一段字符串: 代表Pager套件会自动产生两个变数,而且这个网页会用两个不同的urlVar变数来控制两个分页,两个分页系统不会 因为同在一个网页而发生错乱。
▓1-8结论 这个套件介绍到此可以告一个段落了,除了少数几个较少用到的方法与设定项外,常用的设定项与Pager物件的方法,笔者几乎都有用范例文件加以说明。 最后有一点要注意的,就是若读者使用的是PHP5,在建立pager物件时,不可以使用new的方式了,如下程序代码:
请改用Pager类别的factory的方法来建立pager物件,也就是说上一行的程序码,请以底下这一行的程序代码来取代;
否则会发生错误喔,这是因为PHP5 与PH4的物件导向设计上有些不同,套件开发者只好另行用factory方法来取代new关键词来建立新物件。
全文完
相关阅读 更多 +