MacDevCenter    
 Published on MacDevCenter (http://www.macdevcenter.com/)
 See this if you're having trouble printing code examples


PHP's PEAR on Mac OS X

by Jason Perkins
01/21/2003

The PHP Extension and Application Repository (PEAR) is an online repository of high-quality, peer-reviewed PHP classes that conform to a rigorous coding standard. Started in 1999, PEAR was until recently only available via its CVS repository. In order to download and install the packages it contained, developers needed to master a somewhat arcane set of commands, often copied and pasted from a FAQ, and usually assuming some level of familiarity with CVS in general.

The release of the PEAR Package Manager has changed all of that. In terms of functionality, it's similar to Perl's CPAN or Fink for Mac OS X in that using this command line utility you can browse, install, update, and remove PHP packages from a central, remote PEAR server to your local system. Installing, configuring, and using the PEAR Package Manager on OS X 10.2 is the focus of this article.

Laying the Groundwork

First, make certain that you've installed Apple's 2002-08-23 Security Update by running the Software Update application in your computer's System Preferences. Apple has updated at least one library that's required for this installation to work. Next you'll need to install the PHP CGI binary before you can run the PEAR Package Manager's Command Line Installer. Execute the following from a new window in Terminal to download and install the PHP CGI binary:


% curl -O http://www2.entropy.ch/download/php-cgi-4.1.1.gz 
% gunzip php-cgi-4.1.1.gz 
% sudo mkdir /usr/local/bin 
% sudo mv ./php-cgi-4.1.1 /usr/local/bin/php 
% sudo chmod 755 /usr/local/bin/php

To test the install, at the prompt enter:

% php -v

You should be rewarded with the current version of the PHP CGI binary that you just installed. If you see a message indicating that it wasn't found, make certain that /usr/local/bin is in your path by entering at the command line:

% echo $PATH

That command will generate output that looks something similar to:

/bin:usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/usr/lib:.

Each directory in the path is separated from the other directories by a colon. If you don't see an entry for /usr/local/bin listed in the output, then you'll need to identify your specific shell to modify its path. From the command line, enter:

% echo $SHELL

If /bin/tcsh is output, then execute these commands:

% echo 'set path = ($path /usr/local/bin)' >> ~/.cshrc 
% source ~/.cshrc

If /bin/bash is output from the echo $SHELL command then enter:

% echo 'PATH=$PATH:usr/local/bin' >> ~/.bash_profile 
% source .bash_profile

When a shell is initially launched, it looks for a configuration file in the home directory of the user that launched it. For tcsh this is the .cshrc file, and for bash it's the .bash_profile file. Within that file you can place several different types of configuration information, initialize new variables, or modify existing variables that the shell will use. We're interesting in modifying the $PATH variable.

As explained earlier, the $PATH variable is a colon delimited list of directories that the shell will search through for a command when you invoke that command from the shell. For instance, you know that ls will list the current directories contents.

Here's how this happens. When you type ls and press enter, the shell begins searching the directories specified in the $PATH variable (in the order in which they're specified in the variable) for the ls command. When it finds the ls command it stop searching and executes that command.

Related Reading

Learning Unix for Mac OS X
By Dave Taylor, Brian Jepson

We need to modify the $PATH so that we can enter php from the command line and have the shell able to locate and run the PHP binary. To accomplish this, we need to append the /usr/local/bin directory to the $PATH. That appending is what the first line in both cases accomplishes. Note that we said that the configuration file is read when the shell initially starts so our appending of the $PATH normally wouldn't take place until we launched a new shell.

The source command lets us get around that by causing the shell to read the specified configuration file at runtime. With those two commands we've modified the $PATH -- from now on when we launch a shell it will be able to find the PHP command in /usr/local/bin -- and we've caused the currently running shell to read its configuration file again. Now we can proceed with the current shell able to find and run the PHP binary.

I covered the two most common shells used; if you use an alternate such as zsh, then you'll need to check its documentation and add /usr/local/bin to its path. At this point, we've finished laying the groundwork and can start the installation of the PEAR Package Manager.

Installing and Configuring the PEAR Package Manager

To begin the installation of the PEAR Package Manager, enter the following at the prompt in Terminal:

% curl http://pear.php.net/go-pear | php

Note: If you're at all concerned about security, be sure to read the source of that URL first before executing it.

This command starts curl, has it access http://pear.php.net/go-pear, and pipes the source of that page (which is a PHP script) to the binary PHP executable that you just installed. As the installer runs, you'll be asked a series of questions by the script in preparation for the actual installation. First, you'll be asked to confirm that you want to install the PEAR command: press Enter to continue with the install. Second, you'll be asked for configuration details for a proxy if one exists. Third, you'll be asked to review the suggested file layout for the PEAR install. We're going to modify that section of the install.

