In my Beyond Frameworks talk, I explained how a component-based architecture can help answer some of the important (i.e. expensive!) questions you might face when creating long-lived apps that rely on a PHP framework. In this series of blog posts, I’m going to look at how to go about creating and working with components.

I’m now going under the bonnet of our components, and looking at the different file roles that the PEAR installer expects to find when we distribute our component as a PEAR-compatible package. Documentation is very important to your users, but what you ship in your PEAR-compatible package should really be just the bare minimum.

Documentation Is The Missing Feature

I’m sorry to report that there is currently a large gap when it comes to handling of documentation in PHP’s PEAR-driven packaged ecosystem.

  • There is no standard markup format(s) for documentation shipped in packages.
  • There is no standard structure to install a package’s documentation into.
  • The PEAR installer does not gather up all of the installed documentation to generate a single PHP Manual-style local website of all of the installed PEAR-compatible packages. This would be a killer feature for someone to create.
  • The PEAR installer does not auto-generate PHPdoc-compatible documentation from all of the installed PEAR-compatible packages after installation.

The pear.php.net website hosts documentation for the PEAR project, but at the time of writing this documentation isn’t shipped with PEAR (or PEAR-compatible) packages.

During the rehersals for my Beyond Frameworks talk, my test audience was crystal clear about the importance of documentation. The PHP Manual is undoubtedly one of PHP’s killer features, and it rightly sets a high standard for the documentation that developers should expect to both create and have provided to them. The process and toolset for documenting PEAR-compatible packages isn’t yet a mature practice, and there’s definitely an opportunity for someone to step up and plug this gap.

This doesn’t mean that it’s a waste of time documenting your packages; it just means that, today, you’re better off including some documentation in your package, and publishing the rest of the docs somewhere else.

What Are The Docs You Should Include In Your Package?

Every PHP component should, as a minimum, ship the following documentation inside the PEAR-compatible package:

  1. LICENSE.txt – what copyright and licensing terms apply to the package
  2. README.txt – general information about the package, and where to find the package’s main website

The LICENSE.txt file is absolutely essential: it tells responsible developers whether or not they can legally use your work in their project, and just as important it sets the scene for whether or not anyone can fork your component should you decide not to maintain it any more. This file should contain the full text of the license. If you are not sure which license to use, the PHP ecosystem strongly prefers the new BSD license or the MIT license.

(You should also include license details in your docblocks at the top of your source files; that is a topic for later in the series).

The README.txt file is also essential: at the very least, it tells developers where to go to find your component’s website and full documentation. If you publish your source code via GitHub, you can write this file as README.md (using GitHub’s flavour of Markdown) and GitHub will automatically pick up the file and display it on your repository’s homepage (as an example, see phix’s homepage).

Quite a few existing PHP components also include a CREDITS.txt file, although some PHP components prefer to publish this information on their website instead.

Where Do Docs Go Inside Your Component’s Structure?

If we look at the ComponentManagerPhpLibrary component, you’ll find that the essential documentation files actually live in the component’s top-level folder:

The component skeleton will automatically pick up any files in the top-level folder that match the patterns ‘*.txt’ or ‘*.md’.

Where Does The PEAR Installer Install The Docs?

When you use the PEAR installer to install your component:

$ pear install phix/ComponentManagerPhpLibrary

all of the documentation files get installed into /usr/share/php/docs/<package-name> on your computer:

The PEAR installer’s behaviour here is different to both command-line scripts and PHP code; the installer creates a sub-folder with the name of your package, and then installs your doc files into this sub-folder, and not into the main doc_dir folder. This isn’t a problem in practice, as long as you are aware of the different behaviour here.

The doc file README.md therefore ends up installed onto your computer as /usr/share/php/docs/ComponentManagerPhpLibrary/README.md.

There’s always the possibility that some Linux distros (and Mac OS X) will install doc files into a different folder. You can see where the PEAR installer will put these files on your computer by running:

$ sudo pear config-show | grep doc_dir
PEAR documentation directory   doc_dir          /usr/share/php/docs

Okay … So What Should We Do About Proper Documentation?

Anyone getting started with your component clearly needs a lot more documentation than a LICENSE and a basic README. Unfortunately, as discussed at the start of this article, today the PEAR installer has poor support for shipping the sort of high-quality, in-depth documentation that your users both expect and deserve.

For now, the right thing to do is to publish your documentation on a website. I’m going to look at that in detail later in this series, after I have finished looking at the rest of the file roles supported by the PEAR installer.

3 comments »

In my Beyond Frameworks talk, I explained how a component-based architecture can help answer some of the important (i.e. expensive!) questions you might face when creating long-lived apps that rely on a PHP framework. In this series of blog posts, I’m going to look at how to go about creating and working with components.

I’ve just put out ComponentManager version 1.1.3, with the following (hopefully useful) changes:

Bug Fixes For The php-library Skeleton

  • Any text docs in your component’s top-level folder (such as LICENSE.txt and README.md) will now be automatically picked up and added to your PEAR-compatible package as documentation to install.

How To Upgrade

To upgrade your installation, please do the following:

$ pear clear-cache
$ pear upgrade pear/pear
$ pear upgrade Gradwell/ComponentManager

Once the latest version of ComponentManager has been installed, you will need upgrade the skeletons of your existing components by doing:

$ cd <where-I-put-it>/<my-component>
$ phix php-library:upgrade .

