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.

This is a guest post by Martin Wernståhl. Martin is a university student at Chalmers University of Technology, Sweden, currently studying the first year of Engineering Physics. He started programming at an age of 9 by writing Not-Quite-C for LEGO robots. Since then he has been programming a little bit of everything until he started with PHP around five years ago. Using CodeIgniter at first, he soon started to write libraries and hack the core of CodeIgniter until he felt that it was too limiting and resorted to starting to experiment with creating his own ORM tools (IgnitedRecord, discontinued as he no longer uses CodeIgniter and RapidDataMapper, development paused because of indecision related to syntax) and lately he has gone back to experimenting with creating a very modular PHP framework. Martin has also been a very enthusiastic supporter and tester of Phix and ComponentManager since their first releases.

If you would like to contribute a guest post about PHP components, please poke @stuherbert on Twitter.

How to Host a PEAR Channel on GitHub

GitHub has a feature called GitHub pages which they introduced about 2.5 years ago. This enables you to host static files located in a specific branch in a repository (gh-pages) on GitHub’s webserver. This can also be used to host a PEAR channel and can be very useful for smaller projects or if you don’t have the time or money to configure a specific server for PEAR. An added bonus is that the content of your PEAR channel server will be versioned by git.

For an example of a GitHub hosted PEAR channel, see the Inject Framework’s PEAR channel page.

The Repository

First, create a new repository on GitHub for your PEAR channel. You may now wonder why I wrote a new repository, this is because of the fact that it is usually better to separate your projects and the PEAR channel repository because of the difference in content, plus, the repository name will be a part of the URL. You might also not want to limit which packages you can put in the channel because of the naming of the parent repository.

A recommended name for the new repository is pear, as that will be equivalent with ${yourusername}.github.com/pear. A must is that the name is lowercase, as GitHub’s URLs are case sensitive.

For an example repository hosting a PEAR channel, see the Inject Framework’s PEAR repo on GitHub.

Create Your Repository Locally

To create the repository we are going to use Pirum. Pirum is a PEAR channel server "generator" which generates static files which can be used by any PEAR installer to install your packages.

So, create a folder for your pear repository and then place a pirum.xml file there:

 
<?xml version="1.0" encoding="UTF-8" ?>
<server>
    <name>${yourusername}.github.com/${pear_repository}</name>
    <summary>${page_title}</summary>
    <alias>${short_prefix}</alias>
    <url>http://${yourusername}.github.com/${pear_repository}</url>
</server>

yourusername and page_title are fairly self-explanatory. pear_repository is the name of the GitHub repository you will store your PEAR channel in. But what does the <alias> tag do?

The contents of the <alias> tag is the channel alias which can be used instead of the contents of <name> when installing PEAR packages after you have run pear channel-discover. An example is the InjectFramework: instead of injectframework.github.com/pear/InjectStack you write injectfw/InjectStack [1].

Then we create our new Git repository, run pirum build . to create the PEAR channel, then link our repository with GitHub and finally create and push the gh-pages branch:

 
cd my/pear/repository
git init
pirum build .
git remote add origin git@github.com:${yourusername}/${pear_repository}.git
git add *
git commit
git branch gh-pages
git checkout gh-pages
git push -u origin master
git push origin gh-pages

Now you should receive a notification from GitHub (can be sent via email too depending on your notification settings) telling you that your page build was successful [2]. It might take as long as up to 10 minutes before your pages will appear on http://${yourusername}.github.com/${pear_repository} the first time you push your changes. Following pushes should update the pages almost instantly.

Now on to see if it works as it should; if pear channel-discover http://${yourusername}.github.com/${pear_repository} does not return any errors, everything went fine. You might want to check http://${yourusername}.github.com/${pear_repository} using a browser to see if it has been uploaded first, you will get a 404 if it is not.

Creating A PEAR Package Using Phix

If you are using Phix to help maintain your project, you have an environment which already is configured for generating PEAR packages. But first you have to configure Phix so that it will generate the proper package.xml file:

First we edit the project.channel value in build.properties:

 
project.channel=${yourusername}.github.com/${pear_repository} 

Then we go on to the package.xml file, most of the everyday stuff (like adding files etc.) will be handled by Phix, but the descriptions, version history and package requirements need to be edited manually. See the PEAR package.xml documentation for more information.

Don’t forget to bump version info in build.properties and change-log information in package.xml when you are creating a new package version.

When you have got the package.xml and build.properties configured properly, use the command phing pear-package to create a PEAR package which will be placed in dist/${<packagename>}-X.Y.Z.tgz

Adding The Package To Your PEAR Channel

To add a PEAR package, you just use:

 
pirum add my/pear/repository my_pear_package-X.Y.Z.tgz
cd my/pear/repository
git commit -a -m "Added my_pear_package-X.Y.Z"
git push

Then visit ${yourusername}.github.com/${pear_repository} with your browser to see a list of all the uploaded packages.

Conclusion

In the beginning there was only pear.php.net, the only resource for PEAR packages in the world. Then other package channels arrived, and publishing your own PEAR package channel became really easy with Pirum. Now you don’t even need your own web-server to host it; you can host it on GitHub, along with the source code for your PEAR package.

Now, if we only can get some kind of PEAR channel aggregator or similar thing to avoid having to use channel-discover for every new tool we want to install…

Footnotes

  1. The channel name must match the regular expression [a-zA-Z0-9\-]+(?:\.[a-zA-Z0-9\-]+)*(\/[a-zA-Z0-9\-]+)*
  2. You might want to turn off email notifications for successful page builds, because the emails can easily pile up if you make many pushes.

6 Comments

  1. Luís Otávio Cobucci Oblonczyk says:
    September 22nd, 2011 at 8:52 pm

    We don’t have a channel aggregator yet, but we can use auto-discovery feature:

    pear config-set auto_discover 1

    Then instead doing:

    pear install ${short_prefix}/${packageName}

    You can do:

    pear install ${yourusername}.github.com/${pear_repository}/${packageName}

  2. Luís Otávio Cobucci Oblonczyk says:
    September 22nd, 2011 at 8:53 pm

    Just a small fix…

    Then instead doing:

    pear channel-discover ${yourusername}.github.com/${pear_repository}
    pear install ${short_prefix}/${packageName}

    You can do:

    pear install ${yourusername}.github.com/${pear_repository}/${packageName}

  3. Daniel O'Connor says:
    September 22nd, 2011 at 10:21 pm

    Don’t forget to add in your channel to http://pear.php.net/channels/

    That will ensure it’s discoverable by http://pyr.us/ as part of https://github.com/pyrus/Pyrus/issues/33

  4. digifa’s devblog » Blog Archive » Einen eigenen PEAR-Channel bei Github anlegen says:
    September 23rd, 2011 at 7:11 am

    [...] Artikel [...]

  5. Christiaan Baartse says:
    September 23rd, 2011 at 8:52 am

    You might also want to check out Pearhub at http://www.pearhub.org it automates all this.

  6. Stuart Herbert says:
    September 23rd, 2011 at 11:59 am

    @christiaan only to a point; it expects the GitHub repo to basically be an uncompressed PEAR package. That’s very limiting in practice compared to the approach we’re advocating.