After creating an API with Laravel 5 about a month ago, I was really liking the new directory structure and some of the features that were available. Today, I tried to replicate this magic and was having issues getting a stable version of Laravel 5 (which is to be expected to a degree since Taylor is still deciding some of the bootstrapping process). Then it hit me.
I can make Laravel 4 act a lot like Laravel 5!
Most of what I liked was the structure and use of service providers to boot things. With the development process that we've created with our team, some of the new features like Annotations, Elixer, and Request Validations aren't on our list to adopt adopt. So, after a bit of scratching my head, I was able to come up with a way to set up Laravel 4 to work similar to Laravel 5 (and hopefully make converting to Laravel 5 REALLY easy).
src
Folder
The first thing that I do is create a src
folder for my application code.
Then I put in some basic folders (somewhat inpired by the namespaces included in the bootstrap project for Laravel 5).
src/
|-Http/
| |-Controllers
| |-Requests
| |-Responders
|-Models/
|-Providers/
Strip out app
From the app
directory, I delete the folders for controllers
, commands
, models
, and tests
.
And, I delete the routes.php
and filters.php
files.
Then, I move the database
, and storage
folders up to the root level of my project.
Then there's some updating to do in the app/start/global
file.
I go and remove commands
, controllers
, and models
from the class loader, and I update the app_path().'/database/seeds'
to base_path('/database/seeds')
.
I then need to remove and update the autoloader in my composer.json
file to look like this:
"classmap": [
"database/migrations",
"database/seeds"
],
resources
Next, I move the app/views
directory to resources/templates
(I prefer to call these templates since I refer to the objects that perform the actual rendering views).
To make this work in the framework, I then go to app/config/view
and update the paths
to array(base_path('resources/templates'))
.
Autoloading with PSR-4
Now, I go and update the composer.json
file to autoload the src/
directory to my application/vendor namespace.
Bootstrap Provider
In order to make my src
directory as easy as possible to drop into any project, I create a single service provider called BootstrapServiceProvider
in my src/Providers
folder.
It then looks like the following:
class BootstrapServiceProvider extends ServiceProvider
{
protected $providers = [
];
public function register()
{
foreach ($this->providers as $provider) {
$this->app->register($provider);
}
}
}
Now in app/config/app.php
I just need to refer to this single provider.
And when I'm building my application itself, any new service provider that I want to load within my own application namespace just get's thrown into the providers
array in my BootstrapServiceProvider
.
Routes Provider
I then can create a routes provider that looks a bit like this:
class RoutesServiceProvider extends ServiceProvider
{
protected $namespace = 'Acme\\Http\\Controllers';
public function register()
{
}
public function boot()
{
$router = $this->app['router'];
$router->group(['namespace' => $this->namespace], function($router) {
require __DIR__.'/../Http/routes.php';
});
}
}
And now in my src/Http/routes.php
file, I can use the $router
variable to declare routes rather than using the Route
facade.
Build from there
Right now, that's about the needs for my application to make it structured like Laravel 5 and pull out some of the weight that was in the original app
directory.
As I need them, I create more service providers to alias interfaces, register events, register class based filters, and more.