Share a PHP package with Composer and Packagist

Hi there! In this quick tutorial we will see how to create a package for your PHP class/library with composer and publish it on packagist.org.

You probably are already using composer to manage dependencies in your projects and search for packages to speed up your development.

And guess what… creating your packages and giving back to the PHP community is as easy as requiring them!

Before we start…

(Skip this part if you already have composer installed and you project code on a version control system)

Installing composer

You will need composer installed on your system to create and test your packages so, if you don’t have it already, let’s go ahead and install it.

I recommend you install composer globally so then you can access it in any directory by just typing composer:

curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer

# After it finishes, test it!
composer --version

Although, if you are on windows or just want a to install composer locally for your project, you can check their quick start guide.

Puting your project in a VCS (We will use Github)

To submit your package to packagist.org you will need to provide a public repository URL (the repository type can either be Git, Svn or Mercurial).

The most widely used public repository website in open source projects is Github. To create a repository there check my other article about that topic.

Step 1: Creating a composer.json file

The first thing you need to do is create a composer.json file in the root of your project. To do that you can use composer init command and fill out your package information, in a step by step manner:

composer_init

Or use a composer.json file from other package as reference and change it according to your package.

// composer.json file from my rollbackpt/url-extractor package

{
    "name": "rollbackpt/url-extractor",
    "description": "PHP Class to extract images and meta data information from URLs",
    "type": "library",
    "keywords": ["url","metatags", "metadata"],
    "homepage": "http://urlextractor.joaoperibeiro.com/",
    "license": "MIT",
    "authors": [
        {
            "name": "Joao Ribeiro",
            "email": "[email protected]",
            "homepage": "http://joaoperibeiro.com",
            "role": "Developer"
        }
    ],
    "require": {
        "ext-curl": "*"
    },
    "autoload": {
        "psr-4": {
            "rollbackpt\\UrlExtractor\\": "src/UrlExtractor/"
        }
    }
}

Note that the first part of the file until the “authors” is pretty straightforward. Just notice that the package naming convention is “your-vendor-name/package-name”.

In the “require” section you can specify other packages that your code requires to run. For instance, let’s suppose that your package user a yaml file to store some options and you use the symfony/yaml package to handle the file creation. In that case, all you need to do is add it to the “require” section and it will come along automatically when the user requires your package without you having to copy it yourself to your project and worrying about updating it when symfony releases a new version.

The “require-dev” section works in a similar way, with the difference that those packages will not be required when used in production.

"require": {
    "php": ">=5.3.0",
    "ext-curl": "*",
    "another-vendor/package": "1.*"
}

// You can also manage requirements that are only for development

"require-dev": {
   "phpunit/phpunit": "5.0.*"
}

You can also use “require” to specify system requirements like minimum PHP version or extensions (curl / imagick / any-other-extension).

If you’re having trouble finding out the minimum version and the extensions required for your code to run, check out php-compat-info.

The “autoload” section uses the psr-4 specification and it reflects your namespacing and folder structure so that your classes can be correctly autoloaded.

(Check the example below)

urlextractor_folders

There are a few other parameters that you can use in your file and you can check them in the composer schema documentation. Also, the packagist about page gives you good references in terms of naming conventions and version managing.

Step 2: Testing your PHP package

To test your composer.json file just run the following command to install your package:

composer install

If everything was ok, the output should look something like this:

composer_install

And then let’s create a test.php file to include your package through composer autoloader and test if everything went OK.

<?php

// Require composer autoload
require __DIR__ . "/vendor/autoload.php";

// Alias you class for easy usage
use yourclass\namespace\ClassName as ClassName;

// Instantiate your class
$var = new ClassName();

// Call a class method
$var->doSomething();

Now, you can test it by running your code on the command line:

php -f test.php

 

Step 3: Publishing your PHP package

This is, probably, the easiest step of all. Packagist make it really simple to submit packages! After creating your account, just go to https://packagist.org/packages/submit and enter your repository URL.

(Check the example below)

packagist_submit

Step 4: Setting up Auto Updating

In you package page you will probably see a warning saying that your package is not being auto updated. This happens because packagist recommends that you create a Webhook that auto updates your package every time you push something to the repository. This way, the other developers will always be downloading the last version of your package.

To accomplish that, go to your Github repository and click on Settings (left sidebar) -> Webhooks & services (right sidebar) -> Add service and the search for “Packagist”.

(Check the example below)

github_webhook

This will take you to a page where you just need to fill the following information and click “Add Service”.

User: Your packagist username

Token: Your API token. Check him here.

Domain: https://packagist.org

And voilà, you have configured your Webhook on Github.

Step 5: Requiring it from Packagist

After your package have been submitted to packagist, you can check if it is already available by typing the following command on your terminal (outside your project folder):

composer show your/newpackage

The output should look something like this:composer_show

Still outside your project folder, you can require it and test it by typing:

composer require vendor-name/package-name

And then using the same code example we used in step 2.