简介
PSR是PHP Standards Recommendation的简称
PSR是php-fig组织制定的一套规范。**
官网:https://www.php-fig.org/
下面是常用的几套规范
PSR-0:该标准不推荐使用,已被PSR-4替代。
PSR-1:基本编码标准。
PSR-2:该标准不推荐使用,已被PSR-12替代。
PSR-3:日志记录器接口。
PSR-4:自动加载。
PSR-12:扩展编码样式。该规范扩展,扩展和替代了PSR-2(编码样式指南),并且要求遵守基本编码标准PSR-1
PSR-1
RSR-1:基本编码标准。
概述
- 文件只能使用<?php和<?=标记。
- 文件必须仅使用UTF-8,而不使用BOM用于PHP代码。
- 文件应该任一声明的符号(类,函数,常量等) 或引起副作用(例如生成输出,变化的.ini设置,等等),但是不应该这样做既。
- 命名空间和类必须遵循“自动加载” PSR:[ PSR-0,PSR-4 ]。
- 类名必须在中声明StudlyCaps。
- 类常量必须在所有大写字母中使用下划线分隔符声明。
- 方法名称必须在中声明camelCase。
命名空间和类名详解
命名空间和类必须遵循“自动加载” PSR:[ PSR-0,PSR-4 ]。
这意味着每个类本身都在文件中,并且在至少一个级别的命名空间中:顶级供应商名称。
类名必须在中声明StudlyCaps。
为PHP 5.3和之后编写的代码必须使用正式的大驼峰式名称空间。
例如:
<?php
// PHP 5.3 and later:
namespace Vendor\Model;
class Foo
{
}
为5.2.x和之前版本编写的代码应Vendor_在类名上使用前缀的伪命名间隔约定。
<?php
// PHP 5.2.x and earlier:
class Vendor_Model_Foo
{
}
类常量,属性和方法详解
术语“类”是指所有类,接口和特征。
1.常数
类常量必须在所有大写字母中使用下划线分隔符声明。例如:
<?php
namespace Vendor\Model;
class Foo
{
const VERSION = '1.0';
const DATE_APPROVED = '2012-06-01';
}
2.属性名称
本指南有意避免关于使用任何建议
$StudlyCaps,$camelCase或$under_score
属性名称。
无论使用哪种命名约定,都应在合理范围内一致地应用。该范围可以是供应商级,程序包级,类级或方法级。
3.方法
方法名称必须小写字母开头的驼峰式camelCase() 。
PSR-3
RSR-3:日志规范样式。
八个 水平(调试,信息,通知,警告,错误,危险,严重警告,紧急)
<?php
namespace Psr\Log;
/**
* Describes log levels.
*/
class LogLevel
{
const EMERGENCY = 'emergency';
const ALERT = 'alert';
const CRITICAL = 'critical';
const ERROR = 'error';
const WARNING = 'warning';
const NOTICE = 'notice';
const INFO = 'info';
const DEBUG = 'debug';
}
PSR-4
RSR-4:自动加载。
规格
术语“类”是指类,接口,特征和其他类似的结构。
完全限定的类名称具有以下形式:
\<NamespaceName>(\<SubNamespaceNames>)*\<ClassName>
完全合格的类名称必须具有顶级名称空间名称,也称为“供应商名称空间”。
完全合格的类名称可以具有一个或多个子命名空间名称。
完全合格的类名称必须具有终止类名称。
下划线在完全限定的类名的任何部分中没有特殊含义。
完全限定的类名中的字母字符可以是小写和大写的任意组合。
所有类名必须以区分大小写的方式引用。
加载与完全限定的类名相对应的文件时…
在完全限定的类名(“名称空间前缀”)中,一个或多个开头的名称空间和子名称空间名称(不包括开头的名称空间分隔符)的连续序列对应于至少一个“基本目录”。
“名称空间前缀”之后的连续子名称空间名称对应于“基本目录”中的子目录,其中名称空间分隔符表示目录分隔符。子目录名称必须与子命名空间名称的大小写匹配。
终止类名对应于以结尾的文件名.php。文件名必须与终止类名的大小写匹配。
自动加载器的实现不得抛出异常,不得引发任何级别的错误,并且不应返回值。
示例
完整名称 | 命名空间前缀 | 基本目录 | 结果文件路径 |
---|---|---|---|
\Acme\Log\Writer\File_Writer | Acme\Log\Writer | ./acme-log-writer/lib/ | ./acme-log-writer/lib/File_Writer.php |
\Aura\Web\Response\Status | Aura\Web | /path/to/aura-web/src/ | /path/to/aura-web/src/Response/Status.php |
\Symfony\Core\Request | Symfony\Core | ./vendor/Symfony/Core/ | ./vendor/Symfony/Core/Request.php |
\Zend\Acl | Zend | /usr/includes/Zend/ | /usr/includes/Zend/Acl.php |
PSR-12
RSR-12:扩展编码样式。
总览
该规范扩展,扩展和替代了PSR-2(编码样式指南),并且要求遵守基本编码标准PSR-1。
本示例简要概述了以下一些规则:
<?php
declare(strict_types=1);
namespace Vendor\Package;
use Vendor\Package\{ClassA as A, ClassB, ClassC as C};
use Vendor\Package\SomeNamespace\ClassD as D;
use function Vendor\Package\{functionA, functionB, functionC};
use const Vendor\Package\{ConstantA, ConstantB, ConstantC};
class Foo extends Bar implements FooInterface
{
public function sampleFunction(int $a, int $b = null): array
{
if ($a === $b) {
bar();
} elseif ($a > $b) {
$foo->bar($arg1);
} else {
BazClass::bar($arg2, $arg3);
}
}
final public static function bar()
{
// method body
}
}
行规定
线长绝不能有硬性限制。
行长的软限制必须为120个字符。
行数不能超过80个字符;长于该行的行应分成多行,每行不超过80个字符。
行尾一定不能有尾随空格。
除非明确禁止,否则可以添加空行以提高可读性并指示相关的代码块。
每行不得超过一个语句。
缩进
代码必须为每个缩进级别使用4个空格的缩进,并且不得使用制表符进行缩进。
关键字和类型
所有PHP保留的关键字和类型都必须小写。
添加到将来的PHP版本中的任何新类型和关键字都必须小写。
类型关键字的缩写形式必须使用,即bool代替boolean, int代替integeretc。
声明语句,命名空间和导入语句
PHP文件的标头可能包含许多不同的块。如果存在,则下面的每个块都必须由单个空白行分隔,并且不得包含空白行。每个块都必须按照下面列出的顺序进行,尽管可以忽略不相关的块。
开头<?php标签。
文件级文档块。
一个或多个声明语句。
文件的名称空间声明。
一个或多个基于类的use导入语句。
一个或多个基于函数的use导入语句。
一个或多个基于常量的use导入语句。
文件中的其余代码。
当文件包含HTML和PHP的混合时,以上任何部分都可以使用。如果是这样,即使代码的其余部分包含一个封闭的PHP标记,然后包含HTML和PHP,它们也必须出现在文件的顶部。
当开始<?php标记在文件的第一行时,它必须在自己的行上且没有其他语句,除非它是一个包含PHP开头和结束标记之外的标记的文件。
导入语句绝不能以反斜杠开头,因为它们必须始终完全合格。
以下示例说明了所有块的完整列表:
<?php
/**
* This file contains an example of coding styles.
*/
declare(strict_types=1);
namespace Vendor\Package;
use Vendor\Package\{ClassA as A, ClassB, ClassC as C};
use Vendor\Package\SomeNamespace\ClassD as D;
use Vendor\Package\AnotherNamespace\ClassE as E;
use function Vendor\Package\{functionA, functionB, functionC};
use function Another\Vendor\functionD;
use const Vendor\Package\{CONSTANT_A, CONSTANT_B, CONSTANT_C};
use const Another\Vendor\CONSTANT_D;
/**
* FooBar is an example class.
*/
class FooBar
{
// ... additional PHP code ...
}
extends和implements
在extends和implements关键字必须在同一行类名来声明。
<?php
namespace Vendor\Package;
use FooClass;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;
class ClassName extends ParentClass implements \ArrayAccess, \Countable
{
// constants, properties, methods
}
implements在接口的列表中,如果是接口,则extends可以分成多行,每行的后一行缩进一次。这样做时,列表中的第一项必须位于下一行,并且每行必须只有一个接口。
<?php
namespace Vendor\Package;
use FooClass;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;
class ClassName extends ParentClass implements
\ArrayAccess,
\Countable,
\Serializable
{
// constants, properties, methods
}
抽象,最终和静态
如果存在,则abstract和final声明必须在可见性声明之前。
如果存在,则static声明必须在可见性声明之后。
<?php
namespace Vendor\Package;
abstract class ClassName
{
protected static $foo;
abstract protected function zim();
final public static function bar()
{
// method body
}
}
控制结构
控件结构的通用样式规则如下:
控制结构关键字后面必须有一个空格
开头括号后一定不能有空格
右括号前不得有空格
右括号和左括号之间必须有一个空格
结构体必须缩进一次
主体必须在开括号之后的下一行
右括号必须在主体之后的下一行
每个结构的主体必须用大括号括起来。
<?php
if ($expr1) {
// if body
} elseif ($expr2) {
// elseif body
} else {
// else body;
}
if (
$expr1
&& $expr2
) {
// if body
} elseif (
$expr3
&& $expr4
) {
// elseif body
}
switch ($expr) {
case 0:
echo 'First case, with a break';
break;
case 1:
echo 'Second case, which falls through';
// no break
case 2:
case 3:
case 4:
echo 'Third case, return instead of break';
return;
default:
echo 'Default case';
break;
}
switch (
$expr1
&& $expr2
) {
// structure body
}
while ($expr) {
// structure body
}
while (
$expr1
&& $expr2
) {
// structure body
}
do {
// structure body;
} while ($expr);
do {
// structure body;
} while (
$expr1
&& $expr2
);
for ($i = 0; $i < 10; $i++) {
// for body
}
for (
$i = 0;
$i < 10;
$i++
) {
// for body
}
foreach ($iterable as $key => $value) {
// foreach body
}
try {
// try body
} catch (FirstThrowableType $e) {
// catch body
} catch (OtherThrowableType | AnotherThrowableType $e) {
// catch body
} finally {
// finally body
}
一元运算符
递增/递减运算符不得在运算符和操作数之间有任何空格。
$i++;
++$j;
类型转换运算符的括号内不得有任何空格:
$intValue = (int) $input;
二元运算符
所有二进制算术,比较,赋值,按位, 逻辑,字符串和类型运算符都必须位于前缀和后跟至少一个空格:
if ($a === $b) {
$foo = $bar ?? $a ?? $b;
} elseif ($a > $b) {
$foo = $a + $b * $c;
}
三元运算符
条件运算符(也简称为三元运算符)必须位于? 和:字符之前和之后至少一个空格:
$variable = $foo ? 'foo' : 'bar';
当省略条件运算符的中间操作数时,该运算符必须遵循与其他二进制比较运算符相同的样式规则:
$variable = $foo ?: 'bar';
闭包
闭包必须在function关键字之后加一个空格,在关键字之前和之后加一个空格use。
开括号必须在同一行上,闭括号必须在主体之后的下一行上。
参数列表或变量列表的右括号后不得有空格,参数列表或变量列表的右括号前不得有空格。
在参数列表和变量列表中,每个逗号前面一定不能有空格,每个逗号后面一定不能有空格。
具有默认值的闭包参数必须位于参数列表的末尾。
如果存在返回类型,则它必须遵循与正常函数和方法相同的规则;如果存在use关键字,则冒号必须紧跟use列表结束括号,两个字符之间不能有空格。
闭包声明如下所示。请注意括号,逗号,空格和花括号的位置:
<?php
$closureWithArgs = function ($arg1, $arg2) {
// body
};
$closureWithArgsAndVars = function ($arg1, $arg2) use ($var1, $var2) {
// body
};
$closureWithArgsVarsAndReturn = function ($arg1, $arg2) use ($var1, $var2): bool {
// body
};