These conventions follow the style defined by PSR-12, the successor of PSR-2 (which keeps evolving today as PER Coding Style).
I hope this becomes the page you come back to whenever you’re not sure what to call something.
The basics
Before we start, a quick refresher on the styles we use to name things.
Naming styles
Programming has plenty of styles for getting rid of the spaces ( ) between words when naming variables, functions, classes, URLs and a long list of etc. These are some of the most common ones:
camelCase
This style removes the spaces and capitalizes the first letter of each following word. Note that the very first letter is always lowercase. The name comes from the humps of a camel /\/\. Examples:
thisIsFineThisIsNotRightneither_is_thisPascalCase
Very similar to the previous one, except that here the first letter is uppercase too. It’s named after the Pascal programming language. Examples:
ThisIsFinenotAnymoreeven_less_thissnake_case
Here the spaces become underscores (_) and everything is written in lowercase. As the name suggests, it looks like a snake slithering along the ground. Examples:
this_is_finethisIsNotThisEvenLessdont-get-me-started-on-this-onekebab-case
Same idea as the previous one (snake_case), with the only difference that it uses hyphens (-) instead of underscores. The words end up lined up on a skewer, hence the name (kebab). Examples:
finally-my-turnThisIsNotRightthisEvenLesslooks_similar_but_nopeSo, to sum up:
- PascalCase
- camelCase
- snake_case
- kebab-case
These aren’t the only styles out there, I’m sure there are a bunch more, but they’re the ones we need today. Now, on to the good stuff.
Laravel conventions
Let’s group the naming rules by the kind of thing being named. One general note first: the whole framework is written in English, so that’s the language you should use to name your stuff too. Yes, even if your team speaks Spanish.
Controllers
Controller names are derived from the (singular) model name, plus the suffix Controller. They use PascalCase. Some examples:
class UserControllerclass OrderDetailControllerclass UsersControllerclass customerControllerclass DetalleDeFacturaControllerclass borrowed-book-controllerFunctions
Functions are named in camelCase. Some examples:
public function getUser()public function isAdmin()public function orderDetails()public function ThisIsABadExample()public function this_is_also_incorrect()Models
A model takes the singular name of the entity, always in PascalCase. Some examples:
class Userclass OrderDetailclass Usersclass customerclass DetalleDeFacturaclass borrowed-bookModel properties
Attributes, both the ones coming from the database and the computed ones, are named in snake_case:
$user->name$order->created_at$invoice->createdAt$book->LaunchDateRelationships
Relationships follow the same rules as functions. On top of that, their names go in singular or plural depending on the kind of relationship.
hasMany, belongsToMany and morphMany relationships go in plural, since they obviously deal with a collection of things:
$continent->countries()$book->authors()$spider->leg()$continent->country()hasOne, belongsTo and morphTo relationships go in singular, since they deal with a single instance of the related model:
$phone->owner()$room->house()$house->districts()$line->files()Model methods
Every other method on the model follows the same rules as any regular function: camelCase. That includes accessors and mutators, query scopes and so on.
Since Laravel 9, an accessor or mutator is a single method that returns an Attribute and is named after the attribute, but in camelCase. The attribute itself stays in snake_case:
protected function firstName(): Attribute{ return Attribute::make( get: fn (string $value) => ucfirst($value), );}
$user->first_name;Same story with scopes: the classic scopeActive() or, since Laravel 12, active() with the #[Scope] attribute. Either way you call it as User::active().
Tests
Test methods start with test, and the rest of the name describes what’s being tested. When I first wrote this, the usual style was camelCase (testGetUserOrderHistory()), but since Laravel 8 the framework’s own stubs use snake_case, so that’s the convention today. PHPUnit runs both, as long as the method starts with test. Examples:
public function test_get_user_order_history()public function test_create_and_assign_roles_to_a_user()public function getUserOrderHistory()And if you use Pest, the problem goes away: the name is just a string, as in it('returns the user order history').
Routes
Nouns in routes go in plural, using kebab-case. Examples:
/customers/23/orders/order-details/7/user/15/orderDetails/7Tables
Entity tables
Tables take the plural English name of the entity, this time in snake_case. Some examples:
usersorder_detailsPaymentinvoicelibrosPivot tables
The name of a pivot table (the one behind a many-to-many relationship) is made of the singular names of the related entities, in alphabetical order, using snake_case. Watch the order: it’s permission_user, not user_permission, because p comes before u. Some examples:
permission_usercategory_postuser_permissionUserPermissionpost_categoryColumns
Columns are named in snake_case. Examples:
idcreated_atphone_numbercreatedAtPhoneNumberPrimary and foreign keys
Unless you say otherwise, Laravel assumes the primary key of a table is id.
Foreign keys take the singular name of the entity plus the suffix _id. Examples:
post_iduser_idmobile_phone_iduserIdPostIdVariables
Variables should be descriptive: plural when they hold a collection, singular when they hold a single item. They use camelCase. Some examples:
$admins = User::isAdmin()->get();$activeUser = User::active()->first();$room = Room::all();$invoices = Order::find(1)->invoice;Views
Blade views are named in kebab-case and end in .blade.php. Examples:
footer.blade.phpactive-user.blade.phpcreate-admin.blade.phpactive_user.blade.phpcreateAdmin.blade.phpWrapping up
These are the recommendations and styles that Laravel and most of its community use to name things. You may agree or not, and that’s fine: at the end of the day they’re recommendations. For instance, I’ve always preferred snake_case for my test names because I find them easier to read (and Laravel eventually came around to the same idea), but hey, everyone has their quirks.
Either way, it’s always good to keep these in mind so you know how things are usually done. I hope it helps.
PS: I’ll keep adding more items as I run into them in my code. If you know one that’s missing from the list, please let me know.