PSR是由FIG这个组织制定的PHP规范,官网是 www.php-fig.org
PSR-0:自动加载
PSR-0 是FIG出的第一套规范,主要是制定了一些自动加载标准。不过 PSR-0 已经被标记为 Deprecated(已弃用),自动加载的新规范为 PSR-4。
PSR-1:基本代码规范
PSR-1 规范包括了一些为确保共享PHP代码之间高水平的技术互操作性所需的标准编码元素。
- PHP源文件必须只使用
<?php
和<?=
这两种标签。 - 源文件中php代码的编码格式必须是不带字节顺序标记(BOM)的
UTF-8
。 - 一个源文件建议只用来做声明(类、函数、常量等)或者只用来做一些引起副作用的操作(例如:输出信息、修改.ini配置等),但不建议同时做这两件事。
- 命名空间(namespace)和类(class)必须遵守PSR-0/PSR-4自动加载标准。
- 类名必须使用骆驼式(StudlyCaps)写法 (注:驼峰式的一种变种)。
- 类中的常量必须只由大写字母和下划线组成。
- 方法名必须使用驼峰式(camelCase)写法。
PSR-2:代码样式
PSR-2 是对 PSR-1 规范的补充和扩展,主要是用于约束代码风格,多人协作开发时统一代码风格是很重要的。
- 代码必须遵循 PSR-1 的基本代码规范。
- 必须使用4个空格来缩进,不能使用Tab键。
- 一行代码的长度不得有硬性限制,软限制必须是120字符,建议是最多80个字符。
- 在
namespace
声明之后必须有一个空行,并且在use
声明块之后必须有一个空行。 - 声明类、方法的花括号必须单独写在一行。
- 必须在所有属性和方法上声明可见性(public/protected/private),
abstract
和final
必须在可见性之前声明,static
必须在可见性之后声明。 - 控制结构关键字,就是 if else while switch foreach等,后面必须要有一个空格。
- 控制结构的左花括号必须与控制关键字在同一行,右花括号必须单独写在一行。
PSR-3:日志接口
PSR-3 规范描述的是日志库的通用接口,主要目标是允许库以简单和通用的方式接收Psr\Log\LoggerInterface
对象并将日志写入其中。
Basics
- 接口
LoggerInterface
暴露了8个方法,用于写8种级别的日志,包括debug
,info
,notice
,warning
,error
,critical
,alert
,emergency
。 - 第九个方法
log($level, $message, $context)
,根据$level
参数调用特定日志级别的方法,如果传入的日志 level 不存在,必须抛出一个Psr\Log\InvalidArgumentException
异常。
Message
- 每个方法都接受一个字符串作为消息,或一个带有
__toString()
方法的对象。实现者可以对该入参进行特殊处理,最后必须都转换为字符串。 $message
中可以包含占位符,实现时可以用$context
数组中的值替换。
- 占位符名称必须是
$context
数组中的键; - 占位符必须用花括号
{}
括起来,占位符名称与花括号之间不能再有空格; - 占位符名字应该只由大小写字母、数字、下划线、点组成。
- 占位符名称必须是
Context
- 每个方法都接受一个
$context
数组作为上下文数据,该数组可以包含任何内容。
<?php
namespace Psr\Log;
/**
* Describes a logger instance
*
* The message MUST be a string or object implementing __toString().
*
* The message MAY contain placeholders in the form: {foo} where foo
* will be replaced by the context data in key "foo".
*
* The context array can contain arbitrary data, the only assumption that
* can be made by implementors is that if an Exception instance is given
* to produce a stack trace, it MUST be in a key named "exception".
*
*/
interface LoggerInterface
{
public function emergency($message, array $context = array());
public function alert($message, array $context = array());
public function critical($message, array $context = array());
public function error($message, array $context = array());
public function warning($message, array $context = array());
public function notice($message, array $context = array());
public function info($message, array $context = array());
public function debug($message, array $context = array());
public function log($level, $message, array $context = array());
}
更多请查看PSR-3规范。
PSR-4:自动加载
PSR-4 规范了如何从文件路径自动加载类,同时规范了自动加载文件的位置。
- 术语
class
指的是类,接口,trait,和其他类似结构。 - 一个完全限定类名具有以下形式:
\<NamespaceName>(\<SubNamespaceNames>)*\<ClassName>
- 必须具有顶级命名空间,也称为vendor namespace;
- 可能具有一个或多个子命名空间;
- 下划线(_)没有任何特殊含义;
- 必须区分大小写。
- 加载一个完全限定类名对应的文件时:
- 在完全限定类名中, 不包含前面的命名空间分隔符,由一个顶级命名空间与一个或多个二级命名空间名称组成的命名空间前缀,对应于至少一个“base目录”;
- 在命名空间前缀后面的二级命名空间名称对应于“base目录”中的一个子目录, 这里命名空间分隔符表示目录分隔符。子目录名称必须匹配到二级命名空间名称;
- 最后的类名对应于以
.php
为后缀的文件名,且大小写也要相同。
- 自动加载的实现一定不能抛出异常,一定不能引发任何级别的错误, 并且不应该有返回值。
举例
完全限定类名 | 命名空间前缀 | Base目录 | 最终文件路径 |
---|---|---|---|
\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 |