Creating Composer Package Library

In this post, we will learn how to create a PHP library that can be easily integrated to any PHP application via Composer.

Posted by Darwin Biler on February 28, 2016

One of the main rants about old PHP applications is PHP developers tends to copy-paste snippets of codes from the web all over the place, w/o any sort of structure, testing process and dependency management. This makes every PHP applications become a Big Ball of Mud, accumulating more and more muds as it rolls by on another monkey coder that tries to implement changes as possible by cutting-corners and applying quick patches.

Don't be part of that problem. Encapsulate your codes in a reusable library!

This post aims to make your life, as a library author, as easy as possible, by guiding you on how to implement a new library with the least possible steps.

Create the project folder structure

Execute the following in your console (you need to have Composer installed first of course). The mylibrary in the command is the name of your library, so replace it with the actual name.

composer create-project buonzz/composer-library-template mylibrary

what is happening?

Not much, it just creates a new library under mylibrary folder. Let us take a look at the generated files.

  • src is where your codes will live in, each class will need to reside in its own file inside this folder.
  • tests each class that you write in src folder needs to be tested before it was even "included" into somewhere else. So basically we have tests classes there to test other classes.
  • .gitignore there are certain files that we don't want to publish in Git, so we just add them to this fle for them to "get ignored by git"
  • LICENSE terms of how much freedom other programmers is allowed to use this library.
  • README.md it is a mini documentation of the library, this is usually the "home page" of your repo if you published it in GitHub and Packagist.
  • composer.json is where the information about your library is stored, like package name, author and dependencies.
  • phpunit.xml It is a configuration file of PHPUnit, so that tests classes will be able to test the classes you've written.

This is the most basic strucure that you can start with.

Customize the generated files

You will see a sample class generated under src/YourClass.php. You will need to rename this with the actual classname. Remember that you should not put multiple classes in the same PHP file. So the classname you pick for this file should match the filename as well. If you need to write another class, create a new file.

Namespacing

It is a good practice that you namespace each of your classes, so your class wont clash to another classname when they are used by an application. Usually, the good namespace is your GitHub username. For example, in my case my GH username is Buonzz, so it makes sense that I have namespace like Buonzz\MyLibrary

In general, each class you make should live under VendorName\PackageName syntax. This should be the first line of every class in your library.

<?php 
namespace Buonzz\Template;

In the above example, the VendorName is Buonzz, and the package name is Template. You need to pick one of your own and make sure this is consistently placed in every PHP files in this library.

You need to also edit the composer.json file, to reflect these changes.

"name": "vendorname/packagename"

Then

 "psr-4": {
            "VendorName\\PackageName\\": "src/"
        }

The above will be the information used by packagist.org, to indentify the name of your package, and the second snippet allows autoloader to know exactly what namespace to find your classes.

Adjust the branding

Next, you need to add a small description of what this library is for, along with keywords to easily find this package in packagist.org. You also specify the author information with your name. This is all can be adjusted in composer.json as well

    "description": "this is my very own php package.",
    "keywords": ["my package", "composer", "package"],
    "license": "DBAD",
    "authors": [
        {
            "name": "Your Name",
            "email": "your email"
        }
    ]

After this, validate your composer.json file, to make sure you did not make any typo error when you made the adjustments by executing

composer validate

After this, you need to customize the README.md file included, it is basically a short documentation on what is the purpose, what is the requirements and how to use this library. You can find a more detailed documentation of how to make a README file in here.

Write the Test Class

There is a provider test class under tests folder. This is called "YourClassTest.php". The code provided is simply checking the corresponding class if there is any syntax error. Remember that each Class in src folder should have a test class associated with it. The test class name should be the same as the class it is testing plus "Test" string. So if you have a src/Utils.php class, you also need to have test/UtilsTest.php

We are using a library called PHPUnit, to facilitate this testing process. To install PHPUnit, you need to install it first

composer install

This will install phpunit in vendor/bin/phpunit

Now, edit the test class with your own namespace by replacing the Buonzz\Template namespaces with your own. After that, run the PHPUnit by executing it in console

vendor/bin/phpunit

It should return success, and you can continue this cycle of development until you had written all your classes and its corresponding test-classes. Unit-testing of its own is a very complex topic, so if you want to explore more about the idea, you can check the following links

You should design your library so that it can be tested on its own w/o hitting external dependencies ( databasses, API, classes/functions inside another CMS or library) as much as possible

Publish Your work

Before publishing your package, make sure to change the "type" field in composer.json file to "library". This is so that packagist.org will recognize your package as library.

Once you are done writing your classes and you had tested it fully. Time to publish your work!. You need to have an account to the following sites before you can publish your work:

  • GitHub.com
  • Packagist.org

Go on and signup an account if you don't have one yet. Once done create a new repo in your github account. The repo should be the same name as your library. After that, push the library to that repo by

git init
git remote add origin [email protected]:yourusername/yourlibraryname.git
git add --all
git commit -m "initial files"
git tag -a v1.0.0 -m "initial release"
git push -u origin master

After that, click the Settings tab of the repo. On the left sidebar, click Webhooks & Services. On the Services tab, click the Add Service Choose Packagist

You need to enter your username on packagist for this along with the token.

To get the token, go to your profile page and click the Show Token button to copy the token. Paste this token to GitHub.

Now you are ready to submit your package to packagist!

Go to https://packagist.org/packages/submit and paste the url of your Github repo. It might take a while, while packagist validate your package name and library. Once done, your package is now available in packagist!

To use your library, simply

composer init
composer require yourusername/yourpackagename

Then create an index.php file that will load the autoloader

require 'vendor/autoload.php';

All the classes inside your library is now ready to use!