Laravel 4 Application Setup: App library, Autoloading, Binding
I like to create my own library for any application. Similarly, I like keeping the "models" directory clean - I only add Laravel classes (Usually Eloquent instances) inside of the "model" folder.
An application-specific library works well for code which isn't generic enough to warrant its own composer package, and also isn't a direct extension of any Laravel class. An example is business logic code, such as calculations specific to an application.
(The following assumes a clean install of Laravel.)
How do I setup my own library?
I accomplish this by creating a directly inside of the app folder called 'lib'. Then I choose a namespace for my application code - usually whatever I call my application.Let's start coding project Acme. Here's a directory structure I'd create.
Acme
app
lib
Acme
commands
config
…etc…
filters.php
routes.php
A sample class that may go in our Acme library is an Anvil line of products.
// app/lib/Acme/Product/Anvil/AnvilInterface.php
<?php namespace Acme\Product\Anvil;
interface AnvilInterface {
public function drop();
}
// app/lib/Acme/Product/Anvil/AnvilHeavy.php
<?php namespace Acme\Product\Anvil;
class AnvilHeavy implements AnvilInterface {
public function drop()
{
return "ouch!";
}
}
Here's what our files look like:
Acme
app
lib
Acme
Product
Anvil
AnvilInterface.php
AnvilHeavy.php
commands
config
…etc…
filters.php
routes.php
.
Autoloading
We now have a home for Acme product library. Let's autoload those libraries. To accomplish this, I edit composer.json
, and add to the "autoload" section. Note the addition of the psr-0 section, with the Acme library.
{
"require": {
"laravel/framework": "4.0.*"
},
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/models",
"app/database/migrations",
"app/tests/TestCase.php"
],
"psr-0": {
"Acme": "app/lib"
}
},
"minimum-stability": "dev"
}
After this is saved, you can run $ php composer.phar dump-autoload;, and Laravel will know how to load those classes. Let's try it out. Edit your routes.php file.
// routes.php
Route::get('/', function()
{
$anvil = new Acme\Product\AnvilHeavy;
print_r($anvil);
return View::make('hello');
});
Run this in your browser. You should see a print out of the AnvilHeavy object.
Binding
As you may know, Laravel's use of IoC containers makes for a powerful tool. This adds to the [maintainability and testability](http://fideloper.com/post/39306821065/testable-maintainable-di-containers) of an application.To bind our Anvil object (add to a container), we can use:
App::bind('Anvil', function()
{
return new Acme\Product\AnvilHeavy;
});
Later in our application, we can use resolve our AnvilHeavy object:
App::make('Anvil');
What have we learned?
At this point, we have done a few things:- Created a library we can use to add business logic.
- Setup autoloading to our library.
- Creating a container for our AnvilHeavy product.
Note that I haven't done anything to show the power of containers. This container binding is a contrived example, as the point I want to make here is how to setup your own application-specific library.