PHP Coding Rule - Final
PHP Coding Rule - Final
For projects are written in PHP, we need to have contribution rules in development team. Beside
that the rules should be accepted widenly as an international standard to avoid controversy,
ambiguous and ensure a high level of technical interoperability.
In the limitation we will agree about some conventions are recognized by the community and
another specific rules.
Index
1. International Standard Convention
2. PHP Project Convention
2.1. Basic Rules and Standard
2.2. Naming Convention
2.2.1. Case Styles
2.3. Rules for break line
2.4. Rules for comment
2.5. Rules for logging
2.6. Rules for quantity (optional)
2.7. Rule for checking empty (optional)
2.8. Hard coding
2.9. Template
3. Traits
4. Best Practices
5. Check Style
6. Conclusion
1. International Standard Convention ↑
RFC7231 asserts about the semantics and content for Restful Web Service and related
technologies such as AJAX so HTTP methods (GET, HEAD, POST, PUT, PATCH, DELETE) will
be used in the suitable context.
RFC2616 asserts about HTTP status codes and its meaning for suitable case as it should be.
PSR-2 and PSR-4 are coding conventions for PHP Coding Standard which are approved
widenly from PHP Community (PHP Framework Interoperability Group) for several industrial
frameworks so PHP Developers must comply strictly in software development process.
Object Oriented Programming and related concepts of Object Oriented Programming must
be strictly apply to ensure about the abstraction , encapsulation , polymorphism and
inheritance at least. A professional developer should understand clearly and apply it
properly to ensure the structural, tightness, maintainable and adapt for enterprise
application.
Laravel Framework asserts that we should follows PSR-2 and PSR-4 so it ONLY contains
rules about PHPDoc. Anything relates to Laravel Framework which does not comply to RFC
or PSR-2/PSR-4 or OOP Concepts (if exist) will not be accepted.
2. PHP Project Convention ↑
2.1. Basic Rules and Standard ↑
These are the standards for writing code, there are a few simple rules as follows:
For file
The code must be written in <?php ?> Tag pairs and should use <?= ?> Short tags instead
of echo.
For PHP> = 5.4, use [] to declare array, instead of array ().
Code can only use UTF-8 without BOM (BOM - Byte Order Mark is the sequence of EF, BB,
BF at the beginning of the file, allowing the software to know this is a UTF-8 file).
Use the latest version of PHP if possible.
Each PHP file should only do 1 single task, avoid overlapping (called side effect).
For naming
Code must comply with PSR-1 & PSR-0.
Namespace must comply with the standard PSR "autoloading" (PSR-0, PSR-4).
The class name must be written according to the PascalCase rule (or another name
StudlyCaps).
The parameters must capitalize all letters, separated by underscores.
The method name is written according to the camelCase rule.
For functions
The closing and opening tags of a function {} must be separated on one line.
Before opening and closing the {} function, there must be no blank line.
If you must use abstract and final or static to declare the function, you must declare it in
order.
For variables and parameters
A single quote must be used to declare the string does not contain a variable, if the string
contains the character ' then use double quotes " to wrap it around (we are often
confused by this problem).
There must be a space before and after the operation, when cast, there must be a space
between the data type and the cast variable.
Use accents . to concatenate - notice before and after the period . must have spaces. If
the string is too long, split into multiple lines and the dot is placed before the line with the
equal sign.
The parameters passed to the function must have a space before the comma, you can split
into multiple lines but must be indented 1 unit.
The variable name is written as camelCase. For the property name inside the Model, it can
be written as snake_case to match the names of the columns in the Database tables.
Use the ' sign for a normal string. Use " only when PHP variables are internally
implemented.
There should be a space before and after operators like +, -,, /,.,>, <, ==
Variables should be declared at the beginning of the function or a scope block.
Reusable variables should not be declared in a loop scope block.
PHP is a loosely typed language, it allows variable declaration without specifying its
datatype. PHP provides various datatypes and the type conversion can be performed in
various methods. After each type casting, please specify the output and the type of the
variable using PHP comment line.
For statements, elements and arrays
For switch case statements, the case must be 4 spaces behind the switch, and the
commands in the case must be 4 spaces behind the case. There must be a break or return
keyword, in which case no one has to comment // no break
When declaring arrays, elements of the array can be separated into multiple lines. In doing
so, the following rules need to be followed:
The first word of the array must be on a new line.
Only one element per line is allowed, elements are allowed to indent once.
Commas need to be at the end of the last element.
The end of the array declaration (square brackets) must be placed on a new line.
For lines
On a line that does not exceed 120 characters, it is best to be less than or equal to 80
characters, there should be no trailing white space.
There must be a blank line after the namespace declaration and there must be a blank line
after the use declarations.
2.2. Naming Convention ↑
PascalCase for name of classes, functional directories,... E.g.: SendMailService,
HomeController, Controllers,...
camelCase for name of variables, methods, functions. E.g.: $userName, getUserName,
setGoodsPrice,...
snake_case for name of resources. E.g.: user_detail, order_list,...
UPPER_CASE for name of constants, parameters. E.g.: CATEGORY_CD_PAYMENT_TYPE ,
PROCESS_STATUS_DONE ,...
Note:
Below version of PHP 5.5, empty() only supports variables, anything other will result in a
parse error. The following statement will not work empty(trim($var)) . Instead, use
trim($name) == false .
Return Value:
It returns FALSE when $var exists and has a non-empty, non-zero value. Otherwise it
returns TRUE .
These values are considered to be as an empty value:
"" (an empty string)
0 (0 as an integer)
0.0 (0 as a float)
"0" (0 as a string)
NULL
FALSE
array() (an empty array)
The table below is an easy reference for what these functions will return for different values. The
blank spaces means the function returns bool(false) .
Value of variable ($var) isset($var) empty($var) is_null($var)
"" (an empty string) bool(true) bool(true)
TRUE bool(true)
2.9. Template ↑
Copyright header
<?php
/**
* --------------------------------------------------------------------
* Copyright (c) 2019 Project X. All rights reserved.
* --------------------------------------------------------------------
* NOTICE: All information contained herein is, and remains
* the property of Vitalify Asia Co., Ltd and its suppliers,
* if any. The intellectual and technical concepts contained
* herein are proprietary to Vitalify Asia Co., Ltd
* and its suppliers and may be covered by Vietnamese Law,
* patents in process, and are protected by trade secret or copyright law.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Vitalify Asia Co., Ltd.
* --------------------------------------------------------------------
* Author 1: Author One <author.one@@vitalify.asia>
* Author 2: Author Two <author.two@@vitalify.asia>
* --------------------------------------------------------------------
Class description
namespace App\Core\Controller;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
/**
* Abstract Controller
* This controller is an example about abstract class
*
* @category \App\Core
* @package \App\Core\Controller
* @author Author One <author.one@vitalify.asia>
* @author Author Two <author.two@vitalify.asia>
* @copyright 2019 Vitalify Asia Vietnam
*/
abstract class Controller extends BaseController
{
/**
* By default this controller uses a trait to
* provide this functionality without requiring any additional code.
*/
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
}
Encapsulation in OOP
/**
* User hashed password
*
* @var string password
*/
private $password;
/**
* Set password for user
* Raw password will be hashed by bcrypt algorithm before saving to database
*
* @param string $email
* @return User
*/
public function setPassword(string $rawPassword): User
{
$this->password = Hash::make($rawPassword);
return $this;
}
/**
* Get user password in bcrypt format
*
* @return string
*/
public function getPassword(): string
{
return $this->password;
}
3. Traits ↑
As of PHP 5.4.0, PHP implements a method of code reuse called Traits.
Traits are a mechanism for code reuse in single inheritance languages such as PHP. A Trait is
intended to reduce some limitations of single inheritance by enabling a developer to reuse
sets of methods freely in several independent classes living in different class hierarchies.
The semantics of the combination of Traits and classes is defined in a way which reduces
complexity, and avoids the typical problems associated with multiple inheritance and Mixins.
A Trait is similar to a class, but only intended to group functionality in a fine-grained and
consistent way. It is not possible to instantiate a Trait on its own. It is an addition to traditional
inheritance and enables horizontal composition of behavior; that is, the application of class
members without requiring inheritance.
Precedence
An inherited member from a base class is overridden by a member inserted by a Trait.
The precedence order is that members from the current class override Trait methods, which
in turn override inherited methods.
Multiple Traits
Multiple Traits can be inserted into a class by listing them in the use statement, separated by
commas.
Example for Multiple Traits Usage
<?php
trait HelloTrait {
public function sayHello() {
echo 'Hello ';
}
}
trait WorldTrait {
public function sayWorld() {
echo 'World';
}
}
class MyHelloWorld {
use HelloTrait, WorldTrait;
public function sayExclamationMark() {
echo '!';
}
}
$o = new MyHelloWorld();
$o->sayHello();
$o->sayWorld();
$o->sayExclamationMark();
?>
Conflict Resolution
If two Traits insert a method with the same name, a fatal error is produced, if the conflict is
not explicitly resolved.
To resolve naming conflicts between Traits used in the same class, the insteadof operator
needs to be used to choose exactly one of the conflicting methods.
Since this only allows one to exclude methods, the as operator can be used to add an alias to
one of the methods. Note the as operator does not rename the method and it does not
affect any other method either.
Example for Conflict Resolution
In this example, Talker uses the traits AndyTrait and BobTrait . Since AndyTrait
and BobTrait have conflicting methods, it defines to use the variant of smallTalk from
trait BobTrait , and the variant of bigTalk from trait AndyTrait .
The Aliased_Talker makes use of the as operator to be able to use BobTrait's bigTalk
implementation under an additional alias talk.
<?php
trait AndyTrait {
public function smallTalk() {
echo 'andy';
}
public function bigTalk() {
echo 'Andy';
}
}
trait BobTrait {
public function smallTalk() {
echo 'bob';
}
public function bigTalk() {
echo 'Bob';
}
}
class Talker {
use AndyTrait, BobTrait {
BobTrait::smallTalk insteadof AndyTrait;
AndyTrait::bigTalk insteadof BobTrait;
}
}
class Aliased_Talker {
use AndyTrait, BobTrait {
BobTrait::smallTalk insteadof AndyTrait;
AndyTrait::bigTalk insteadof BobTrait;
BobTrait::bigTalk as talk;
}
}
?>
Right
Declare property $thisPropertyDoesNotExist before using it
Eval function
Wrong
eval("$a + $b");
Right
// This is an explaination about why we must use eval in here
// If you can not explain please DO NOT use
eval("$a + $b");
Ternary operator
Wrong
$example = trim($this->doSomething()) ? $this->doSomething() : "";
Right
// ONLY use ternary in return statement of simple statement
$isSomethingNotEmpty = ! empty(trim($this->doSomething()));
return $isSomethingNotEmpty ? $this->doSomething() : "";
if ($c) {
return;
}
return;
Else keyword has no effect to return statement
Wrong
if ($a) {
return true;
} else {
return false;
}
return false;
Because the cost for human readable and maintainace is expensive so please DO NOT abuse if
you can do in a better way.
5. Check Style ↑
It is required for all PHP project, base on defined project convention.
Use checkstyle.xml to check code convention before commit code.
6. Conclusion ↑
All developers should follow this agreement about best practices
to ensure about unique coding style and maintainability.