PSR-[0-4]
- PSR stands for Proposing a Standards Recommendation.
- PSR-0 (Autoloading Standard)
- PSR-1 (Basic Coding Standard)
- PSR-2 (Coding Style Guide)
- PSR-3 (Logger Interface)
- PSR-4 (Improved Autoloading, can replace PSR-0)
PSR-1
- PHP source files must use only the
<?php and <?= tags.
- Source code encoding must be UTF-8 without BOM.
- A source file should either declare symbols (classes, functions, constants) or perform side effects (e.g., output, config changes), but not both.
- Namespaces and classes must follow the PSR-0 standard.
- Class names must be written in StudlyCaps.
- Class constants must use only uppercase letters and underscores.
- Method names must be written in camelCase.
PSR-2
- Files must end with a single blank line.
- Line endings must be Unix LF.
- The closing tag
?> must be omitted in pure PHP files.
- Indentation must be 4 spaces.
- Line length should be kept at most 80 characters.
- PHP keywords, including
true, false, and null, must be lowercase.
- Namespaces
- One blank line after the namespace declaration.
- All
use declarations must be placed after the namespace declaration.
- Only one
use keyword per statement.
- One blank line after the
use block.
<?php
namespace App\Models;
use Psr\Log\LoggerInterface;
use App\Exceptions\DatabaseException as DBException;
use App\Services\ConfigService;
class User
{
}
extends and implements must be on the same line as the class name, and the opening brace must be on a new line.
<?php
namespace App\Models;
class User extends BaseModel implements \ArrayAccess, \JsonSerializable
{
}
- Properties must declare their visibility (
public, protected, or private).
- Methods must declare their visibility. The opening brace must be on a new line. Parameters: first parameter after a space, comma and space between parameters, functon name and opening parenthesis must have a space. Default values should be spaced.
<?php
namespace App\Models;
class User extends BaseModel implements \ArrayAccess, \JsonSerializable
{
public function fetchDetails(string $username, int $age, string $gender = 'unknown')
{
// method body
}
}
- When using
abstract or final, they must be placed before the visibility declaration. static must be placed after visibility.
<?php
namespace App\Core;
abstract class AbstractFactory
{
protected static $instances = [];
abstract protected function createInstance(string $type);
final public static function getInstance(string $type): self
{
// method body
}
}
- Function calls
- No spaces before or after parentheses.
- No space before a comma, one space after.
- For multi-line arguments, each argument on its own line.
<?php
bar();
$foo->bar($arg1);
Foo::bar($arg2, $arg3);
$foo->bar(
$longArgument,
$longerArgument,
$muchLongerArgument
);
<?php
if ($condition) {
// if body
} elseif ($otherCondition) {
// elseif body
} else {
// else body
}
switch ($statusCode) {
case 200:
echo 'OK';
break;
case 301:
case 302:
echo 'Redirect';
// no break
case 404:
echo 'Not Found';
return;
default:
echo 'Unknown';
break;
}
while ($iterator->valid()) {
// structure body
}
do {
// execute at least once
} while ($running);
for ($index = 0; $index < $max; $index++) {
// for body
}
foreach ($items as $key => $value) {
// foreach body
}
try {
// try body
} catch (InvalidArgumentException $exception) {
// catch body
} catch (RuntimeException $exception) {
// catch body
}
<?php
$add = function(int $a, int $b): int {
return $a + $b;
};
$multiplyWithFactor = function(int $value) use ($factor): int {
return $value * $factor;
};
// Multi-line examples
$processData = function (
string $input,
array $options,
int $timeout = 30
) {
// body
};
$useLongVars = function () use (
$longVar1,
$longerVar2,
$muchLongerVar3
) {
// body
};
$bothLong = function (
$longArgument,
$longerArgument,
$muchLongerArgument
) use (
$longVar1,
$longerVar2,
$muchLongerVar3
) {
// body
};
$longArgsShortVars = function (
$longArgument,
$longerArgument,
$muchLongerArgument
) use ($var1) {
// body
};
$shortArgsLongVars = function ($arg) use (
$longVar1,
$longerVar2,
$muchLongerVar3
) {
// body
};
PSR-3
PSR-4
- Improved autoloading.
- The term "class" refers to classes, interfaces, traits, and other similar structures.
- A fully qualified class name has the following structure:
\<Namespace>(\<SubNamespace>)*\<ClassName>
- A fully qualified class name must have a top-level namespace ("vendor namespace").
- It may have one or more sub‑namespaces.
- It must have a final class name.
- Underscores in any part have no special meaning.
- Letters can be any combination of upper‑ and lower‑case.
- All class names are case‑sensitive.
- The contiguous sequence of namespace and sub‑namespaces before the class name (minus the leading separator) is the "namespace prefix", which must correspond to at least one "base directory".
- The sub‑namespaces after the prefix must match the base directory structure, using the namepsace separator as directory separator.
- The final class name must match the file name, with a
.php extension.
- Autoloader implementations must not throw exceptions, must not trigger errors of any level, and should have no return value.