This guide defines a set of rules aimed to create consistent code across all PHP projects of Jasny.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.
The term Application is used for deliverables that are typically served by a web server or run on the command line. The term Library is used for a collection of classes and/or functions which is consumed by projects or other libraries.
Jasny follows the PSR-1 basic coding standard and PSR-2 coding style guide.
1.1. Exception on Section 2.3 - Lines
The following rule may be ignored:
Lines SHOULD NOT be longer than 80 characters; lines longer than that SHOULD be split into multiple subsequent lines of no more than 80 characters each.
The keywords AND
and OR
SHOULD NOT be used. Instead use &&
and ||
.
PHP files SHOULD be 500 lines or less.
Functions and methods SHOULD be 30 lines or less.
The alternative syntax for control structures MUST NOT be used in files containing only PHP.
You MUST a single space after each comma delimiter.
You MUST add a single space around binary operators (==, &&, ...), with the exception of the concatenation (.) operator.
You MUST place unary operators (!, --, ...) adjacent to the affected variable.
if (isset($foo->bar) && $foo->bar > 0) {
$foo->bar--;
}
You MUST use brackets [ ]
to create an array and not array( )
.
You SHOULD place each subarray on a new line for multidimension arrays.
$array = [
['red', 'blue', 'green'],
['big', 'small'],
[22, 99]
];
Loose comparison does loose casting with unexpected results. Similar to arithmetic operators (+
/-
/*
//
/**
/%
),
loose comparison operators should only be used for numeric values. This is true for ==
, !=
, <
, >
, <=
,
>=
and <=>
.
For other types use strict comparion ===
and !==
or type specific functions like strcmp
.
Within the body of a function or method, there SHOULD be no more than 3 levels of nesting. With this many levels of nesting, introduce a new function rather than to use more nested blocks.
function foo() {
if (/* ... */) {
foreach (/* ... */) {
if (/* ... */) {
// No more nested blocks
}
}
}
}
Assertions and alternative flows SHOULD come before the normal flow to reduce nesting.
Examples of good flow:
function fizz($a) {
if (!$a) {
return;
}
foo();
bar();
}
function buzz($b) {
while ($b as $i) {
if (!$i) {
continue;
}
$i->foo();
$i->bar();
}
}
Examples of bad flow, with unnecessary nesting:
function fizz($a) {
if ($a) {
foo();
bar();
}
}
function fizz($a) {
if ($a) {
foo();
} else {
return;
}
bar();
}
function buzz($b) {
while ($b as $i) {
if ($i) {
$i->foo();
$i->bar();
}
}
}
Each project MUST include a README.md
document in the root folder.
The README document SHOULD include the title of and a short description the project.
The README document MAY include a list of prerequisites.
The README document SHOULD include installation instructions.
The README document SHOULD include API documentation or a link to the API documententation.
The README document MAY include additional information which can be useful for developers.
Each class MUST have a document block.
Each public property that doesn't have a type hint MUST have a document block with an @var
tag. Each protected and
private property that doesn't have a type hint SHOULD have a document block with an @var
tag.
Each function and method SHOULD have a document block with @param
tags for all parameters and an @return
tag if a
value is returned.
Variables document block SHOULD be as precise as possible. Examples:
@return string|boolean|array
is preferred to@var mixed
@var Foo|Bar
is preferred to@var object
@var Foo[]
is preferred to@var array
A document block for a method that implements the fluent interface pattern
SHOULD state @return $this
.
Tests cases are an exception to this paragraph. See 4.4.
Applications and libraries SHOULD include unit tests, runnable by phpunit or codeception.
Each library class and function SHOULD be covered by unit tests, with a code coverage of 100%. Code that can't be tested should be explicitly ignored.
Each model class SHOULD be covered by unit tests, with a code coverage of 95% or more.
A controller class SHOULD NOT be covered by unit tests.
Applications with a web service API SHOULD include API tests, runnable by codeception.
Controller methods related to a web service SHOULD be covered by API tests, with a code covereage of 95% or more.
Applications with a user interface SHOULD have a test plan for manual acceptance testing.
Controller methods not related to a web service MAY be covered by automated functional tests, runnable by codeception.
Test cases SHOULD NOT use document blocks for all properties and methods as stated in 3.2.
Tests SHOULD use document blocks for annotations where available. Test cases SHOULD use annotations rather than code if possible.