cult3

How to build a PHP package

Mar 12, 2014

Table of contents:

  1. The tools of Open Source
  2. PHP interoperability standards
  3. Package structure
  4. Namespacing
  5. Conclusion

For many years, PHP has struggled to keep up with other language options due to lack of interoperability of code and lack of a common interchangeable standard. For many years, if you chose to use a particular PHP framework, you were stuck using the entire codebase without the option to swap out the individual pieces.

However over the last couple of years, PHP has experienced a renaissance of sorts. The community has finally got behind Composer as the package manager of choice and we are seeing a lot of really great new packages that are framework agnostic. Furthermore, with excellent latest generation frameworks like Laravel and Symfony that are built on these principles, your choices as a PHP developer have never been greater.

Whilst I think PHP has still got a long way to go, it finally feels like things are on track.

Over the next couple of weeks I’m going to be walking you through the process of building framework agnostic PHP packages that meet my requirements of being high quality packages. This will not only cover how to create the package, but also some general programming concepts and design patterns to ensure the quality of your code is high.

In this post I will be covering general principles and the important things to understand when building a PHP package. In each of the following weeks I will cover a specific topic. By the end of this mini series we will have built a couple of real world PHP packages that can be used in isolation or together as part of a bigger application.

The tools of Open Source

There has never been a better time to write Open Source software as we now have the tools and systems in place to share and collaborate on code together. As a contributor to Open Source PHP software, you should become familiar with the following three tools.

Composer

As I mentioned above, Composer is the package manager that has been broadly adopted by the PHP community. Composer makes it incredibly easy to pull in third party packages into your project and keep those packages maintained as new updates are released.

If you have been following along with my “Building Cribbb” series you will know that I’m a big fan of Composer.

I’ve already covered getting started with Composer in a previous tutorial, so I won’t go over old ground again.

Packagist

Packagist is the central PHP package archive where you can browse for packages that are available through Composer.

I think one of the traits of a good developer is you try not to reinvent the wheel. The first place I look if I have a specific problem I need to solve is to go to Packagist to see if someone else has already solved it.

Once you have created your PHP package you can submit it to Packagist so other developers can find it and use it too.

Github

Github has been an amazing driver of Open Source software over the last couple of years. Github allows you to host your Open Source git repositories for free and provides many amazing collaboration tools such as issues, pull requests and wikis as well as a whole host of social tools that revolve around writing code together.

When you host your PHP package on Github you have all the tools you need to fix bugs, answer questions and allow other developers to contribute work to your package. It’s an amazing feeling when someone takes time out of their life to fix a bug or create a new feature on one of your Open Source projects.

PHP interoperability standards

In order to create little nuggets of code that can be swapped out and used interchangeably, it’s important that we all play by the same rules. Having standard ways of doing things means all packages will have the same expectations and so, as a developer, you can easily pull in a package and expect it to work within your project.

The PHP FIG is a group of developers that represent different projects and initiatives within the world of PHP. The group aims to agree standards for which PHP should be written to achieve interoperability.

The group has passed five standards since it’s inception in 2009. These are:

PSR-0 - Aims to provide a standard file, class and namespace convention to allow plug-and-play code. PSR-1 - Aims to ensure a high level of technical interoperability between shared PHP code. PSR-2 Provides a Coding Style Guide for projects looking to standardise their code. PSR-3 Describes a common interface for logging libraries. PSR-4 Defines a common way to autoload packages.

Whilst you don’t have to follow every line of these standards in order to make your package available through Composer, it’s usually a good idea to stick broadly to them. Every developer has their own preferences for how they want to write code, but following a predefined standard does make things a lot cleaner.

Each of the standards are pretty short and easy to consume, so have quick read through to familiarise yourself with what has already been agreed. You are more than likely already following most of the standards if you are already writing PHP in a commercial setting anyway.

Package structure

How you structure your package is the final important thing to get your head around. By following an agreed standard we not only ensure that things work technically, but also everyone will instantly know where to find what they are looking for when reading the package for the first time.

In order to illustrate the structure of a PHP package, let’s look at the Plates> package.

So as you can see we have a handful of files in the root of the directory. The most important of these files is the composer.json file which holds meta data about the package as well as any dependencies that might be required.

You will notice there are two directories, src and tests. The src directory is where we keep the actual source code of the package and the tests directory is where we keep all of the tests.

If you click through to the src you will find the code of the package. PSR-4 actually changed how packages should be structured. Previously you would of found a League file and then a Plates but now you know longer need to have those extra directories. However a lot of packages have not yet moved over to this new structure.

Namespacing

When you first start looking at PHP packages, it can seem a bit redundant to have all of these single directories. However this structure is very important for how these packages work together.

If you refer to PSR-0 you will see that we are required to use namespaces of Vendor\Namespace\File. As you can see from the Plates package, League is the Vendor name, and Plates is the namespace.

Why is this important? Well we need to use Namespaces to organise our code correctly and to prevent conflicts. Namespaces are a way to ensure we are picking the right class when two classes have the same name. For more on namespaces, take a look at my post What is namespacing?.

Conclusion

By working towards the same standards and using the same tools the PHP community is flourishing with a wealth of really great packages that can be used interchangeably within projects. This means when you face a particular problem, you can simply pull in a battle hardened package that has already been written and tested and instead get on with writing your implementation.

This is the first post in a mini series about creating packages for PHP. I’ll be covering all of the building blocks that go into building high quality, framework agnostic PHP packages.

Philip Brown

@philipbrown

© Yellow Flag Ltd 2024.