Jun 24, 2013
Table of contents:
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.
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.
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.
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',
),
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.
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.
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.
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.
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.