Matok's PHP Blog

Building reusable library with Composer

article image

I'm building BB Code Parser library which will be publish on GitHub soon. On this little project I will write series of articles how to make reusable PHP code like a boss.

What is library?

Library is collection of classes and/or functions that provide concepts to solve some shit. Main feature of library is reusable behavior. You can use it in as many project as you want. It's my definition so you likely find other/better definition on the web. Good example of library in PHP world in swift mailer that is library for sending an emails or Gregwar\Image that is library for resize images and do some other manipulations with them.

Init composer.json

I presume you have composer installed on machine. Open console, navigate to some nice directory where we put our library code. Just type in your console: composer init
Answer to composer prompts and you should end like this where you can everything confirm by typing yes.
{
    "name": "matok/bbcode-parser",
    "description": "BB Code Parser: Turns BB Code to any format you like.",
    "type": "library",
    "license": "MIT",
    "authors": [
        {
            "name": "Matej Kuna",
            "email": "mat.kuna@gmail.com"
        }
    ],
    "require": {}
}

Do you confirm generation [yes]? 

Fill it by your way. If you don't know anything just hit return. Most import is name and it has format vendor/name. There can be many parsers, but only one and best one from matok rule them all. Emm.. pardon me. After confirm generation you should have this file in directory:

$ ls -l
total 1
-rw-r--r-- 1 Matej Kuna 197121 242 Jun 29 20:23 composer.json

Define requirements and autoloading

I make two more directories and now it looks like:
$ ls
composer.json  library/  tests/

I put source code to library directory and unit tests to tests directory. Now I open composer.json in editor and add some more information, my whole file now looks like this:

{
    "name": "matok/bbcode-parser",
    "description": "BB Code Parser: Turn BB code to any format you like.",
    "homepage": "http://matok.me.uk",
    "keywords": ["bbcode", "phpbb", "bb code", "parser", "html converter"],
    "type": "library",
    "license": "MIT",
    "authors": [
        {
            "name": "Matok",
            "email": "mat.kuna@gmail.com"
        }
    ],
    "autoload": {
        "psr-4": {
            "Matok\\BBCode\\": "library/"
        }
    },
    "require": {
        "php": ">=7.0.0"
    },
    "require-dev": {
        "phpunit/phpunit": "dev-master"
    },
    "autoload-dev": {
        "psr-4": {
            "Matok\\BBCode\\Tests\\": "tests/"
        }
    }
}
This reflects directories I mentioned. I want use PHP 7 (I use features from this version), therefore require section contains minimal version of PHP. During development I am using unit test so phpunit/phpunit has place in require-dev section.

Last configuration I want to setup is PSR4 autoloading which means all files placed directly in library/ directory has namespace Matok\BBCode. To be sure what I am saying:

$ ls
Converter/  Exception/  Parser.php  Token/

$ head -7 Parser.php
<?php

namespace Matok\BBCode;

class Parser 
{
  private $text;

Working with you library

Everything is configured now. To check that config is correct type in console composer install, output:

$ composer install
Loading composer repositories with package information
Updating dependencies (including require-dev)
Nothing to install or update
Writing lock file
Generating autoload files

New files should be here

$ ls
composer.json  composer.lock  library/  tests/  vendor/

Important file is vendor/composer/autoload_psr4.php because it holds mapping between namespace and directory

$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);

return array(
    'Matok\\BBCode\\Tests\\' => array($baseDir . '/tests'),
    'Matok\\BBCode\\' => array($baseDir . '/library'),
);

In situation you need to change directory or add new directory in composer.json you must do composer install again or maybe a little faster way is composer dump-autoload

Epilogue

When everything is properly set up I can write whole library logic and also unit tests to its functionality. Unit test result looks like this:

$ phpunit
PHPUnit 6.0.10 by Sebastian Bergmann and contributors.

................................................................. 65 / 70 ( 92%)
.....                                                             70 / 70 (100%)

Time: 644 ms, Memory: 12.00MB

OK (70 tests, 70 assertions)

Well, library is written & tested. I intentionally omit GIT or any type of versioning system, but I presume we are using for the whole time.


If you like this article then mark it as helpful to let others know it's worth to read. Otherwise leave me a feedback/comment and we can talk about it.

I'm foreigner. Where I live my friends call me Maťok.


Comments - Coming Soon