How to write clean code in Laravel?
Tags: cleancode, laravel, beginners, productivity
Published: 2023-03-27 12:31:08

Laravel is the most beautiful thing ever done to PHP. But most developers working in project based company like in India don't utilize it to make there strength. The best thing about it is predefined structure but of-course people break it bcoz any code written in core PHP works inside Laravel. I'm writing this blog to transfer my knowledge of writing clean code in Laravel hence making projects and products maintainable and beautiful.

## Why clean code?
1. With clean code you can find your files and code faster, hence resulting into faster development.
2. Your code looks shorter hence easy to understand.
3. User experience become good with good code.
4. Debugging and updating of business logic takes less time.   

## Clean PHP
1. There are many rules for writing standard PHP code, I cannot list them all here hence just use tools which can fix your code. 
2. Use [PHP CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer), Use [PHP-CS-Fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer), Use [Laravel Pint](https://laravel.com/docs/pint) or just use Duster package for Laravel.
3. [Duster](https://github.com/tighten/duster) is a tool that brings together Laravel Pint, PHP CodeSniffer, PHP-CS-Fixer, and Tighten's Laravel-specific lints in Tlint to provide a powerful and comprehensive linting and fixing toolset for Laravel apps.
4. One programming hack I want to point it out here, Please don't use nested "If else". Instead use more "return" statements.

## Clean Models
![Models](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/reblozmc9dqbps6t42ic.jpeg)
1. Models are the representation of database table in object format hence clean Model should only contain respective table information.
2. Model should tell us which are all the field present in table without looking in database by mentioning them [Fillables](https://laravel.com/docs/10.x/eloquent#mass-assignment). 
3. Mention all the [Relationships](https://laravel.com/docs/10.x/eloquent-relationships) with other tables.
4. Use [Mutators & Casting](https://laravel.com/docs/10.x/eloquent-mutators) for formatting fields before using them.
5. Use [Scopes](https://itnext.io/understanding-laravel-scopes-a3d1f9030d51) for making eloquent queries short in respect to particular table.
6. Don't write any additional code like db queries or heavy functions. It will eventually deteriorate the quality of model.
 
## Clean Controllers
![Controllers](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q126cgfvhqub0qqq3rx6.jpg)
1. Controller is the place where business logic resides and hence it's also the place where most of the mess take place
2. Keep validation logic separately in [FormRequest](https://laravel.com/docs/10.x/validation#form-request-validation) classes. They are also simple to use and understand.
3. Keep function name simple as index, store, create, update, delete, download, search etc. Don't use random names like getUserData or saveUser. I know you will require different data set for particular entity or Model like getAdminUsers but you can just apply and extra if to your index function and that's it.
4. If a particular function like index fetches two or more items it's ideal to make child functions which you can declare in Helpers, Services, Actions, Jobs etc
In this case try to keep if-else and for-loop inside controller function only.
5. If the function doesn't use much code then it's ideal to use Models or DB query directly.
6. It's much efficient to use DB query for getting list or Index data and Eloquent for create, update, delete. 
7. Don't use try catch everywhere. it's only useable in case of multiple insertion into database for [rollback](https://laravel.com/docs/10.x/database#database-transactions). Else let the error come in logs and fix it. 
You can handle 500 error at frontend catch part, so why to catch it in backend? It will decrease your code coverage while writing test.
And if you do get error, then you always has to edit the code for finding that error in local, there's no way you will be editing backend on server, Will you?
8. Use [Resource Classes](https://laravel.com/docs/10.x/eloquent-resources) for json output. Or atleast keep the format of response same everywhere. Don't send status like "status" or "success" or "error" in response body, it can be automatically determined by [status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status) in response header.

## Clean Views
![Views](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ecdql5r87aoqd8c488t6.jpg)
1. Views are meant for better UX/UI and that can be done with better design, css, SPA, fast interaction with frontend logic.
It doesn't meant to carry all of your applications load.
2. For things which are not regularly used by user like deleting an item, why need to define it in frontend and backend both, sometimes dev do it in frontend alone, You can only handle it in backend. 
3. If your entity has less data or is static why to get that data from backend? You can store, search and filter that data quickly in you frontend, why to bother backend. In case of data change, It will be less time taking and cheaper if you store all that in single constants file rather then database. 
4. Use single master template and different layout templates for different user types. Keep Header, Sidebar and footer like component inside "includes" folder.
5. Don't call eloquent queries in blade files.
6. Keep folder structure exactly like url in pages folder even if you use frontend framework like vue or react so you can also use [folder based routing](https://github.com/hannoeru/vite-plugin-pages).
7. Keep your JS at one place(resouces/js) and css at one place (resouces/sass).
8. Use single blade file in case of [Vue](https://vuejs.org/) SPA or [Inerita](https://inertiajs.com).
9. If you are using some heavy library like moment, always use helpers or utils file as intermediatory file, don't import this heavy package directly in your component file. It will make huge impact on your bundle size.


I hope you enjoyed reading this.
Thankyou and have a nice day!