
Good content takes time and effort to come up with.
Please consider supporting us by just disabling your AD BLOCKER and reloading this page again.
In this article, let's learn how to write clean code in PHP. These tips help you to write readable, reusable & refactorable code in PHP.
Comment comment comment your code. This doesn't mean that you start commenting everywhere in your code and create shit load of unwanted comments. If you do so then your failing to express the code you had written to other developers.
Comment whenever it's necessary, when you have some complicated code or expression so that developers and you at later point will understand what you were trying to achieve.
/** Get the user details */
public function getUser(int $id)
{
/** Fetch the user details by id */
$user = User::where('id', $id)->first();
/** Calling function to calculate user's current month salary */
$this->currentMonthSalary($user);
}
/** Calculating the current month salary of user */
private function currentMonthSalary(User $user)
{
/** Salary = (Total Days - Leave Days) * PerDay Salary */
// ...
}
public function getUser(int $id)
{
$user = User::where('id', $id)->first();
$this->currentMonthSalary($user);
}
private function currentMonthSalary(User $user)
{
/** Salary = (Total Days - Leave Days) * PerDay Salary */
// ...
}
<?php ?>
Sometimes developers try to take shortcuts when declaring PHP like the following, so that you don't have to think on enabling short tags syntax in php.ini files.
<?
echo "Hello world";
?>
<?="Hello world"; ?>
<% echo "Hello world"; %>
<?php
echo 'Hello world';
?>
$ymdstr = date('d-M-Y', strtotime($customer->created_at));
$customerRegisteredDate = date('d-M-Y', strtotime($customer->created_at));
public function user($email)
{
// ...
}
public function getUserDetailsByEmail($email)
{
// ...
}
getUserInfo(); getUserData(); getUserRecord(); getUserProfile();
getUser();
Try to use CONSTANTS or Functions for more readable & searchable code. This helps you very much in a longer run
// What the heck is 1 & 2 for?
if ($user->gender == 1) {
// ...
}
if ($user->gender == 2) {
// ...
}
public const MALE = 1;
public const FEMALE = 2;
if ($user->gender == MALE) {
// ...
}
if ($user->gender == FEMALE) {
// ...
}
Avoid deep nesting as much as possible and use early returns.
function isShopOpen($day)
{
if ($day) {
if (is_string($day)) {
$day = strtolower($day);
if ($day === 'friday') {
return true;
} elseif ($day === 'saturday') {
return true;
} elseif ($day === 'sunday') {
return true;
} else {
return false;
}
} else {
return false;
}
} else {
return false;
}
}
function isShopOpen($day)
{
if (empty($day)) {
return false;
}
$openDays = ['friday', 'saturday', 'sunday'];
return in_array(strtolower($day), $openDays) ? true : false;
}
function isShopOpen($day)
{
if (empty($day)) {
return false;
}
return in_array(strtolower($day), ['friday', 'saturday', 'sunday']) ? true : false;
}
Try checking for false conditions or negation conditions first so that the valid code remains at the bottom of the functions, this will help in readability and maintainability of the code
function isShopOpen($day)
{
if (!empty($day)) {
return in_array(strtolower($day), ['friday', 'saturday', 'sunday']) ? true : false;
}
return false;
}
function isShopOpen($day)
{
if (empty($day)) {
return false;
}
return in_array(strtolower($day), ['friday', 'saturday', 'sunday']) ? true : false;
}
Don’t force the reader of your code to translate what the variable means.
$l = ['Austin', 'New York', 'San Francisco'];
for ($i = 0; $i < count($l); $i++) {
$li = $l[$i];
doSomething();
// ...
dispatch($li);
}
$locations = ['Austin', 'New York', 'San Francisco'];
foreach ($locations as $location) {
doSomething();
// ...
dispatch($location);
}
Basically if you use the variable more than 2 times in a code then keep that variable else directly use it inside the code. This improves the readability and makes your code very cleaner.
public function create()
{
$zones = Zone::get();
$data = [
'zones' => $zones,
];
return view('customer.create', [
'data' => $data
]);
}
public function create()
{
return view('customer.create', [
'zones' => Zone::get()
]);
}
Abbreviations are nothing but your butler words or short words which you basically use in message texting.
$ord = Order::create($data);
// ...
$ord->notify();
$order = Order::create($data);
// ...
$order->createNotification();
If your class/object name tells you something, don't repeat that in your variable name.
class Car
{
public $carMake;
public $carModel;
public $carColor;
// ...
}
class Car
{
public $make;
public $model;
public $color;
// ...
}
Basically the parameter that you use with the methods will be interpreted differently by different users.
So, if you use Type Hinting then it will help the users reading your code, even your IDE will type hint the code and try to auto complete, and PHP will throw proper errors and warnings on the same.
Here we don't know whether the parameter $user
is an integer, array, object or any other type
public function show($user)
{
//
}
public function show(User $user)
{
// ...
}
public function schoolFunction(array $guests)
{
// ...
}
This is not good because $breweryName can be NULL.
function createMicrobrewery($breweryName = 'Hipster Brew Co.'): void
{
// ...
}
This opinion is more understandable than the previous version, but it better controls the value of the variable.
function createMicrobrewery($name = null): void
{
$breweryName = $name ?: 'Hipster Brew Co.';
// ...
}
You can use type hinting and be sure that the $breweryName will not be NULL.
function createMicrobrewery(string $breweryName = 'Hipster Brew Co.'): void
{
// ...
}
if ($today == 'sunday') {
return true;
} else {
return false;
}
return ($today == 'sunday') ? true : false;
Null Coalescing operator checks if the variable or the condition was empty or not.
if (!empty($user)) {
return $user;
}
return false;
return $user ?? false;
The simple comparison will convert the string in an integer.
$a = '42';
$b = 42;
if ($a != $b) {
// The expression will always pass
}
The comparison $a != $b returns FALSE but in fact it's TRUE! The string 42 is different than the integer 42.
The identical comparison will compare type and value.
$a = '42';
$b = 42;
if ($a !== $b) {
// The expression is verified
}
The comparison $a !== $b returns TRUE.
Writing conditions is not bad but if you encapsulate into methods/functions then it will help better readability and maintain code in future.
if ($article->status === 'published') {
// ...
}
if ($article->isPublished()) {
// ...
}
Dead code is just as bad as duplicate code. There's no reason to keep it in your codebase. If it's not being called, get rid of it! It will still be safe in your version history if you still need it.
function oldGetUser()
{
// ...
}
function getUser()
{
// ...
}
$request = getUser();
function getUser()
{
// ...
}
$request = getUser();
Ya I know its very hard to come out of mysql or mysqli function for database connections in PHP. But you will end up facing the following problems.
Where as if you use PDO then there are many advantages like
If you are still downloading the libraries and manually adding them or if your still using PEAR then better check composer.
Composer is a PHP Dependency manger. This will automatically add, update, remove the libraries for your project with just a simple commands.
If you would like to learn more on composer then please check the following articles
What Is Composer? How Does It Work? Useful Composer Commands And Usage
Composer Install v/s Composer Update
composer.json v/s composer.lock
If you use plain HTML/PHP view pages then you might face the following problems
Start using templating engines like smarty, twig, mustache, dwoo
Sometimes you might be prompted to run you scripts with unlimited time. But that totally bad idea to change in php.ini file
If you really want to run specific scripts without any time limit then you can only use the time limit on top of that script file or method like the following
ini_set('max_execution_time', '300'); //300 seconds = 5 minutes
ini_set('max_execution_time', '0'); // for infinite time of execution
Never trust your users, always validate any form you have in your website.
Basically 2 types of validation
1. Client side validation - done on the HTML part with Javascript or Javascript libraries like jQuery validate.
2. Server Side validation - Even if you omit the client side validation never ever skip your server side validation. Here you will validate on the server side ie. PHP side.
Eg: listing pages, same query frequently used
Turn on error reporting during development and turn off when you deploy the project to production so that your users don't see weird error on their browsers.
If you are using plain PHP then you may configure you init.php
like the following
if(!defined('ENVIRONMENT')){
define('ENVIRONMENT', 'DEVELOPMENT');
}
if (defined('ENVIRONMENT'))
{
switch (ENVIRONMENT)
{
case 'DEVELOPMENT':
$base_url = 'http://localhost/product/';
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL|E_STRICT);
break;
case 'PRODUCTION':
$base_url = 'Production URL'; /* https://google.com */
error_reporting(0);
/* Mechanism to log errors */
break;
default:
exit('The application environment is not set correctly.');
}
}
Most of the code has been adopted from Clean Code PHP & few of my experiences.
Will keep updating the article meanwhile don't forget to checkout my other articles. Hope this article helped you. Please share it with your friends.
Unable to prepare route [{fallbackPlaceholder}] for serialization. Uses Closure In Laravel
Laravel Last Executed Query In Plain SQL Statement For Debugging
Google reCAPTCHA Integration In PHP Laravel Forms
Custom Validation Rules In PHP Laravel (Using Artisan Command)
Install NGINX In Linux / Ubuntu And Managing
@stack @push and @prepend In Laravel Blade
What Is Laravel Resourceful Controllers?
Setup MAMP Virtual Hosts For Local PHP Development
Generate RSS Feeds in PHP Laravel
Sass or SCSS @function vs @mixin