Computerworld

Using PEAR

The PHP Extension and Application Repository (PEAR) is an open source structured library of packages for PHP developers. These packages provide routines which solve problems PHP developers regularly face: sending structured e-mail (such as an HTML attachment), interacting with different databases from a single script, error handling, recovery and logging.

Python vs. PHP: Choosing your next project's language

The base installation of PEAR is shipped with PHP itself. The programmers working on PEAR have developed a method of installing new packages and keeping your existing installation up-to-date, called the PEAR package manager.

PEAR package manager

If you are using a version of PHP prior to 4.3, you will need to install the PEAR package manager. UNIX users can run the following command:

lynx -source http://go-pear.org/ | /path/to/php

This downloads the source of the page at http://go-pear.org and runs it with the PHP binary (replace /path/to with the path to PHP on your system).

Windows users should go to the specified URL and save the page as 'pear.php' then run the following in DOS:

\path\to\php pear.php

The installation process creates a program called pear (this program is shipped with PHP 4.3), which is the PEAR package manager. Once installation is complete, you are ready to interact with the PEAR package manager.

Using the package manager

The PEAR package manager requires Internet access to download and install new packages. Make sure you are connected to the Net before proceeding. Before downloading new packages, it is useful to see which PEAR packages are installed. To do so, run:

pear list

This prints a formatted list of the package names, their version, and their status (whether the release is stable, in beta or otherwise). For basic installations, this list is quite short. To see all available PEAR packages, run:

pear remote-list

To install a package on the remote list, type:

pear install <package name>

For example, a package which is not installed by default is Mail_Mime. To install Mail_Mime type:

pear install Mail_Mime

You can find out more about Mail_Mime with the following command:

pear remote-info Mail_Mime

Using PEAR

PEAR uses classes and objects to provide a unified interface to the extensions provided. The following code shows how easy it is to use.

01 <?
02 require_once("Mail.php");
03 require_once("Mail/mime.php");
04
05 $html = "<HTML><BODY><p>Hello World, in HTML</p></BODY></HTML>";
06 $mime = new Mail_mime();
07
08 $mime->setTXTBody(strip_tags($html));
09 $mime->addAttachment($html,"text/html","test.html",false);
10
11 $body = $mime->get();
12 $headers = $mime->headers(array("From" => "test@myhost.com.au", "Subject" => "Test"));
13
14 $mail =& Mail::factory("mail");
15 if(!$mail->send("you@yourhost.com.au",$headers,$body)) {
16 echo "Could not send email";
17 }
18 ?>

This short script generates a MIME-formatted e-mail with plain text and HTML parts. Lines two and three include the files Mail.php and mime.php, where the PEAR classes to be used are stored. We use require_once() instead of include(), since PEAR packages might also call include(), causing an error.

On line six, we create an object, $mime, from the Mail_mime class. Mail_mime methods allow developers to create multi-part MIME e-mails. On line eight, we add a text-based MIME section using the setTXTBody() method. On line 9, we attach the HTML version using the addAttachment() method. The first argument to this method is the string to attach, $html. The next argument specifies the MIME content type - in this case, text/html. The third argument specifies a file name for the attachment to be called and the fourth tells addAttachment() whether the string passed as the first argument is a file name or not. We tell it that it is not a file name (and that, therefore, it is the data which should be attached). On line 11, we generate the multi-part MIME body of the e-mail. On line 12, we generate the e-mail headers (the from address, and the e-mail subject); change these to suit your own situation.

Line 14 generates our mailer object, which is used on the following line to dispatch the e-mail, using the send() method.

Page Break

Using PEAR: Part II

In the previous page we looked at managing and installing PHP Extension and Application Repository (PEAR) packages, as well as how to use such a package from a PHP script. Now we will look at some of the other packages in the PEAR library.

The packages required for this column are available from www.pear.php.net.

To install them into your local PHP system, copy all packages from the PEAR site into a temporary directory, then type:

$ pear install

Where <package filename> is the filename of the package you are installing. The packages are stored in tar gzipped format, so you may get an error like this:

The extension 'zlib' couldn't be found.

Please make sure your version of PHP was built with 'zlib' support.

If so, you will need to rebuild PHP passing the '--with-zlib' argument to configure (see the INSTALL file in the PHP source archive on the cover CD for more information).

File system packages

It is often convenient to store information for your Web application on the file system. Using the File_Find PEAR package you can search and map directories used by your application. Consider the following simple script, which lists all files ending with .php in a specified directory:

01 <?
02 require_once('PEAR.php');
03 require_once('File.php');
04 require_once('File/Find.php');
05
06 $ff = new File_Find();
07 $files = $ff->glob("/.*\.php$/","scripts/","perl");
08 ?>

Lines 02, 03 and 04 include the relevant PEAR package files. Line 07 creates a new File_Find object. Line 08 calls the glob() method with three arguments: the first a search pattern, the second the directory to search - in this case, the directory scripts/ - and the third the search algorithm to use. The search pattern may look strange to readers unfamiliar with Perl regular expression syntax. It means: match strings ending in '.php'. For more information on Perl regular expressions see the Regular Expression Functions (Perl Compatible) section of the PHP manual.

This script can easily be expanded to search all sub-directories by calling the search method.

$files = $ff->search("/.*\.php$/","scripts/","perl");

Alternatively, it might be useful to build a map of a directory hierarchy and its files. This can be done by calling the maptree() method:

$files = $ff->maptree("scripts/");

This returns a two dimensional array. The first element, $files[0], is an array of sub-directories; the second element, $files[1], is an array of files in those sub-directories.

Search and replace

PEAR makes it easy to search multiple files and replace strings of text. Consider the following script, which changes a copyright string in each file.

01 <?
02 require_once('PEAR.php');
03 require_once('File.php');
04 require_once('File/Find.php');
05 require_once('File/SearchReplace.php');
06
07 $ff = new File_Find();
08 $files = $ff->search("/.*\.php$/","scripts/","perl");
09
10 $fsr = new File_SearchReplace("Copyright Abc, Inc. 2002","Copyright Abc, Inc. 2003", $files, "scripts/");
11 $fsr->doSearch();
12 ?>

This script builds on the file system search functionality we looked at above by building a list of files that we want to manipulate (line 08). Line 10 creates a File_SearchReplace object. We pass four arguments to the object constructor: the first argument is the string to replace, the second argument is the replacement string, the third argument is an array of files to search and replace in, and the fourth argument specifies the directory in which to look.

Line 11 performances the actual search and replace.

Logging

Logging can be a very important part of application development, debugging and management. The PEAR Log package provides a convenient mechanism for doing this in a standardised manner.

01 <?
02 require_once('Log.php');
03
04 $log = Log::singleton("file","log.txt");
05 $log->log("Log file test");
06 $log->WriteOut();
07 ?>

Line 04 creates an instance of the object we're interested in: namely, a file-based logging object (argument one) that logs to log.txt (argument two). Line 05 buffers a log message inside the object and line 06 writes the buffer to log.txt. This last point is very important: if you do not call the WriteOut() method the log message(s) will be lost.