The initial, default install of PHP on Mac OS X places the PEAR packages in /System/Library/PHP/PEAR. Placing the packages retrieved with the PEAR Package Manager there would entail either changing the permissions of that directory or running the Package Manager via sudo. For security reasons, neither of these options is attractive. We'll specify that the PEAR packages should be installed in the /usr/local directory that we established earlier. When the installer displays the directory scheme that it will use, modify it so that it matches the following:

Finally, you'll be asked to confirm that you want to install the packages that are bundled with the PEAR Package Manager; select yes for this option. With the setup questions behind us, the installer will run for a bit, creating the subdirectories that you specified if they don't already exist, downloading and installing the Package Manager and the additional packages that it requires. When it's finished, you'll be rewarded with:

The 'pear' command is now at your service at /usr/local/bin/pear Run it without parameters to see the available actions, try 'pear list' to see what packages are installed, or 'pear help' for help.

At this point, the installation is complete. For your local PHP install to make use of the local PEAR repository and the packages that you install there, you'll need to create or edit the file /usr/local/lib/php.ini and add (or modify) the include path to tell PHP the location of the new PEAR directory. First open the file in BBEdit (or your editor of choice) with:

% bbedit -c /usr/local/lib/php.ini

and modify (or add) the include_path variable to include the /usr/local/share/pear directory:

include_path = ".:/usr/local/share/pear";

When PHP processes a script and encounters an include statement, it will search the directories specified in the include_path for the included file. Each directory in the include_path is separated from the others by a colon. In UNIX parlance, the current directory is represented with a single period. Paraphrased, that include_path means: When PHP encounters an include, it should first look in the current directory for the specified file. If it's not in the current directory, then it should look in the /usr/local/share/pear directory for the specified file. Although I used the include statement for demonstrative purposes, this applies equally to the require statement.

If you haven't saved your modified php.ini, do so now. Congratulations, you now have the PEAR Package Manager installed and configured on your system. Now we'll discuss its use.

Using the PEAR Package Manager

With the Package Manager installed and configured, to see what packages the installer added to your system to satisfy its own dependencies, type:

% pear list

For a list of all packages available for installation with their version information and the current versions that you have installed, enter:

% pear list-all

All packages:
=============
+----------------------+--------+-------+
| Package              | Latest | Local |
| apd                  | 0.2    |       |
| PHPUnit              | 0.4    |       |
| Var_Dump             | 0.2    |       |
| Archive_Tar          | 0.9    | 0.9   |

For information about a specific package that's installed locally, use the pear info command:

% pear info XML_Parser

And you should see information similar to the following:

About XML_Parser-1.0
====================
+-----------------+------------------------------------------------+
| Package         | XML_Parser                                     |
| Summary         | XML parsing class based on PHP's bundled expat |
| Description     | This is an XML parser based on PHP's built-in  |
|                 | xml extension. It                              |
|                 | supports two basic modes of operation: "func"  |
|                 | and "event". In "func"                         |
|                 | mode, it will look for a function named after  |
|                 | each element                                   |
|                 | (xmltag_ELEMENT for start tags and             |
|                 | xmltag_ELEMENT_ for end tags), and             |
|                 | in "event" mode it uses a set of generic       |
|                 | callbacks.                                     |
| Maintainers     | Stig Saether Bakken <stig@php.net> (lead)      |
| Version         | 1.0                                            |
| Release Date    | 2002-05-09                                     |
| Release License | PHP License                                    |
| Release State   | stable                                         |
| Release Notes   | First independent release                      |
| Release Deps    | PHP >= 4.0.4pl1                                |
| Last Modified   | 2002-11-23                                     |
+-----------------+------------------------------------------------+

To get information for a package that you don't have installed locally, use the pear remote-info command:

% pear remote-info Net_Portscan

To install a new package, use the pear install command:

% pear install Net_Portscan

and to remove an installed package, use pear uninstall:

% pear uninstall Net_Portscan

Keeping your packages up to date with the latest releases either individually or en masse is done with the pear upgrade and pear upgrade-all commands:

% pear upgrade Net_Portscan

% pear upgrade-all

For now, install the Net_Portscan package by entering:

% pear install Net_Portscan

Were going to be using that in the next section when we cover using PHPDoc to generate the developer documentation for a package.

Generating Developer Documentation from PEAR Packages

