Laravel 5.0 - Directory structure and namespace
Posted on September 12, 2014
Warning: This post is over a year old. I don't always update old posts with new information, so some of this information may be out of date.
One of the big reasons Laravel 4.3 got moved to 5.0 is because the directory structure can seem like a big shift in thinking.
I love it. The directory structure has been modified to now better reflect how a majority of Laravel developers either work or recommend working, and this will reduce some of the pain of comprehending "best practices", and it makes the entire task of understanding Laravel simpler.
What does it look like?
app Commands Console Events Handlers Commands Events Http Controllers Middleware Requests Providers Services bootstrap config database migrations seeds public package resources lang views storage cache logs meta sessions views work tests
app directory has been trimmed down--and also boosted a little. Where it used to be a more classic Rails/CodeIgniter-style directory that holds all of your application's logic and framework config and templates and persistence and everything else, it's now primarily trying to hold your application's logic (including the business "domain")--and it's loading it all as PSR-4 classes.
As a result, Laravel-specific configuration details are now in their own directory. Resources--language and views--are now in their own directory. Database-related information is now in its own directory.
Note: There is a Legacy Service Provider (see the docs here) that'll allow you to serve a 5.0+ app from a 4.2- directory structure, so upgrading older Laravel apps to 5.0 won't require changing to the new directory structure.
So, why is this actually an improvement?
For starters, we're separating our concerns. The app directory was previously a bit of a catchall for pretty much all code other than frontend code. Now, it contains the core logic of your app--fittingly--and some of the particular implementation details live elsewhere.
Additionally, it's been considered best practice for quite a while to have an "App" style top level namespace for your domain logic. Getting started on a new project, for many of us, was at the very least deleting the models directory, adding a namespace folder named after our app, and PSR-4 autoloading that namespace. Now that's a native part of the folder structure, and it just got a lot easier to namespace Controllers and other aspects of your more framework-related code.
Finally, a lot of the code that used to be in procedural files (filters, for example) is now moved to classes and Service Providers. This makes execution easier to predict, reduces the amount of procedural code, and encourages more userland (i.e. "in our code, not in the framework") usage of Service Providers.
It's a little too extreme to say that the code in your app directory should be framework independent; controllers, filters, commands, and service providers will extend Laravel classes, and all of your classes may inherit from or receive injections of Laravel classes. But, this change goes a long way to moving the primary logic of your applications into PSR-4 loaded classes that could theoretically exist independent of Laravel.
Where does ___ go?
If it's a class, or could be a class, it should go somewhere in
app/. If it's an Eloquent model, it should go somewhere in
app/. If it has to do with the traffic of your request through a web server (e.g. Controllers, FormRequests), it should go in
app/Http. If it has to do with CLI (command line interface) requests, it should go in
app/Console. If you would've put it in routes.php (but it isn't a route), or in start.php in the past, it should go into a Service Provider. And if it's a filter, it should now be its own class in
Other than that, it should be pretty clear.
How does the namespace work in code?
By default, every Laravel app has a "namespace" that represents the top-level namespace for the app's classes. Out of the box it defaults to "App", and it maps directly to the
app/ folder directly via PSR-4.
But you can easily rename the namespace with an artisan command that will also replace all instances of "App/" (in namespace declarations in Laravel classes) with your new namespace.
So if I was starting Confomo again, I'd create the new Laravel install, and then instantly run the artisan command to rename the namespace:
$ php artisan app:name Confomo
Now all of the default-included classes in the
/app directory are namespaced to Confomo; the PSR-4 autoloading statement in
composer.json is updated; and Laravel knows to look for its filters, controllers, etc. in that namespace.
The new app structure and the app namespacing in Laravel 5.0 are helping us, step by step, increase the overall quality, consistency, and flexibility of our code. I like it.
Did I miss anything? I'm @stauffermatt on Twitter.
Comments? I'm @stauffermatt on Twitter
Tags: laravel • laravel 5 • 5.0
(This is part of a series of posts on New Features in Laravel 5.0. )
Sep 10, 2014 | laravel, 5.0, laravel 5In creating FormRequest, Taylor separated out both an interface (ValidatesWhenResolved) and a trait (ValidatesWhenResolvedTra...
Sep 10, 2014 | laravel, 5.0, laravel 5Laravel 5.0 Laravel 5.0 is coming out in November, and there are a lot of features that have folks excited. The New Directory...
Sep 12, 2014 | laravel, laravel 5, 5.0One of the big reasons Laravel 4.3 got moved to 5.0 is because the directory structure can seem like a big shift in thinking....
Sep 20, 2014 | laravel, 5.0, laravel 5Performance optimization within our PHP code isn't always something at the forefront of our minds, but our backend code--espe...
Sep 28, 2014 | laravel, laravel 5, 5.0In Laravel 5, you can now use the same Filesystem class which previously simplified interactions with the local filesystem, a...
Sep 30, 2014 | laravel, 5.0, laravel 5Laravel 5.0 introduces the ability for the Container to resolve depencies injected into any methods that are resolved by the ...
Oct 9, 2014 | laravel, 5.0, laravel 5Note: Route Annotations were eventually removed from core, and separated to a package maintained by the Laravel Community. T...
Oct 10, 2014 | laravel, 5.0, laravel 5If you've been following along with my previous blog posts about Laravel 5.0, you may have noticed that route filters were fi...
Oct 10, 2014 | laravel, 5.0, laravel 5Note: Event Annotations were eventually removed from core, and separated to a package maintained by the Laravel Community. T...
Oct 16, 2014 | laravel, 5.0, laravel 5If you've followed my blog for a while, you've probably seen me struggle with Laravel's environment detection--especially reg...
Nov 20, 2014 | laravel, 5.0, laravel 5Eric Barnes has a longer write up on this, so I'll just keep it short: Laravel 5.0 is introducing a pretty incredible cron-st...
Jan 2, 2015 | laravel, 5.0, commands, laravel 5As you’ve probably read me mention on Twitter, I’ve paused on blogging new Laravel 5 features to try to give Taylor some ...
Jan 16, 2015 | laravel, laravel 5It's very simple to get started in a new Laravel 5 app: composer create-project laravel/laravel my-project-name-here dev-deve...
Jan 19, 2015 | laravel 5, laravelYou might be missing the "prettier" Whoops error handler from Laravel 4. If so, here's how to bring it back. Updat...
Jan 21, 2015 | laravel, events, 5.0, laravel 5If you haven't read it yet, go read the Laravel 5.0 - Commands & Handlers post. It'll give much-needed background for th...
Jan 26, 2015 | laravel, laravel 5Sometimes it can seem like a lot of work to create an event, create its handler, and bind the two. Create a command, create i...
Feb 1, 2015 | laravel, laravel 5When you wanted to customize your error pages—for example, showing a particular cat GIF when your users hit a 404—you’d...
Feb 14, 2015 | laravel 5, laravel, eloquentI had completely forgotten to finish my Laravel 5.0 blog posts, but I saw a great quick introduction to attribute casting at ...