ÄúµÄλÖãºÑ°ÃÎÍøÊ×Ò³£¾±à³ÌÀÖÔ°£¾PHP ±à³Ì£¾PHP 5 Power programming
Team LiB
Previous Section Next Section

12.6. Building Packages

In this section, you explore the PEAR package system from the inside, learning how to build your own packages and how to make the most out of the installer. Following is an example package containing a PHP class, a command-line script, a regression test, and a package description file.

12.6.1. PEAR Example: HelloWorld

This is the minimal example, a single PHP source file implementing a class called HelloWorld:

<?php

/**
 * Hello World class.  The ubiquitous example.
 * @package HelloWorld
 */
class HelloWorld
{
    function HelloWorld($html = true)
    {
        if ($html) {
            print "Hello, World!<br />\n";
        } else {
            print "Hello, World! \n";
        }
    }
}

HelloWorld.php

Here is a command-line script called "hello" for demonstration:

#!/bin/sh
exec php -d output_buffering=1 $0 $@
<?php
ob_end_clean();

require_once "HelloWorld.php";

$hello = new HelloWorld(false);

hello

It is a good idea to write regression tests for your classes sooner rather than later. This example regression test verifies that the HelloWorld constructor's $html parameter works like intended:

--TEST--
HelloWorld test
--FILE--
<?php
include dirname(__FILE__).'/../HelloWorld.php';
new HelloWorld(false);
new HelloWorld(true);
?>
--EXPECT--
Hello, World!
Hello, World!<br />

HelloWorld.phpt

A .phpt file is split into sections that start with a single line containing --SECTION--. The following sections exist (see Table 12.2).

Table 12.2. Test Section Headings

Section

Description

TEST*

Short description of the test.

FILE*

Actual test code.

EXPECT*

The exact output that the test code should print.

EXPECTF

Expected output with some placeholders.

EXPECTREGEX

Regular expression matching expected output.

GET

HTTP GET variables (for example, a=foo&b=bar).

POST

HTTP POST variables; same format as GET.

SKIPIF

If this code snippet prints "skip," the test is not executed but marked as skipped.

ARGS

Command-line parameters; space-separated.

INI

Php.ini directives; directive=value, one per line.


The sections marked with "*" are required; the rest are optional. The EXPECTF section uses these placeholders (see Table 12.3).

Table 12.3. EXPECTF Placeholders

Placeholder

Description

%e

Platform directory separator, typically "/" or "\"

%s

Any string (not greedy)

%i

Any integer

%d

Any positive integer

%x

Any hexadecimal positive integer

%f

Any floating-point number

%c

Any single character


To package this class into a proper PEAR package, you need a package description file called package.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE package SYSTEM "http://pear.php.net/dtd/package-1.0">
<package version="1.0">
  <name>HelloWorld</name>
  <summary>Simple Hello World Package</summary>
  <description>
    This package contains a class that simply prints "Hello, World!".
  </description>
  <license>PHP License</license>
  <maintainers>
    <maintainer>
      <user>ssb</user>
      <role>lead</role>
      <name>Stig S. Bakken</name>
      <email>stig@php.net</email>
    </maintainer>
  </maintainers>
  <release>
    <version>1.0</version>
    <state>stable</state>
    <date>2004-04-24</date>
    <notes>
      First production release.
    </notes>
    <filelist>
      <file role="php"    name="HelloWorld.php"/>
      <file role="script" name="hello"/>
      <file role="test"   name="01-HelloWorld.phpt"/>
    </filelist>
  </release>
</package>

A comprehensive reference of all the XML elements of the package description format is found in "The package.xml Format" section later in this chapter.

12.6.2. Building the Tarball

With these two files (HelloWorld.php and package.xml), you can create a package tarball with the pear package command:

$ pear package
Analyzing HelloWorld.php
Package .../HelloWorld-1.0.tgz done
Tag the released code with 'pear cvstag package.xml'
(or set the CVS tag RELEASE_1_0 by hand)

The message about tagging the released code reminds package maintainers who work on the php.net CVS server to just ignore it for now.

HelloWorld-1.0.tgz is your package tarball. This file may be installed with the pear install command on any machine that has a PEAR installer.

If you do not have zlib support in your PHP build, the created package tarball will not be compressed, and the file name would be "HelloWorld-1.0.tar." Compressing it with an external gzip program will work in this case.

12.6.3. Verification

Use the pear package-validate (or pear pv) command to validate that your tarball is good:

$ pear pv HelloWorld-1.0.tgz
Validation: 0 error(s), 0 warning(s)

Validation fails if

  • You have defined symbols that are outside your package's namespace.

  • Required elements are missing in package.xml.

  • Dependencies are bad.

  • The file list is bad or missing.

Another way to verify that your package tarball works as you intend is to use the pear info and pear list commands:

$ pear info HelloWorld-1.0.tgz
ABOUT HELLOWORLD-1.0
====================
Provides        Classes:
Package         HelloWorld
Summary         Simple Hello World Package
Description     This package contains a class that simply prints
                "Hello, World!".
Maintainers     Stig S. Bakken <stig@php.net> (lead)
Version         1.0
Release Date    2004-04-24
Release License PHP License
Release State   stable
Release Notes   First production release.

The info output quickly reveals if something went wrong with the tarball creation:

$ pear list HelloWorld-1.0.tgz
CONTENTS OF HELLOWORLD-1.0.TGZ
==============================
PACKAGE FILE             INSTALL PATH
HelloWorld.php           /usr/local/lib/php/HelloWorld.php
hello                    /usr/local/lib/php/hello
tests/01-HelloWorld.phpt -- will not be installed --

Check the install path of each file and make sure it is what you intended. If a file ended up in the wrong location, go back to your package.xml file and set the baseinstalldir attribute in the <file> element for that file.

You should also install and uninstall it for a final verification and to ensure that the install/uninstall scripts are working. If your package uses the platform attribute in one or more <file> elements, you should repeat the same procedure for at least one platform that the "platform" rule matches, and for at least one that it does not match.

12.6.4. Regression Tests

Testing involves two things:

  • Installing and uninstalling the package to verify that the package scripts, if any, work and to finally test that the tarball is good

  • Running package regression tests with pear run-tests

This means we need to make a regression test for our HelloWorld package. These tests use PHP's ".phpt" format; here is an example:

--TEST--
HelloWorld test
--FILE--
<?php
include dirname(__FILE__).'/../HelloWorld.php';
new HelloWorld(false);
new HelloWorld(true);
--EXPECT--
Hello, World!
Hello, World!<br />

The --FOO-- lines mark the start of different sections. The .phpt format defines these sections:

  • TEST. Title of the test.

  • SKIPIF. PHP code (must start with <?php) run to determine whether the test should be executed at all. The test is skipped if this code prints skip.

  • FILE. PHP code that comprises the test itself.

  • EXPECT. The expected output of the PHP code in the FILE section.

  • GET. HTTP GET input variables (for example, foo=bar&ya=da, which requires CGI binary).

  • POST. Raw HTTP POST data (same format as GET data), which requires CGI binary.

The pear run-tests command looks for files with the ending ".phpt" in the current directory, or subdirectories called "tests."

    Team LiB
    Previous Section Next Section