Borrowing from Perl's PerlDoc and Java's JavaDoc, PHP has an application (natively coded in PHP, of course) called PHPDoc that will generate documentation for an installed package that's derived from that package's source code. To make use of PHPDoc, first make certain that it's installed using

% pear list

and look for the PHPDoc package. If it's not installed, install it using the PEAR Package Manager by issuing the

% pear install PHPDoc

command.

Before beginning the document generation, it's important to clarify that the word preceding the underscore of the package name indicates its subdirectory of the PHP Code Directory. When we initially set up the PEAR Package Manager, we specified that the PHP Code Directory should be located in the /usr/local/bin/share/pear directory. In the case of Net_Portscan, that means that the Portscanner class can be found in the Net subdirectory of /usr/local/bin/share/pear. Likewise, the XML_Parser can be found in the XML subdirectory. Now cd into to the Net subdirectory and do a listing of that directory's contents:

% cd /usr/local/share/pear/net 
% ls

You should see a listing of the Portscan.php package in addition to a couple of other packages. To generate the Portscan documentation, call PHPDoc with the s flag indicating the directory and filename of the package that you want to generate the documentation for. In the case of Net_Portscan, that should be:

% PHPDoc -s ./Portscan.php

The ./ preceding Portscan.php tells the Installer to use your current directory and within it the Portscan.php file. PHPDoc will run for a few seconds and you'll see output like this:

Parser starts...
... preparse to find modulegroups and classtrees.
... parsing classes.
... parsing modules.
... writing packagelist.
Parser finished.
Starting to render...

API Docs for ./Portscan.php done in /usr/local/share/pear/docs

4 seconds needed

Now use your preferred browser to open the file:

file://localhost/usr/local/share/pear/docs/index.html

Remember that this is beta software and the initial PackageList may be empty. That's fine because we can get to the information that we need by selecting ClassTrees and choosing the Net_Portscan link. You now have detailed documentation of the Net_Portscan class.

In the Public Method Summary, you'll see a method description that reads:

array  checkPortRange(string $host, integer $minPort, integer $maxPort,
[ integer $timeout ]) 
Check a range of ports at a machine

The first item, array, indicates the data type that this method will return, followed by the methods name (checkPortRange in this instance), followed by the methods list of parameters. The data type prepending each parameter's name is the data type that is expected of that parameter. Parameters in square brackets are optional.

Using PEAR Classes in Your Applications

Here's the code that we'll use to explore how to include and use installed PEAR packages:

<? 

  require_once("Net/Portscan.php");

  $scanner = new Net_Portscan;
  $host = "www.example.com"; 
  $minPort = 50; 
  $maxPort = 100;
	
  $activePorts = $scanner -> checkPortRange( $host,  $minPort,  $maxPort);
	
  foreach($activePorts as $portnumber => $status) { 
    if ($status) { 
      echo "port number $portnumber is open. <br />"; 
    } 
  }

?>

First we include the Portscan.php package by specifying the PEAR subdirectory and filename that it resides in. We're able to get away without specifying the complete path because we added /usr/local/share/pear to PHP's search path when we modified the php.ini. This will also be of use to us if were doing the development locally and upload it to a server for production that doesn't have the PEAR repository in the same location as it is on our local machine. By modifying the php.ini on the server, its PEAR repository can be located anywhere on that machine and our code will still work without modification.

PHP Cookbook

Related Reading

PHP Cookbook
By David Sklar, Adam Trachtenberg

We then create a new instance of the class and set the $host, $minPort, and $maxPort variables. We then call Net_Portscan's checkPortRange method. We know that $activePorts is going to be an array from the online documentation that we generated. Finally, we loop over $activePorts and echo any ports that were returned as active.

Conclusion

The PEAR project has made good strides toward being a working solution to the problem of distributing and versioning solid PHP packages. They're still working out some of the kinks and new features are being added daily, so some of the instructions here may be outdated by the time that you get a chance to use them. For additional, updated information on PEAR, check out its web site and consider subscribing to the PEAR mailing lists via this form.

Author's Note: PHP 4.2.3 is the version that this article is based on. The release of PHP 4.3 eases of the use of PEAR on Mac OS X as the PHP file at /usr/local/bin is now part of the default installation if you build PHP from source. It's unclear if Marc Liyanage of www.entropy.ch will be including that file in his packaged binary releases. I'm watching his site and when he releases his PHP 4.3 binary, I'll update this article to reflect any changes that may be required to get PEAR up and running using it.

Jason Perkins has been involved with Web design and development since 1996 and has recently started writing and technical editing.


Return to the Mac DevCenter.


Copyright © 2009 O'Reilly Media, Inc.