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.

Be the first to leave a 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:

[code lang=”php”]
class LibraryComponentFolder extends ComponentFolder
{
const DATA_DIR=”@@DATA_DIR@@/ComponentManagerPhpLibrary/php-library”;
[/code]

@@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.

Be the first to leave a comment »

I’ve had several conversations on Twitter about how it could be a good idea for someone to setup a new community website for PHP components. This website would not host components itself; it would track all of the independently-published PEAR channels, and be the one-stop shop for users to come to whenever they needed to find a component to solve a requirement.

I think this would be a good thing for the PHP ecosystem.

So – requirements! What do you want from such a website? What do you want it to do? How do you want it to work? At this stage, the sky’s the limit. Leave your requirements in the comments, please, and I’ll pull them together into a summary post next weekend.

Once the requirements are stable-ish, I’d like to organise a hackathon to get the first version built and live. If you’re up for that, and want to help make that happen, do ping me on Twitter: @stuherbert.

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. One of the useful file roles allows us to install new command-line programs (such as PHPUnit, or Phix) onto a computer for everyone to use.

What Is A Command-Line Program?

A command-line program (the ‘script’ file role supported by the PEAR installer) is a PHP script that your users run from inside Terminal (or Command on Windows). It allows you to put powerful tools in the hands of your users.

You can also run them as scheduled jobs via cron.

Where Do Command-Line Scripts Go Inside The Component’s Structure?

If we take a look at the phix component, you’ll find the command-line program itself in the src/bin/ folder:

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

In theory, you could put sub-folders under here, but this is not supported. If you look at phix’s actual code, you’ll see that the phix command-line program loads code that exists in the src/php/ folder of the component (and is installed into /usr/share/php/ when the PEAR installer installs the component). Your classes should go in src/php/ just like with any other component.

Where Do Command-Line Programs Get Installed?

When you use the PEAR installer to install your component:

$ pear install phix/phix

all of the files in your component’s src/bin/ folder gets installed into /usr/bin on your computer:

The command-line script src/bin/phix therefore ends up installed onto your computer as /usr/bin/phix.

The reason why the PEAR installer installs your PHP code under /usr/bin/ is because this folder is normally part of a user’s search path in Terminal. That allows users to run your command-line program simply by:

$ phix

without having to specify the full path to your command-line program.

I haven’t seen it personally, but there’s always the possibility that some Linux distros (and Mac OS X) will install command-line programs 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 bin_dir
PEAR executables directory            bin_dir          /usr/bin

How Do I Make My Command-Line Program Executable?

You’re probably used to running PHP scripts from the command line like this:

$ php ./my-script.php

but for command-line programs, you don’t want your users having to remember to run everything through the PHP interpreter each time.

UNIX (and UNIX-like operating systems such as Linux) have a long tradition of writing command-line programs using scripting languages. If you put a shebang (the characters #! – hash, pling) at the top of your script, you can tell your operating system how to execute your script.

#!/usr/bin/env php
<?php

# PHP code goes here ...

The line #!/usr/bin/env php tells your operating system to use the PHP CLI interpreter (wherever it is in your Terminal’s path) to run this script. Using /usr/bin/env in this way normally makes your script portable across different Linux distros.

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. To get started, I’m going to start with the obvious file role: the PHP code that a component is all about.

What Is PHP Code?

PHP code (the ‘php’ file role supported by the PEAR installer) is your component’s PHP code. This is the code that you want everyone to download and install and then include into their own PHP apps.

Where Does PHP Code Go Inside The Component’s Structure?

If we take a look at the CommandLineLib component, you’ll find all of the PHP code for this component under the src/php/ folder:

src/php/ is meant to be the top of a tree structure that any PSR0-compliant autoloader could load from:

  • The first level of folders under src/php/ is (by convention) the name of the vendor of the code. For CommandLineLib, the vendor is Phix_Project.
  • The second level of folder onwards can be whatever you need them to be. By convention, for our components at work, we are using the second level of folders to be the name of the component, in this case CommandLineLib. This works really well as you start to build up a larger number of components in your PEAR channel.
  • And eventually, you get down to the actual class definitions themselves.

The PHP class Phix_ProjectCommandLineLibCommandLineParser therefore ends up in the file src/php/Phix_Project/CommandLineLib/CommandLineParser.php.

Where Does PHP Code Get Installed?

When you use the PEAR installer to install your component:

$ pear install phix/CommandLineLib

all of the files in your component’s src/php/ folder gets installed into /usr/share/php on your computer:

The PHP class Phix_ProjectCommandLineLibCommandLineParser therefore ends up installed onto your computer as /usr/share/php/Phix_Project/CommandLineLib/CommandLineParser.php.

The reason why the PEAR installer installs your PHP code under /usr/share/php/ is because this folder is normally part of PHP’s include_path. That allows developers to include your code simply by doing:

[code lang=”php”]
include “Phix_Project/CommandLineLib/CommandLineParser.php”;
[/code]

or, better still, by using a PSR0-compliant autoloader, and then simply attempting to create a new instance of the class:

[code lang=”php”]
// load the PSR0-compliant autoloader
require_once “psr0.autoloader.php”;

// create a new command line parser
$parser = new Phix_ProjectCommandLineLibCommandLineParser();
[/code]

Some Linux distros (and Mac OS X) will use /usr/lib/php/ instead of /usr/share/php/. You can see where the PEAR installer will put these files on your computer by running:

$ sudo pear config-show | grep php_dir
PEAR directory                 php_dir          /usr/lib/php
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’ve just put out ComponentManager version 1.1.0, with the following (hopefully useful) changes:

Improvements To The php-library Skeleton

  • Once you’ve setup your metadata, phing build-vendor will build with no errors.

    I’ve added an empty src/php/dummy.php file, so that a valid empty PEAR-compatible package can be build and installed. You’ll want to remove this file when you start putting your own code into the component.

  • New build.property: project.channel. Set this to the name of your PEAR channel. Automatically picked up by package.xml now.
  • New build.property: pear.local. Set this to the folder where your local copy of your PEAR channel resides. (See my blog post for details about why you might want a local copy of your PEAR channel).
  • New build.xml target: publish-local. You can now do phing publish-local to use pirum add your component to your local copy of your PEAR channel.

Bug Fixes For The php-library Skeleton

  • Now tested on both Ubuntu and Fedora 14, especially for @phpcodemonkey.
  • Now excludes .DS_Store folders from the final component, for those using these tools on OS X.
  • Now excludes .svn folders from the final component.
  • Now excludes .empty files from the final component.

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 can upgrade the skeletons of your existing components by doing:

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

You will then want to edit build.properties, to set the new properties added in this release.

Any problems, let me know.

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.

In previous articles, I’ve introduced you to the component skeleton that phix creates for you when you run the phix php-library:init command. Our skeleton is designed to be extremely clean, so that it is very easy to automatically generate your PEAR-compatible component and its package.xml file, so that you don’t have to maintain it yourself (a process which would only end in tears).

At the heart of our skeleton, are the design constraints imposed by the PEAR installer, and that means the way it handles files differently depending on the file’s role.

What Are File Roles?

A file’s role is simply a way of telling the PEAR installer where you want the file installed. The PEAR installer supports the following file roles:

  • data – any data files that your component needs to read at run-time
  • doc – documentation about your component
  • php – your PHP code
  • script – any command-line scripts your component includes
  • test – your (hopefully, PHPUnit-based) tests
  • www – PHP code to be served by Apache

… plus a few more that are of no interest to authors of PHP components.

Where Do I Put Files For Each Role?

To make it extremely easy for the phing pear-package command to auto-generate your package.xml file, there’s a folder in our component skeleton for each type of file.

Here’s a handy summary showing you where to put your files inside your component, based on their role:

  • data – goes in the src/data/ folder
  • doc – goes in the src/doc/ folder
  • php – goes in the src/php/ folder
  • script – goes in the src/bin/ folder
  • test – goes in the src/tests/unit-tests/ folder
  • www – goes in the src/www/ folder

In the next few articles, I’m going to look at each of these file roles in turn, and show you in detail how the PEAR installer treats them, and how to work with them in your own components, starting with the php role.

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.

In my last article, I looked at how to publish your own PEAR channel, and why today that’s the best option for you and your projects. It takes about 10 minutes to publish your first PEAR channel, thanks to Fabien’s work on creating Pirum.

But what is it like to actually work with your own PEAR channel on a long-term basis? What are the things you could do to make things as easy as possible?

Tip 1: Local Copy Of Your PEAR Channel

Sometimes, you develop a component for the sake of it, but most of the time, you end up writing your components and the app that needs them side by side. This is what happened with phix et al, and behind the scenes here it is also what is happening with the components for my example app called sental.

When that happens, no matter how focused and skilled your unit testing is, you’ll want to release preview versions of your component, try them in your app, and then go back to your component and tweak things … all before you’re ready to share the next release of your component via your PEAR channel. This is what the ‘alpha’ and ‘beta’ stability flags in package.xml were originally designed for, but it’s more pragmatic to have a local, private copy of your PEAR channel on your dev box, and leave those stability flags well alone.

Here are the steps you need to follow to setup your own private copy of your PEAR channel on a Linux box:

  1. Setup Apache on your dev box with a virtual host to publish your PEAR channel, just like you have done on your public webserver.
  2. Use pirum to create your PEAR channel’s files on your dev box (or, even better, see Tip 3 below).
  3. Edit /etc/hosts to have the fully-qualified domain name for your PEAR channel point to IP address 127.0.0.1.

With this done, every time you use the PEAR installer on your dev box to install something from your PEAR channel, the PEAR installer will actually download your component from your private copy of your PEAR channel. You can keep putting new copies of your component onto this private copy of your PEAR channel until you’re satisfied with it, and it doesn’t matter that you’re not actually bumping the version number of your component each time you do so, because only you are affected.

And when you’re ready to send this new version out into the world, you just need to tag the release in source control, and then upload your private copy of your PEAR channel to your public webserver.

(Btw, if you do a lot development disconnected from the internet like I do, having a local copy of your PEAR channel is pretty much a must!)

Tip 2: Tag Your Releases

Once you’ve decided that your component is ready to share with everyone on your PEAR channel, that’s the time to tag your release in source control. It’s dead easy to do, and it gives you and anyone else who takes over maintenance of your code a record of what was in each release.

Here’s how to do it in git.

stuart:~/Devel/sental/repustateApi$ git tag -a -m 'Release 0.1.0' 0.1.0
stuart:~/Devel/sental/repustateApi$ git push --tags origin master

If you’re publishing on GitHub, you can then go to your component on there and forever more see your code for that release. Here’s the repustateApi component at version 0.1.0 on GitHub, as a real example of tagged code. An even better example is Sebastian Bergmann’s PHPUnit project, where at the time of writing there are 193 tags to see!

As an aside, we really should be digitally signing these tags, but that is a topic in its own right for a later blog post!

Tip 3: Publish Your PEAR Channel Via Source Control

It isn’t just the code for your components that can be tracked via source control; there is nothing stopping you from publishing your PEAR channel via source control too. pear.gradwell.com is our public PEAR channel, and we have a pear.gradwell.com repo up on GitHub for it.

This makes it extremely easy to publish new packages to our PEAR channel. On my dev box, I add a new release to source control like this:

stuart:/var/www/pear.gradwell.com$ git clone git@github.com:Gradwell/pear.gradwell.com.git
stuart:/var/www/pear.gradwell.com$ pirum add . ~/Devel/repustateApi/dist/repustateApi-0.1.0.tgz
stuart:/var/www/pear.gradwell.com$ git add -i
stuart:/var/www/pear.gradwell.com$ git commit -m 'Added repustateApi-0.1.0'
stuart:/var/www/pear.gradwell.com$ git push origin master

… and then I SSH into our public webserver, and simply do:

stuart:/var/www/pear.gradwell.com$ git pull

Job done 🙂

This is actually a very handy setup when you have more than one developer publishing packages. Each of your developers merges their new releases into source control, so that no-one trips over each other (very important in a distributed team), and everyone can clearly see who has published what.

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.

In the last article, I explained how to create a PEAR-compatible package from your component, and how to install the package both for local testing and for system-wide use on your own computer. One of the strengths of picking the PEAR installer for our components is that it’s a very easy way for others to download and consume our components.

We just need somewhere to publish them. We either need to find an existing PEAR channel to publish to, or we need to publish our own.

To Self-Publish Or Not

It’s worth taking a moment to consider whether you should publish your own PEAR channel or not.

At the time of writing, the components culture in the PHP community is at an embryonic stage of development. There are curated pockets here and there, but we have nothing yet that compares with both the traction and ubiquity of RubyForge or Perl’s CPAN.

There is the venerable PEAR project, which has given us the installer I’m using for the components skeleton featured in these blog posts, but its no-compete policy for packages means that you have to apply for permission to have your package carried by their channel.

There are other efforts around such as Pearhub and Pearfarm, but neither of them have really nailed the complete experience for both package publisher and package user at this time. If anyone wants to take up the challenge of providing our community with a modern, credible equivalent to RubyForge, I’d love to hear from you 🙂

This is why many of the tools you’ll hear talked about at PHP conferences (such as the QA tools that Sebastian talks regularly about) end up being self-published. Today, it’s simply easier to do.

How To Setup Your Own PEAR Channel

Self-publishing your PEAR channel is incredibly easy. All you need is some web-hosting space, and Fabien’s Pirum. Pirum is a very simple, very straight-forward tool that creates and updates all the files needed for your own PEAR channel. Best of all, these files are all static files, keeping things lean and mean.

To install Pirum, simply run these commands from the command-line:

pear channel-discover pear.pirum-project.org
pear install pirum/Pirum

This installs a command-line tool that you’ll use to create your PEAR channel.

Next, you need to configure Apache to serve your PEAR channel to the world. By convention, PEAR channels normally are http://pear.<project>.whatever or http://pear.<vendor>.whatever. The PEAR installer works best if your PEAR channel files are in the DocumentRoot of your website.

Let’s say that the DocumentRoot of your PEAR channel is going to be /var/www/pear.example.com. Once you’ve configured Apache to serve pear.example.from from /var/www/pear.example.com, you need to create a pirum.xml file to describe your PEAR channel. This is a very simple file that tells Pirum the essential information it needs to create your PEAR channel’s files.

mkdir /var/www/pear.example.com
cd /var/www/pear.example.com
vi pirum.xml

For pear.example.com, the pirum.xml file would look like this:

<?xml version="1.0" encoding="UTF-8" ?>
<server>
	<name>pear.example.com</name>
	<summary>Example PEAR channel</summary>
	<alias>Example</alias>
	<url>http://pear.example.com</url>
</server>

Now we need to tell pirum to build our PEAR channel files:

cd /var/www/pear.example.com
pirum build .

Congratulations – you now have your own PEAR channel. Remember to change ‘pear.example.com’ to be the actual name of your own PEAR channel, and you too can have your own PEAR channel up and running in about 10 minutes first time around.

Once you’ve built a PEAR-compatible package from your component, it’s one command in Pirum to publish that package on your PEAR channel.

Adding A Package To Your Own PEAR Channel

Let’s say I’m going to publish my RepustateApi package on the pear.example.com channel I created above. The full sequence of commands to create and publish the channel is:

stuart:~/Devel/repustateApi$ phing pear-package
stuart:~/Devel/repustateApi$ pirum add /var/www/pear.example.com dist/repustateAPI-0.1.0.tgz

It’s that straight forward 🙂

Now, in reality, you’re unlikely to be developing your PHP components on your public webserver. You’re more likely to be developing your PHP components on your local desktop or laptop (or on a shared development server), and then uploading the final results to your public webserver. This is how we work at Gradwell right now, and in the next blog post I’ll go through our actual workflow for publishing a new or updated component, showing you how we’re setup to both support multiple contributors and disconnected development.

5 comments »
Page 4 of 9« First...23456...Last »

This Month

November 2017
M T W T F S S
« Jul    
 12345
6789101112
13141516171819
20212223242526
27282930