#native_company# #native_desc#
#native_cta#

Creating Framework-Agnostic PHP Packages

By Voja Janjic
on August 20, 2015

One of the common problems with PHP used to be that if you chose to use a particular framework, you were able to use only the libraries and plugins that are made specifically for that PHP framework. It was difficult to switch the frameworks or to re-use the code between frameworks. However, PHP has experienced major changes recently. Composer, a package manager widely used by PHP developers, and latest generation frameworks, such as Laravel and Symfony, have enabled PHP developers to create framework-agnostic packages. Furthermore, Packagist has emerged as a central PHP package archive where you can browse for packages that are available through Composer. On top of that, Github has improved open source project collaboration, bug reporting, feature requests and other social aspects of code writing.

PHP Interoperability Standards

Before we start coding our first PHP package, let’s take a look at a few standards that will make your code cleaner and easier to read and understand. These standards are made by PHP FIG, a group of PHP developers. They have passed 6 standards so far:

   • PSR-0 – Autoloading standard, provides standard file, class and namespace convention

   • PSR-1 – Basic coding standard

   • PSR-2 – Coding style guide

   • PSR-3 – Logger interface

   • PSR-4 – Improved autoloading standard

   • PSR-7 – HTTP message interfaces

Although you don’t have to follow every line of these standards, it is a good idea to broadly apply the principles behind them. Also, pay attention to PSR-4 standard, as that one will be used to create a framework-agnostic PHP package.

PHP Package Structure

First, we will create a directory which will hold all the files. The directory name should be the same as the package name – in our case helloworld. That folder will contain two subdirectories – src and tests. All code should be located in src directory, while all unit tests should be put into tests directory.

Since the package will be available through Composer, we will need to create composer.json file inside helloworld directory. Composer.json provides information about the package, such as name, description, license, author, as well as the dependencies that the package will require. An example composer.json file would look like this:

{
    "name": "vojajanjic/Helloworld",
    "description": "My first framework-agnostic PHP package",
    "license": "MIT",
    "keywords": ["helloworld"],
    "authors": [
        {
            "name": "Voja Janjic",
            "email": "[email protected]"
        }
    ],
    "require": {},
    "require-dev": {
        "phpunit/phpunit": "4.0.*"
    },
    "autoload": {
        "psr-4": {
            "VojajanjicHelloworld": "src"
        }
    }
}

The require part defines the list of dependencies that your package will require. Require-dev defines the list of dependencies that are required for the development of the package. Autoload defines how the package should be autoloaded.

After creating the composer.json file, run the following command:

composer install

It will download the dependencies specified in composer.json file and put them into vendor directory.

The next file that needs to be created is .gitignore file, which defines the files which will not be included in our package’s git repository. In order to prevent duplicate code, we will not include the entire vendor directory, as well as the auto-generated composer.lock file. So, the .gitignore file would look like this:

/vendor
composer.lock

At this point, we can start writing our own code. Create a file named Helloworld.php inside the src directory. That file will contain the Helloworld class:

<?php namespace VojajanjicHelloworld;
 
class Helloworld {
 
  public function test()
  {
    return "Hello World!";
  }
 
}

Here is an example how to use this class inside a PHP framework:

<?php

// Autoloading file. This line is usually already executed by the framework
require_once "vendor/autoload.php";

// Create an instance of Helloworld class
$object = new VojajanjicHelloworldHelloworld();

// This should output "Hello World!"
echo $object->test();

After you have finished writing the code, it is a good practice to write unit tests for your package. Also, it is a good idea to create a readme.md documentation file, as that is the first file that will be shown when your project is opened on Github. Finally, you can push your package to Github and Packagist by running the following commands:

git remote add origin [email protected]:username/helloworld.git
git push -u origin master

To integrate Packagist with your Github account, login to your account, go to settings and then find Packagist under Webhooks & Services section.

Conclusion

You can do the whole process by yourself, for practice. However, it is a good idea to use a blank PHP package (League Skeleton, for example) in order to be more productive.