In Laravel, adhering to naming conventions and best practices is essential for maintaining a clean, consistent, and readable codebase. These guidelines ensure that your code is easily understandable by other developers and aligns with community standards. This document covers general naming conventions, detailed conventions for various Laravel elements, and additional best practices to optimize your Laravel application.
Following naming conventions enhances code readability and maintainability. Below are some common naming conventions used in Laravel:
Studly Case: Class names should be in StudlyCase, also known as PascalCase, where each word in the class name starts with a capital letter and there are no separators between words. For example: UserController
, PostController
.
Camel Case: Method names should be in camelCase, where the first word is in lowercase and subsequent words start with a capital letter. For example: getUserById
, createNewPost
.
Camel Case: Variable names should also be in camelCase. For example: $userName
, $postContent
.
Plural Form: Table names should be in plural form. For example, if you have a table for users, the table name should be users
, not user
.
Snake Case: Column names should be in snake_case, where words are separated by underscores. For example: first_name
, email_address
.
Descriptive Names: Route names should be descriptive and follow a logical naming convention. For example, if you have a route to show a user profile, you might name it profile.show
.
Descriptive Names: Views should have descriptive names that reflect their purpose. For example, if you have a view for displaying user information, you might name it: user-profile.blade.php
.
Snake Case: Configuration file names should be in snake_case. For example: database.php
, mail.php
.
Plural Form: Resource names should be in plural form to represent a collection of resources. For example, if you have a resource for managing posts, you might name it: PostsResource
.
To leverage Laravel’s features effectively, follow these detailed naming conventions for various elements. The table below summarizes good and bad practices, adhering to PSR standards and Laravel community conventions:
What | How | Good | Bad |
---|---|---|---|
Controller | singular | ArticleController |
ArticlesController |
Route | plural | articles/1 |
article/1 |
Route name | snake_case with dot notation | users.show_active |
users.show-active , show-active-users |
Model | singular | User |
Users |
hasOne or belongsTo relationship | singular | articleComment |
articleComments , article_comment |
All other relationships | plural | articleComments |
articleComment , article_comments |
Table | plural | article_comments |
article_comment , articleComments |
Pivot table | singular model names in alphabetical order | article_user |
user_article , articles_users |
Table column | snake_case without model name | meta_title |
MetaTitle , article_meta_title |
Model property | snake_case | $model->created_at |
$model->createdAt |
Foreign key | singular model name with _id suffix |
article_id |
ArticleId , id_article , articles_id |
Primary key | - | id |
custom_id |
Migration | - | 2017_01_01_000000_create_articles_table |
2017_01_01_000000_articles |
Method | camelCase | getAll |
get_all |
Method in resource controller | table | store |
saveArticle |
Method in test class | camelCase | testGuestCannotSeeArticle |
test_guest_cannot_see_article |
Variable | camelCase | $articlesWithAuthor |
$articles_with_author |
Collection | descriptive, plural | $activeUsers = User::active()->get() |
$active , $data |
Object | descriptive, singular | $activeUser = User::active()->first() |
$users , $obj |
Config and language files index | snake_case | articles_enabled |
ArticlesEnabled , articles-enabled |
View | kebab-case | show-filtered.blade.php |
showFiltered.blade.php , show_filtered.blade.php |
Config | snake_case | google_calendar.php |
googleCalendar.php , google-calendar.php |
Contract (interface) | adjective or noun | AuthenticationInterface |
Authenticatable , IAuthentication |
Trait | adjective | Notifiable |
NotificationTrait |
Trait (PSR) | adjective | NotifiableTrait |
Notification |
Enum | singular | UserType |
UserTypes , UserTypeEnum |
FormRequest | singular | UpdateUserRequest |
UpdateUserFormRequest , UserFormRequest , UserRequest |
Seeder | singular | UserSeeder |
UsersSeeder |
Note: Always follow PSR standards and naming conventions accepted by the Laravel community for compatibility and maintainability.
Laravel embraces the principle of convention over configuration, reducing the need for explicit configuration when conventions are followed. This leads to cleaner and more maintainable code. Below is an example:
// Table name 'Customer'
// Primary key 'customer_id'
class Customer extends Model {
const CREATED_AT = 'created_at';
const UPDATED_AT = 'updated_at';
protected $table = 'Customer';
protected $primaryKey = 'customer_id';
public function roles(): BelongsToMany{
{
return $this->belongsToMany(Role::class, 'role_customer', 'customer_id', 'role_id');
}
}
// Table name 'customers'
// Primary key 'id'
class Customer extends Model {
public function roles(): BelongsToMany
{
return $this->belongsToMany(Role::class);
}
}
By adhering to conventions (e.g., plural table names, default id
primary key), the good practice example eliminates unnecessary configuration, simplifying the code.
Bad:
$request->session()->get('cart');
$request->input('name');
Good:
session('cart');
$request->name;
Laravel offers helper functions and shorthand methods to make code concise and readable. Below are examples comparing common syntax with shorter alternatives:
Common Syntax | Shorter and More Readable Syntax |
---|---|
Session::get('cart') |
session('cart') |
$request->session()->get('cart') |
session('cart') |
Session::put('cart', $data) |
session(['cart' => $data]) |
$request->input('name') , Request::get('name') |
$request->name , request('name') |
return Redirect::back() |
return back() |
is_null($object->relation) ? null : $object->relation->id |
optional($object->relation)->id or $object->relation?->id |
return view('index')->with('title', $title)->with('client', $client) |
return view('index', compact('title', 'client')) |
$request->has('value') ? $request->value : 'default' |
$request->get('value', 'default') |
Carbon::now() , Carbon::today() |
now() , today() |
App::make('Class') |
app('Class') , resolve('Class') |
->where('column', '=', 1) |
->where('column', 1) |
->orderBy('created_at', 'desc') |
->latest() |
->orderBy('age', 'desc') |
->latest('age') |
->orderBy('created_at', 'asc') |
->oldest() |
->select('id', 'name')->get() |
->get(['id', 'name']) |
->first()->name |
->value('name') |
Using these shorthand methods improves code clarity and reduces verbosity.
Instantiating classes with new
creates tight coupling, complicating testing and maintenance. Use Laravel’s IoC container or dependency injection instead.
$user = new User;
$user->create($request->validated());
public function __construct(User $user)
{
$this->user = $user;
}
public function store(Request $request)
{
$this->user->create($request->validated());
}
Avoid accessing environment variables directly in your code. Use configuration files and the config()
helper instead.
$api_key = env('API_KEY');
// config/api.php
return [
'key' => env('API_KEY'),
];
// Usage
$api_key = config('api.key');
A date as a string is less reliable than an object instance, e.g. a Carbon-instance. It's recommended to pass Carbon objects between classes instead of date strings. Rendering should be done in the display layer (templates):
{{ Carbon::createFromFormat('Y-d-m H-i', $object->ordered_at)->toDateString() }}
{{ Carbon::createFromFormat('Y-d-m H-i', $object->ordered_at)->format('m-d') }}
// Model
protected $casts = [
'ordered_at' => 'datetime',
];
// Blade view
{{ $object->ordered_at->toDateString() }}
{{ $object->ordered_at->format('m-d') }}
DocBlocks reduce readability. Use a descriptive method name and modern PHP features like return type hints instead.
/**
*
* The function checks if given string is a valid ASCII string
*
* @param string $string String we get from frontend which might contain
* illegal characters. Returns True is the string
* is valid.
*
* @return bool
* @author John Smith
*
* @license GPL
*/
public function checkString($string)
{
}
public function isValidAsciiString(string $string): bool
{
}
- Avoid Alien Patterns: Avoid using patterns and tools that are alien to Laravel and similar frameworks (i.e. RoR, Django). If you like Symfony (or Spring) approach for building apps, it's a good idea to use these frameworks instead.
- No Logic in Routes: Never put any logic in routes files.
- Minimize Vanilla PHP in Blade: Use Blade directives and helpers instead.
- In-Memory DB for Testing: Use SQLite or similar for faster tests.
- Avoid Overriding Framework Features: This prevents issues during updates.
- Modern PHP Syntax: Use it where it improves readability, but prioritize clarity.
- Avoid using View Composers and similar tools unless you really know what you're doing. In most cases, there is a better way to solve the problem.
Prefer to use built-in Laravel functionality and community packages instead of using 3rd party packages and tools. Any developer who will work with your app in the future will need to learn new tools. Also, chances to get help from the Laravel community are significantly lower when you're using a 3rd party package or tool. Do not make your client pay for that.
Task | Standard Tools | 3rd Party Tools |
---|---|---|
Authorization | Policies | Entrust, Sentinel and other packages |
Compiling assets | Laravel Mix, Vite | Grunt, Gulp, 3rd party packages |
Development Environment | Laravel Sail, Homestead | Docker |
Deployment | Laravel Forge | Deployer |
Unit testing | PHPUnit, Mockery | Phpspec, Pest |
Browser testing | Laravel Dusk | Codeception |
DB | Eloquent | SQL, Doctrine |
Templates | Blade | Twig |
Working with data | Laravel collections | Arrays |
Form validation | Request classes | 3rd party packages, controller validation |
Authentication | Built-in | 3rd party packages, custom solutions |
API authentication | Laravel Passport, Sanctum | 3rd party JWT, OAuth packages |
Creating API | Built-in | Dingo API and similar |
Working with DB structure | Migrations | Working with DB structure directly |
Localization | Built-in | 3rd party packages |
Realtime user interfaces | Laravel Echo, Pusher | WebSockets, 3rd party packages |
Generating testing data | Seeder classes, Model Factories, Faker | Creating testing data manually |
Task scheduling | Laravel Task Scheduler | Scripts, 3rd party packages |
DB | MySQL, PostgreSQL, SQLite, SQL Server | MongoDB |
By following these conventions and practices, your Laravel application will be more maintainable, compatible with community standards, and easier for others to understand and contribute to.