cult3

Creating a Laravel 4 package

Jun 24, 2013

Table of contents:

  1. The Workbench
  2. Package file structure
  3. Package Service Provider
  4. Package Class
  5. Register the Service Provider
  6. Creating a Facade
  7. Your package in action
  8. Conclusion

One of the best things about Laravel 4 is how it is built entirely around the idea of interoperability. For a long time, it was quite difficult to manage the dependencies of PHP projects. Copying and pasting code into projects was a nightmare, and keep things up-to-date was extremely difficult. Not many developers used PEAR and so you end up with each PHP project reinventing the wheel instead of using existing code from the community.

When choosing a PHP framework to work with you had to be fully committed to using only that framework because you couldn’t easily switch components out.

However with the rise in popularity of Composer (What is Composer?), PHP finally has a package manager that solves this problem.

Laravel 4 has been built from the ground up to work with Composer. Each of the components of the framework are actually individual dependencies that are brought together under one roof. This makes switching out components incredibly easy.

Laravel 4 also has built in tools for creating new packages as well as making it easy to leverage the beautiful facades implementation that allows you to create expressive syntax when working with your package.

In this tutorial I’m going to show you how to create your first PHP package using Laravel 4.

The Workbench

Laravel 4 makes creating new packages incredibly easy. In order for a package to work correctly, you need to set up a directory with the correct files and structure. This can be time consuming and so Laravel 4 can automatically generate these files for you using a single artisan command.

However, before you generate your new package, first you need to set up some configuration details. Open app/config/workbench.php and fill in your name and email. These details will be included in your package’s composer.json file.

Next we can generate the new package using the artisan command:

php artisan workbench vendor/package -resources

You need to replace the vendor and the package names with the names you want to use. Vendor is the name of your company, or organisation, or simply your name, and Package is the name of your package.

So for example, if I was creating a package called supyo I would run the following command:

php artisan workbench philipbrown/supyo -resources

The --resources flag tells artisan to create this package with some additional Laravel directories. If you are creating a package that can be used outside of Laravel, you can leave this off.

Package file structure

Now if you go into vendor/workbench you should see a new directory that contains your generated package.

Before you get started, remember to run composer install.

If you find yourself in a situation where you are getting a File not found error, but you are sure that the file is named correctly and you have the correct namespaces, its usually because composer isn’t aware of the file. To fix this you can simply run composer dump-autoload. This will regenerate the class maps of your package.

If you need to pull in other packages as dependencies, you simply add them to your composer.json file and run composer update like you would if you wanted to add a dependency to your main project.

Note: All of these commands should be run with your package directory, and not in the root of your project.

The file structure can seem a bit overwhelming at first, but you’ll begin to recognise it the more you start working with PHP packages.

The src directory is where you keep all your actual code for the package.

The tests directory is where you keep all your tests.

And the vendor directory is where all of your dependencies are stored.

You will notice there is also a composer.json. This is very important for making your package available on Packagist. This is where you require your dependencies so Composer can automatically pull them in.

Package Service Provider

Next if you drill down through the src directory, you should find a Service Provider file. Mine is:

/workbench/philipbrown/supyo/src/Philipbrown/Supyo/SupyoServiceProvider.php

You can think of the Service Provider file as kind of like this package’s individual bootstrap file. A bootstrap file is simply the file that sets everything up correctly during start up. Here we simply need to set a couple of things up so Laravel knows what to do with it.

Here is what your Service Provider should look like so far:

<?php namespace Philipbrown\Supyo;

use Illuminate\Support\ServiceProvider;

class SupyoServiceProvider extends ServiceProvider
{
    /**
     * Indicates if loading of the provider is deferred.
     *
     * @var bool
     */
    protected $defer = false;

    /**
     * Bootstrap the application events.
     *
     * @return void
     */
    public function boot()
    {
        $this->package("philipbrown/supyo");
    }

    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        //
    }

    /**
     * Get the services provided by the provider.
     *
     * @return array
     */
    public function provides()
    {
        return ["supyo"];
    }
}

Notice how I have already filled in the details for the boot() and provides() methods.

Now you need to register the Service Provider in Laravel’s config. Open app/config/app.php and add your ServiceProvider to the bottom of the array:

'providers' => array(
// —
'Philipbrown\Supyo\SupyoServiceProvider',
),

Package Class

Next we can create the main class of this package. In the same directory as the SupyoServiceProvider.php file create a new file called Supyo.php:

<?php namespace Philipbrown\Supyo;

class Supyo
{
    public static function greeting()
    {
        return "What up dawg";
    }
}

Notice how I set a namespace for this class.

Register the Service Provider

Next, back in the Service Provider, we need to register the new class with the Laravel’s IoC Container. I will probably fully explain how clever Laravel is and how the IoC container works in the future, but for now all you need to know is that you have to register your class so Laravel can resolve an instance of it.

To do that, we need to update the register method:

public function register()
{
    $this->app['supyo'] = $this->app->share(function($app) {
        return new Supyo;
    });
}

$this->app is just an array that holds all of the class instances. $this->app->share is a closure that will return an instance of your class. This means, when you try to use this package, it will be resolved using this instance from the IoC container.

Creating a Facade

Laravel uses a great syntax that makes writing code clean and elegant. Whilst on the surface, it seems like Laravel is just using a load of static methods, Laravel is actually resolving those classes out of it’s IoC container. If all of that went over your head, don’t worry, you don’t really have to understand what is going on. I will explore the in depths architecture and design patterns of Laravel in a future tutorial.

A facade allows you to use your class like this:

echo Supyo::greeting();

This is a facade because as you might already know, this is not how you would normally instantiate the class that we created earlier.

To create the facade, first create a new folder named Facades in your package directory. In this folder, create a new file called Supyo.php and copy the following code:

<?php namespace Philipbrown\Supyo\Facades;

use Illuminate\Support\Facades\Facade;

class Supyo extends Facade
{
    /**
     * Get the registered name of the component.
     *
     * @return string
     */
    protected static function getFacadeAccessor()
    {
        return "supyo";
    }
}

Next add the following to the register method in your Service Provider class:

$this->app->booting(function () {
    $loader = \Illuminate\Foundation\AliasLoader::getInstance();
    $loader->alias("Supyo", "Philipbrown\Supyo\Facades\Supyo");
});

This allows the facade to work without the developer having to add it to the Alias array in app/config/app.php. Props to Chris Fidao for this.

Your package in action

Now you are all set to see your package in action.

Open up your routes.php and copy the following:

Route::get("/test", function () {
    echo Supyo::greeting();
});

Fire up the server and hit the test url, you should see the greeting printed to the screen.

Conclusion

This was a broad overview of how to create Laravel 4 packages. We’ve touched upon a couple of important areas of how Laravel works, in particular how the IoC allows Laravel to have a great syntax whilst still being very testable.

Don’t worry if some of the concepts in this tutorial went over your head. This was a tutorial on just setting up a new Laravel package. In the future I will go into much more depth to explain some of the elegant design patterns of Laravel and how it has been written to promote ease of testing whilst still maintaining it’s expressive syntax.

This is a series of posts on building an entire Open Source application called Cribbb. All of the tutorials will be free to web, and all of the code is available on GitHub.

Philip Brown

@philipbrown

© Yellow Flag Ltd 2024.