This release has been tested on:

  • Ubuntu 10.10
  • Fedora 14

Any problems, let me know.

2 comments »

A couple of weeks ago, I posted a call for requirements for a PEAR channel aggregator.

There’s already been a sizeable response so far, but if you haven’t had your say yet, please head on over and leave a comment soon.

I’ll write up a summary of the suggested requirements on Monday.

1 comment »

At #phpsw this week, former Gradwell-er and all-round good guy Ade Slade delivered a great talk about DbUnit. Testing in general, and doing testing the right way in particular, is one of his great passions as a developer, and he certainly brought a lot of enthusiasm and hands-on experience to an often-neglected part of unit testing one’s code.

The talk and slides are on Ade’s blog.

Be the first to leave a comment »

In my Beyond Frameworks talk, I explained how a component-based architecture can help answer some of the important (i.e. expensive!) questions you might face when creating long-lived apps that rely on a PHP framework. In this series of blog posts, I’m going to look at how to go about creating and working with components.

I’m now going under the bonnet of our components, and looking at the different file roles that the PEAR installer expects to find when we distribute our component as a PEAR-compatible package. Although the vast majority of your components will simply be libraries of code, sometimes you might need to ship data files for them to operate on. Thanks to the PEAR installer’s data role, this is possible.

What Is A Data File?

A data file (the ‘data’ file role supported by the PEAR installer) is an arbitrary file that your code either reads from, or (in the case of images et al) serves up to other programs.

There are some important practices and limitations that you need to follow to avoid any disappointments or nasty surprises:

  • Data files should not be PHP code that you plan on executing.

    Your users expect your code to be in the standard place (which is /usr/share/php for popular Linux systems, or vendor/php/ in the per-app sandbox). Follow the rule of no surprises, and make sure you put your code where your users expect to look for it.

    For example, PEAR’s HTTP2_Request component ships PHP code in its data folder, code to rebuild the Public Suffix List (which is, itself, a data file). The chances are that most of HTTP2_Request’s users are unaware that the data folder exists, and that there is code in the data folder which they might need to use. Another example is ezComponent’s ConsoleTools, which ships a UML diagram for ezComponents in its data folder. This probably belongs in the docs folder, if it is meant to be read by developers using ConsoleTools. My local /usr/share/php/ contains many more relevant examples; yours’ probably does too.

    Our component skeleton offers an alternative approach, to ship generate-list.php a properly-installed command-line program, or perhaps as a drop-in command for phix.

  • Data files cannot be written to; your code should treat them as read-only.

    When your data files are installed for system-wide use, the files are owned by the root user. Unless there is an almighty security cock-up, your code will never ever actually get to run with the root user’s security privileges. If your code tries to write to these data files, it will generate a runtime error.

    But this won’t show up when you unit-test your code. So remember, and don’t write the code in the first place :)

Where Do Data Files Go Inside The Component’s Structure?

If we take a look at the ComponentManagerPhpLibrary component, you’ll find the data files are inside in the src/data/ folder. These are the skeleton files used for a PHP library component.

src/data/ is meant to be a folder that holds the data files that you want installed into the computer system.

Where Do Data Files Get Installed?

When you use the PEAR installer to install your component:

$ pear install phix/ComponentManagerPhpLibrary

all of the files in your component’s src/data/ folder gets installed into /usr/share/php/data/<package-name> on your computer:

The PEAR installer’s behaviour here is different to both command-line scripts and PHP code; the installer creates a sub-folder with the name of your package, and then installs your data files into this sub-folder, and not into the main data_dir folder. This isn’t a problem in practice, as long as you are aware of the different behaviour here.

The data file script src/data/php-library/README.md therefore ends up installed onto your computer as /usr/share/php/data/ComponentManagerPhpLibrary/php-library/README.md.

There’s always the possibility that some Linux distros (and Mac OS X) will install data files into a different folder. You can see where the PEAR installer will put these files on your computer by running:

$ sudo pear config-show | grep data_dir
PEAR data directory            data_dir          /usr/share/php/data

If you want to read these data files from your PHP code, you cannot safely hard-code the final installation location into your scripts; it will vary from OS to OS, and will also be different again if your component is installed into a vendor directory. You’ll need to locate these files using a different technique.

How Do I Locate The Data Files From My PHP Code?

Take a look at the top of the LibraryComponentFolder class from the ComponentManagerPhpLibrary component:

class LibraryComponentFolder extends ComponentFolder
{
    const DATA_DIR="@@DATA_DIR@@/ComponentManagerPhpLibrary/php-library";

@@DATA_DIR@@ is a token that, at runtime, the PEAR installer expands to be the fully-qualified path to the top of the computer’s data_dir. Underneath that, you need to remember to add your component’s name to the path, otherwise you’ll be scratching your head and wondering why you can’t find the data files!

(The full instructions that tell the PEAR installer to expand this token are added to your component’s package.xml file when we build the PEAR-compatible package. I’ll look at the final package.xml file in detail towards the end of this series of blog posts).

How Do I Unit Test PHP Code That Relies On Data FIles?

There is one important downside to this technique; any unit tests that rely on loading data from your data directory are going to fail, because @@DATA_DIR@@ is only expanded when the PEAR installer installs your component. At the time of writing, I don’t have an easy solution for this, but leave it with me, and I’ll find a solution for this before the end of this series of blog posts.

7 comments »
Page 1 of 3123