Developer FAQ

How do I become a PEAR contributor and/or how do I get SVN access to PEAR?

This is described here.

I have written a PHP module in C. What are the rules of including this in PEAR?

The PECL project (a spin-off from PEAR) is the place where C extensions for PHP are published.

Why is PEAR separated into pear/ and pear-core/?

The first elements of PEAR were stored in the directory pear-core (once php-src/pear) and so they were bundled with each new PHP release.

For future releases of PEAR this isn't workable because PEAR will become too big to be bundled with every release of PHP. So there was a decision to commit all new elements to an own top level directory pear. The other elements which are currently remaining in php-src/pear will be moved to the new top level directory soon. Only the PEAR package manager code will be bundled with every new release automatically.

Why does the directory structure of pear/ and pear-core/ differ?

The directory structure of pear-core/ matches that of the install tree (by default /usr/local/lib/php), and are organized as a simple hierarchy. However, the directory structure of pear/ is based on what package the files belong to. Where files are located in each package directory is completely independent from where they end up being installed, this is all determined by the package description file.

Why a flat directory structure instead of a deep?

In SVN, PEAR code is organized by package instead of hierarchical like it would finally be installed. For example, if you want to use the XML_RPC class, you include "XML/RPC.php". It's easy to think that in SVN, this file should be in pear/XML/RPC.php, but that's not the case. XML_RPC is an independent package with its own directory in SVN, in this case the RPC.php file is actually located at pear/XML_RPC/RPC.php. The package description file (package.xml) is used to say where the files should finally be installed.

The reason SVN is organized this way is that it makes package administration much easier.

Can I commit experimental/unstable stuff?

Yes. But make sure, that you mark up the experimental/unstable status of the project in the documentation. The best place to do this is in the package.xml in the <state>-tag. The values for this tag are

alpha
early stages of development, all things could change (API, behavoir) without notice, expect lots of bugs
beta
API should normally not change, usable software, expect bugs
devel
a release for other developers who want early access to test and give feedback, code quality may vary from pre-alpha to stable
stable
the software has a fixed API, it has undergone tests, and documentation exists. This release is a recommended release for use in production environments.
snapshot
a SVN snapshot from a certain date

Am I expected to add examples and/or test files to my package and where to store them?

Examples are a good idea, especially when your class has a complex API. But examples are only a part of a documentation. Don't create examples instead of a documentation. You should store the documentation and the examples in a sub directory 'docs' of the package directory.

Test scripts are recommended when your class has to be compiled, requires special extensions/programs or needs correctly installed additional files (i.e. templates, graphics). Store them in sub directory called 'tests'.

Are different packages or classes with similar features allowed?

There is no problem with competitive packages, but we want to avoid pollution with 10 template classes, 7 different mail classes, and 3 different layers for databases doing the same only with different function names.

First of all, do a reality check: Why do I want to commit a new package? Really bad answers are "To see my name in PEAR" or "I didn't understand the API of the existing class".

A good reason for a new class is often, that you are missing a function, behaviour or speed in an existing implementation. In this case, you should take a look at this class, if it possible to extend this class. If not, then you have a good reason to commit a new class. "If not" means, it isn't possible to add the required functionality without changing the basics of this class.

If you write a new class, try to keep API compatibility with existing classes as far as possible! If it isn't possible to keep the class compatible himself, try to create a wrapper class to keep compatibility. Don't care, if this wrapper needs a lot of time or memory, a wrapper class only has to keep compatibility and make migration easier.

Committing a competitive class has to be announced on the PEAR developers mailinglist!

A required package includes a package, my package needs it too. Should I include it again?

Yes. You should include every package, you need with require_once() or include_once (), also when it is included already by another package.

What licenses are allowed in PEAR/PECL?

Currently PEAR supports the following list of licenses:

Other licenses may be added to this list on a case-by-case basis. Please get in touch with the PEAR developers mailing list for this.

The allowed licenses were chosen to allow integration into closed source, open source as well as commercial applications. The only limitation is that the original credits must stay in the sources. For LGPL the license additionally requires that all changes to the source code must be licensed under the LGPL to anyone the source is distributed to.

From time to time people raise concerns of using PEAR packages licensed under the PHP license in GPL'ed code. In a discussion about this topic, the creator of PHP, Rasmus Lerdorf, issued the following statement:

It all comes down to semantics of what linking means. The PHP license is pretty much identical to the Apache license and you could indeed make a case for not allowing any GPL'ed software to be "linked to" from Apache either.

See http://www.apache.org/licenses/LICENSE-1.1.

The PHP license was chosen to match the Apache license because Apache and PHP are tied so closely to each other.

This hair splitting over linking, derivation and aggregation has been going on since the beginning of time. My stance is that you can indeed ship PHP licensed PEAR components on the same cd or in the same tarball as GPL'ed code because I see it as an aggregate work. This changes if you take PEAR code, modify it and copy-paste it directly into your own work. Then it moves from aggregate to derived. But the intent of the PEAR components is to be used in aggregate form. The PHP license allows you to use it in derived form as well, of course, but then you should be choosing a license other than the GPL for the derived work.

The FSF has a FAQ on aggregation here: http://www.fsf.org/licensing/licenses/gpl-faq.html#MereAggregation

That text is heavily biased towards compiled software and they talk about executables and memory spaces which don't really apply in this case. If you don't consider using a PEAR component as aggregation then it logically follows that you also cannot have Apache call your code so you will have to stipulate that nobody can use your code from Apache. I think this is an extreme interpretation that pretty much nobody out there shares.

In short, I don't see an issue here. Move along.

For PECL extensions that are linked into PHP, the license must be compatible with the PHP license. That means you can not GPL a PECL extension or you would be violating the GPL. Note also that if you write an extension that links against a GPL'ed library you will be violating the GPL. If you need to link against a GPL'ed library, get permission from the author of the library to use the library under a compatible license.

The license of any PEAR/PECL package can be found in the head of all source code files, inside the <license> tag of the package description file (package.xml) and also on the package homepage.

Why does the PEAR coding standard insist on space-only indentation?

Using spaces and avoiding tabs is the only way to ensure that a piece of code is rendered consistently in all editors and viewers. Many editors render tabs as 4 spaces, and a lot of editors, terminal programs and utilities render tabs as 8 spaces. Example:

printf("%s",
       $arg);

Here, there are 7 spaces before "$arg". If this code was written in an editor with 4-space tabs, it would store it as one tab and three spaces. Now, if another developer edits the same file in an editor with 8-space tabs, it will look like this:

printf("%s",
           $arg);

Likewise, consider this code written with 8-space tabs:

    if ($foo &&
        $bar) {
    }

If viewed in a 4-space-tab editor, it will look like this:

    if ($foo &&
    $bar) {
    }

In a community like PEAR where people use lots of different systems and editors, using tabs simply doesn't work. People will end up doing whitespace commits fixing rendering in their editor, while breaking it for others. With only spaces it will look the same to everyone.

Jamie Zawinski has written a piece on the subject too.

There is also a tool called Astyle which can help you convert your code to the appropriate style.