Skip to content
KHEN / ES
Menu
All posts

Published Feb 22, 2020

Laravel best practices: naming conventions

Almost everything in Laravel is configurable, but the framework already has a way of naming things, and following it saves you a lot of extra setup.

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:

thisIsFine
ThisIsNotRight
neither_is_this

PascalCase

Very similar to the previous one, except that here the first letter is uppercase too. It’s named after the Pascal programming language. Examples:

ThisIsFine
notAnymore
even_less_this

snake_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_fine
thisIsNot
ThisEvenLess
dont-get-me-started-on-this-one

kebab-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-turn
ThisIsNotRight
thisEvenLess
looks_similar_but_nope

So, 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 UserController
class OrderDetailController
class UsersController
class customerController
class DetalleDeFacturaController
class borrowed-book-controller

Functions

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 User
class OrderDetail
class Users
class customer
class DetalleDeFactura
class borrowed-book

Model 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->LaunchDate

Relationships

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/7

Tables

Entity tables

Tables take the plural English name of the entity, this time in snake_case. Some examples:

users
order_details
Payment
invoice
libros

Pivot 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_user
category_post
user_permission
UserPermission
post_category

Columns

Columns are named in snake_case. Examples:

id
created_at
phone_number
createdAt
PhoneNumber

Primary 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_id
user_id
mobile_phone_id
userId
PostId

Variables

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.php
active-user.blade.php
create-admin.blade.php
active_user.blade.php
createAdmin.blade.php

Wrapping 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.