There are countless PHP packages out there that have been shared by their creators (just take a look at Packagist). Chances are that you'll find what you are looking for. But what if you want to add your own package to the community?
This is where Composer comes in handy.
Composer is a dependency manager, a little like NPM (Node Package Manager) for PHP. As mentioned above, a dependency is a pre-built library or tool that you can just plug into your project without much effort.
Composer manages these dependencies, or packages, on a project-by-project basis: you just need to tell it what packages you want to use and in a few simple commands you can install, update or remove them. Sounds ideal, right?
Find out how to download, install and start using Composer here.
Building your own package
In this post, I'll be using the simple example of a string manipulation library, which I've named Bungee (because flexible strings and all that ... ).
It's currently the beginnings of a side project (a very early work in progress) that I've been working on to refresh my skills in test-driven development, object-oriented PHP and Composer. Various examples of string manipulation libraries already exist as Composer packages - including the string library in Laravel's illuminate/support package - but they are finite and I often find myself with string formatting needs that fall outside their abilities! If you are going to write a Composer package, you may as well write one to scratch your own itch in the first instance.
The first thing you need to do is create a project directory. You'll want to version manage the project using Git and include details of how to install and use it in a README.
This is a very important step in the process as it's crucial to let your users know how your package works and not assume that they'll understand it without clear instruction. Here's my Bungee repo, complete with a wiki page for the methods I've created so far.
Create a composer.json file
Next, add a composer.json file in the project root by running
This will guide you through some initial steps including the naming of the package, which needs to be done in the 'vendor/package-name' format.
Bungee contains some dependencies so I need to require these by running
composer require <name-of-package>
This adds a /vendor folder to the project, which I want to include in my .gitignore file. Incidentally, this is how other users will install Bungee when it's published.
Following the above steps creates a composer.lock file, which records the specific versions installed and can be committed to version control to ensure that everyone using the package is on the same page (it can also be updated at a later date). This is obviously handy if you want to share the package across a dev team.
In Bungee, the dependencies I've included are the phpunit/phpunit package for test-driven development and the above-mentioned illuminate/support package, which will be useful for some string formatting - again, no need to reinvent the wheel.
Autoloading
Bungee uses object-oriented PHP, currently with a single class (which I've called Cord) with relevant string manipulation methods and variables scoped to it. Any application that then installs and uses Bungee will be able to call on this class and use the functionality provided by its methods.
The next step is to set up autoloading of this class (and any others that I add in the future) so that it doesn't need to be manually required at the top of all the PHP files that want to use it, which might be OK for a very small simple project, but would soon become tedious in a more complex application.
The autoloader needs to be able to find the files so put all your classes into a /src folder at the root of the project (it doesn't matter what you call this folder). As Bungee is object-oriented I'll keep track of directory structure using namespacing (here the namespace is 'Bungee') and use the PSR-4 method for autoloading.
Add the following to the composer.json file to tell the autoloader where to find the relevant files associated with the namespace:
Once you've added this, you can run
My Cord class is now ready to use.
Add the functionality of the package
You can now add the required functionality to your package.
Bungee is a simple, single class with (at the time of writing) a handful of methods that can be passed a string and other relevant information for formatting. It has been built using test-driven development - evidence of which can be seen in /tests/CordTest.php. You can also see how those methods are being called in the CordTest.php file - by instantiating a new Cord object to access the methods.
Once the package tests are all green and everything is working as it should then you are ready to share it with the world.
Publishing the package
The first step to publishing your Composer package is to commit your finished project and add it to Github.
Go to Packagist and sign in using your Github account. Once logged in you can submit a new package from the site menu.
Here you can add the URL to your Github repo and hit Submit. If this is the first time you have submitted a package, there will be an error concerning auto-updates. Just follow the instructions to give Packagist all the necessary permissions to Github Hooks and then go back and refresh your package submission.
Success! You've now got a package published on Packagist! All of the detailed information on how to install and use the package (i.e. the README file) will now appear at the bottom of the package entry on Packagist.
Updating the package
It's easy and quick to update your package and tag new releases.
Simply commit any new changes to your Github repository, click on the tags icon and Create a new release.
On the following screen you can choose the branch or specific commit that contains the update and tag it with a version number - initially you might want this to read something like v0.1.0 (see more about version numbers below).
The new version will now automatically appear on the Packagist page.
Version Numbering
It's important to note that if your package is so good that other people are actually using it, you need to be mindful of the updates and releases you put out there.
You don't want to break your users' code without giving them fair warning: this would be the difference between a patch/minor release (that should just add fixes or features that won't affect the current functionality) and a major release where your users will need to be warned that their existing code will be broken.
Generally, any version below v1.0 should be considered in its infancy and subject to change - a work in progress. Once you make any major changes you can bump it up to v1.0 and beyond. From this point onwards, your package is going to be more fully-fledged and well-maintained than its previous iterations.
Installing your package
You (and anyone else, for that matter) can now install your package into any other PHP project using Composer.
Welcome to the Open Source community!