Skip to content

Jesse's Software Engineering Blog

Jun 04

Jesse

Create PHP Composer Package

Composer is an important tool in PHP development for dependency management. It allows for applications to easily use and share libraries while maintaining version control. This is a simple tutorial on how to make packages which can be shared with and used by other developers. The tutorial follows a packge I created.

Folder Structure

Typically the source code for a package will be placed in a src/ directory in the project root, followed by the various components for that package. There are different ways to organize packages and I recommend taking a look at some popular PHP packages such as Monolog or Guzzle to see how they are organized.

Namespaces usually start with the components. So for a directory structure of src/InfluxDB the namespace would be InfluxDB for files in the root InfluxDB directory.

Composer File

Once the directory structure is created and the files are written a Composer file will need to be made to identify the code as a package and to set up the namespacing and autoloading. The Composer file is simply a JSON file and can be made by copying another or by using the following command and going through the prompts

composer init

Here’s a complete overview of the different values that can be placed into a composer file. I generally keep mine simple. One import thing to notice is the autoloading

"autoload": {
    "psr-4": {"InfluxDB\\": "src/InfluxDB"}
}

This strategy allows for the namespacing to begin at the component level (child directories of src). After the composer.json file has been created the autoload file can be created and the classes should be accessible

composer install
require_once __DIR__ . "/vendor/autoload.php"; 

use InfluxDB;

$udp = new InfluxDB\Adapter(...);

Packagist

Once the package is ready to be used it needs to be registered with Packagist. Packagist is the composer repository for managing all the composer packages. Before the package can be registered it needs to be in source control such i.e. Github. Typically the naming convention for a package is <github-account-name>/<package-name>.

After creating a Packagist account and pushing code to Github simply submit the Github URL to Packagist i.e. https://github.com/jessecascio/querypro-php

Now try and pull the package from a different project via composer

{
    "require": {
        "jessecascio/influxdb":"dev-master"
    }
}
composer install

The newly created package will be available in the vendor directory and accessible via the code

require_once __DIR__ . "/vendor/autoload.php"; 

use InfluxDB;

$udp = new InfluxDB\Adapter(...);

Packagist Hooks

A convenient feature Packagist offers is the ability to set up hooks which will automatically update the package whenever a push occurs to the Github repo. The following is instructions from the Packagist website

Enabling the Packagist service hook ensures that your package will always be updated instantly when you push to GitHub. To do so you can go to your GitHub repository, click the “Settings” button, then “Webhooks & Services”. Add a “Packagist” service, and configure it with your API token, plus your Packagist username. Check the “Active” box and submit the form. You can then hit the “Test Service” button to trigger it and check if Packagist removes the warning about the package not being auto-updated.

NOTE: The packagist token can be found in your Packagist profile.

Versioning

While versioning can be done via the composer file Packagist recommends using tags instead to manage package versions. When the versioning is absent from the composer file, Packagist will fall back on the repository tags. By default the repository has no tags and thus defaults to the version of “dev-master”. I typically reserve the dev-master tag as the version which is currently under development, and when milestones, or stable releases, are achieved a tag is added to allow access to that version. Tags are similar to branches except that the code in a tag won’t change, it’s like a snapshot of the current code state.

For example my project was recently released and is in a working state. I want to continue to work on the code in dev-master but I want users to be able to access the working code. I make a tag for the working version.

To see tags

git tag

To create a new annotated tag

git tag -a 0.1.0 -m 'release version'
git push origin 0.1.0

And if you need to delete a tag

git tag -d 0.1.0
git push origin :refs/tags/0.1.0

After the tag has been created it will be visible in Github under the branches/tags drop down. Also when looking at the project Packagist page the new tag will be displayed as a different version. To get that version via composer simply update the composer file

{
    "require": {
        "jessecascio/influxdb":"0.1.0"
    }
}

This allows developers the flexibility to use which ever version they want and to update versions when they are ready simply by updating the version number that is referenced in the composer file.

Blog Powered By Wordpress