PHP - PSR
2021-12-02 12:07:21 5 举报
AI智能生成
Process on 上没有 PHP PSR 。我就先发布一个吧
作者其他创作
大纲/内容
国内中文翻译
国际网站
==> PHP Standards Recommendation
PHP 标准建议
PHP 标准建议
出处: PHP-FIG:
PHP FIG 组织制定的 PHP 规范 ;是 PHP 开发的实践标准
PHP-FIG : PHP Framework Interop Group
php 框架共性小组
成员:php 框架的成员
具体规范
PSR0
已废弃
一个标准的命名空间与类名称的定义必须符合以下结构:\<Vendor Name><Namespace>*(ClassName)
其中Vendor Name 为每个命名空间都必须要有的一个顶级命名空间名
需要的话,每个命名空间下可以拥有多个子命名空间
当根据完整的命名空间名从文件系统中载入类文件时,每个命名空间之间的分隔符都会被转换成文件夹路径分隔符
类命名中的每个_字符也会被转换成文件夹路径分隔符,而命名空间中的_字符则是无特殊含义的。
当从文件系统中载入标准的命名空间或类时,都将添加.php为目标文件后缀
组织名称(Vendor Name)、命名空间(Namespace)以及类的名称(Class Name)可由任意大小写字母组成。
PSR1
基础编码规范
1、概览
PHP 代码文件开始标签
必须
以 <?php 或 <?= 标签开始
PHP 代码文件编码
必须
不带 BOM 的 UTF-8
PHP 代码中 应该 声明任一标志(类、函数、常量等),或引起副作用(如果一个函数修改了自己范围之外的资源,那就叫做有副作用,如:生成输出以及修改 .ini 配置文件等),但是不应该二者都有;
没看懂。。。。
命名空间
必须
PSR-4 自动加载规范
类的命名
必须 遵循
大写开头的驼峰命名规范
类中的常量所有字母
必须
大写
单词间用下划线分隔
方法名称
必须 符合
小写开头驼峰命名规范
2、文件
PHP 代码文件开始标签
必须
以 <?php 或 <?= 标签开始
PHP 代码文件编码
必须
不带 BOM 的 UTF-8
2.3. 副作用
真没看懂
3、命名空间和类
命名空间
必须
PSR-4 自动加载规范
意味着每个类都独立为一个文件
并且至少在一个层次的命名空间内
4、类的常量、属性和方法
「类」 ==》指代
类、接口以及可复用代码块(traits
常量
类的常量中所有字母都 必须 大写,词间以下划线分隔
namespace Vendor\Model;
class Foo
{
const VERSION = '1.0';
const DATE_APPROVED = '2012-06-01';
}
class Foo
{
const VERSION = '1.0';
const DATE_APPROVED = '2012-06-01';
}
类属性
三种格式
大写开头的驼峰式 ($StudlyCaps)
小写开头的驼峰式 ($camelCase)
下划线分隔式 ($under_score)
应该
一定范围内 统一: 团队 、包 、类、方法
方法
小写开头驼峰命名规范
camelCase()
PSR2
已废弃
代码必须遵循PSR-1中的编码规范
代码必须使用四个空格符而不是tab键进行缩进
每行的字符数应该软性保持在80个内,理论上不可多于120个,但一定不能由硬性限制
每个namespace命名空间声明语句和use声明语句块后面,必须插入一个空白行
类的开始花名号({)必须在函数声明后自成一行,结束花名号(})也必须在函数主体后自成一行
类的属性和方法必须添加访问修饰符(private protected以及public),abstract以及final必须声明在访问修饰符之前,而static必须声明在访问修饰符之后。
控制结构的关键字后必须要有一个空格符,而调用方法或函数时则一定不能有。
控制结构的开始花括号({)必须写在声明的同一行,而结束花括号(})必须写在主体后自成一行。
控制结构的开始左括号后和结束右括号前,都一定不能有空格符
PSR3
日志接口规范
日志类库的通用接口规范
1规范
1.1 基本规范
Psr\Log\LoggerInterface
八个等级的日志
debug
info
notice
warning
error
critical
alert
emergency
1.2 消息
1.1 中每个方法
接收
字符串类型 or 有 __toString() 方法的对象
记录信息参数
记录信息参数
可以
携带占位符
实现者 可以
上下文
替换成相应的值
占位符
必须
上下文数组中的键名保持一致
必须 由一个左花括号 { 以及一个右括号 }
花括号与名称之间 一定不可有空格符
1.3 上下文
记录函数
接收
上下文数组参数
它 可以 装载任何信息
1.4 助手类和接口
Psr\Log\AbstractLogger
类使得只需继承它和实现其中的 log 方法,就能够很轻易地实现 LoggerInterface 接口,而另外八个方法就能够把记录信息和上下文信息传给它
Psr\Log\LoggerTrait
Psr\Log\NullLogger
Psr\Log\LoggerAwareInterface
Psr\Log\LoggerAwareTrait
只需通过它提供的 $this->logger,就可以轻松地实现等同的接口
Psr\Log\LogLevel
2. 包
psr/log
3. Psr\Log\LoggerInterface
<?php
namespace Psr\Log;
/**
* 描述一个日志记录器实例
*
* 该消息必须实现一个__toString()的字符串或者对象.
*
* 该消息可能包含以下形式的占位符: {foo}
* foo 将会被关键词 "foo"中的上下文数据替换.
*
* 上下文数组可以包含任意数据, 我们只能假设代码实现者
* 如果给出一个生成堆栈跟踪的异常实例, 那么它的键名
* 必须为 "exception"。
*
* 请前往 https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md
* 查看完整的接口规范.
*/
interface LoggerInterface
{
/**
* 系统无法使用。
*
* @param string $message
* @param array $context
* @return void
*/
public function emergency($message, array $context = array());
/**
* 必须立即采取行动。
*
* 例如: 整个网站宕机了,数据库挂了,等等。 这应该
* 发送短信通知警告你.
*
* @param string $message
* @param array $context
* @return void
*/
public function alert($message, array $context = array());
/**
* 临界条件。
*
* 例如: 应用组件不可用,意外的异常。
*
* @param string $message
* @param array $context
* @return void
*/
public function critical($message, array $context = array());
/**
* 运行时错误不需要马上处理,
* 但通常应该被记录和监控。
*
* @param string $message
* @param array $context
* @return void
*/
public function error($message, array $context = array());
/**
* 例外事件不是错误。
*
* 例如: 使用过时的API,API使用不当,不合理的东西不一定是错误。
*
* @param string $message
* @param array $context
* @return void
*/
public function warning($message, array $context = array());
/**
* 正常但重要的事件.
*
* @param string $message
* @param array $context
* @return void
*/
public function notice($message, array $context = array());
/**
* 有趣的事件.
*
* 例如: 用户登录,SQL日志。
*
* @param string $message
* @param array $context
* @return void
*/
public function info($message, array $context = array());
/**
* 详细的调试信息。
*
* @param string $message
* @param array $context
* @return void
*/
public function debug($message, array $context = array());
/**
* 可任意级别记录日志。
*
* @param mixed $level
* @param string $message
* @param array $context
* @return void
*/
public function log($level, $message, array $context = array());
}
4. Psr\Log\LoggerAwareInterface
<?php
namespace Psr\Log;
/**
* logger-aware 定义实例
*/
interface LoggerAwareInterface
{
/**
* 设置一个日志记录实例
*
* @param LoggerInterface $logger
* @return void
*/
public function setLogger(LoggerInterface $logger);
}
5. Psr\Log\LogLevel
<?php
namespace Psr\Log;
/**
* 日志等级常量定义
*/
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';
}
PSR4
自动加载规范
PSR0 的补充
PSR0
Horde/PEAR 约定为准
1、将所有的 PHP 类文件放在一个主目录中
2、 下划线连接的字符串
来表示命名空间
Composer
多目录
因 Composer 而来
PHP的包管理系统Composer已经支持PSR-4,同时也允许在composer.json中定义不同的prefix使用不同的自动加载机制。
面向 - 包的自动加载
具体内容
1、术语“类”指代类、接口、trait 以及其它类似的结构。
2、一个完全限定(fully qualified)类名形如:\<NamespaceName>(\<SubNamespaceNames>)*\<ClassName>。
1、完全限定类名必须包含一个顶级命名空间名,这也被称为“开发商命名空间”。
2、完全限定类名可以包含一个或多个子命名空间名称
3、完全限定类名必须以一个类名结束
4、完全限定类名各部分中的下划线没有任何特殊的含义
5、完全限定类名中的字母可以使用任意大小写组合
6、所有类名必须以大小写敏感的方式被引用
3、当根据完全限定类名加载对应的文件时:
1、由最开始的命名空间开始,连续的一个或多个命名空间组成的序列,不包括最前面的命名空间分隔符,在这个完全限定类名中(这个序列称为“命名空间前缀,namespace prefix”)对应了至少一个“基础目录”
2、“命名空间前缀”之后相邻的子命名空间,对应“基础目录”中的子目录,命名空间分隔符对应目录分隔符。子目录名必须与子命名空间名大小写匹配
3、结尾的类名对应一个以 .php 最为后缀的文件名。
4、文件名必须与类名大小写匹配
4、自动加载机制的具体实现不得抛出异常,不得产生任何等级的错误,且不应该有返回值。
使用==》
https://blog.csdn.net/qq_29920751/article/details/87630803
命名空间前缀
跟 基础目录绑定
https://segmentfault.com/a/1190000004649329?utm_source=sf-similar-article
PSR-5 PHPDoc 标准(未通过)
PSR-6 缓存接口规范
目标是
创建一套通用的接口规范,能够让开发人员整合到现有框架和系统,而不需要去开发框架专属的适配器类。
定义
调用类库 (Calling Library)
实现类库 (Implementing Library)
实现类库 必须 提供 PHP 类来实现
Cache\CacheItemPoolInterface
Cache\CacheItemInterface
生存时间值 (TTL - Time To Live)
以秒为单位的整数值
过期时间 (Expiration)
键 (KEY)
命中 (Hit)
未命中 (Miss)
延迟 (Deferred)
当调用类库调用 commit() 方法时,所有的延迟缓存都 必须 做持久化
数据
Strings
Integers
Floats
Boolean
Null
Arrays
Object
所有对象支持无损的序列化和反序列化,比如 $o == unserialize(serialize($o))
主要概念
缓存池 Pool
缓存项 Items
错误处理#
接口
CacheItemInterface
CacheItemPoolInterface
CacheException
PSR-7 HTTP 消息接口规范
1. 详细描述
1.1 消息
Psr\Http\Message\RequestInterface
Psr\Http\Message\ResponseInterface
命名空间
Psr\Http\Message
继承于 : Psr\Http\Message\MessageInterface
1.2 HTTP 请求头信息
大小写不敏感的字段名字#
$message = $message->withHeader('foo', 'bar');
echo $message->getHeaderLine('foo');
// 输出: bar
echo $message->getHeaderLine('FOO');
// 输出: bar
$message = $message->withHeader('fOO', 'baz');
echo $message->getHeaderLine('foo');
// 输出: baz
对应多条数组的头信息#
$message = $message
->withHeader('foo', 'bar')
->withAddedHeader('foo', 'baz');
$header = $message->getHeaderLine('foo');
// $header 包含: 'bar, baz'
$header = $message->getHeader('foo');
// ['bar', 'baz']
主机信息#
1.3 数据流
StreamInterface
isReadable()
isWritable()
isSeekable()
__toString()
1.4 请求目标和 URI
1.5 服务端请求
RequestInterface
$_COOKIE
$_GET
$_POST
对通过 urlencode 编码提交的 HTTP POST 信息进化反序列化并提供了简化的访问方式
$_FILES
$_SERVER
提供了 CGI/SAPI 环境变量的访问,这些变量通常包括请求方法、请求 scheme、请求 URI 和报头。
ServerRequestInterface
继承于 RequestInterface
1.6 文件上传
ServerRequestInterface
UploadedFileInterface
2. 扩展包
上面讨论的接口和类库已经整合成为扩展包:psr/http-message。
https://packagist.org/packages/psr/http-message
3. 接口
3.1 Psr\Http\Message\MessageInterface
3.2 Psr\Http\Message\RequestInterface
。。。。。
PSR-8 Huggable 接口(未通过)
PSR-9 项目安全问题公示(未通过)
PSR-10 项目安全上报方法(未通过)
PSR-11 容器接口
Laravel 中有使用 容器
ContainerInterface
目的是为了标准化框架或类库如何使用容器来获取对象和参数。(本文其它部分称之为 实体 )。
1. 规范
1.1 基础知识
1.1.1 实体标识符
用来唯一标识容器里的一个对象
调用者不应该通过语义去猜测它具有的结构
1.1.2 容器的方法
Psr\Container\ContainerInterface
get
has
1.2 异常
Psr\Container\ContainerExceptionInterface
通过 get 方法获取一个容器中不存在实体标识符时必须抛出 Psr\Container\NotFoundExceptionInterface 接口的异常实现类
1.3 推荐用法
用户 不应该 将容器作为参数传入对象然后在对象中通过容器获得对象的依赖。这样是把容器当作 服务定位器 使用,而服务定位器是一个不受欢迎的模式。
2. 包
psr/container 包中提供了上面提到的接口和相关异常类
https://packagist.org/packages/psr/container
3. 接口
Psr\Container\ContainerInterface
Psr\Container\ContainerExceptionInterface
Psr\Container\NotFoundExceptionInterface
PSR-11 容器接口 - 说明文档
所有的 DI 容器都是为了解决一个相同的问题:给应用提供一种方法来查找、获取配置的对象(通常是应用需要的服务)。
通过标准化从容器中获取对象的方法,可以让使用 PSR 容器规范的框架和库可以选择使用任何与之兼容的容器类。这样就能让终端用户根据自己的喜好来选择他们自己的容器。
容器下面的两个用法
配置对象实例
获取对象实例
通常框架使用容器来获取对象构建应用,而终端用户倾向于使用它来配置对象
PSR 规范只关注怎么从容器中获取对象。
对象的命名
两种命名策略
实体标识符为类名或者接口名(大多数可以自动装载的框架这么用)
实体标识符为一个普通的名称(更接近于变量名),大多数依赖配置的框架这样使用。
4. 推荐用法:容器 PSR 和服务定位器
// 这是不推荐的,容器被当作服务定位器来使用了
class BadExample
{
public function __construct(ContainerInterface $container)
{
$this->db = $container->get('db');
}
}
// 可以考虑使用直接注入的方式,替代上面的方式
class GoodExample
{
public function __construct($db)
{
$this->db = $db;
}
}
// 然后,你可以使用容器来将 $db 对象注入到 $goodExample 类中。
ontainerInterface: +8
ProviderInterface: +2
LocatorInterface: 0
ReadableContainerInterface: -5
ServiceLocatorInterface: -6
ObjectFactory: -6
ObjectStore: -8
ConsumerInterface: -9
————————————————
原文作者:PHP 技术论坛文档:《PHP PSR 标准规范()》
转自链接:https://learnku.com/docs/psr/psr-11-container-meta/1622
版权声明:翻译文档著作权归译者和 LearnKu 社区所有。转载请保留原文链接
7.2. 参数 $id 的类型
PSR-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()
{
// 方法内容
}
}
2. 总则
2.1 基本编码标准
代码必须遵循 [PSR-1] 中列出的所有规则
PSR-1 中的术语 ‘StudlyCaps’ 必须解释为 PascalCase (帕斯卡命名法:大驼峰式命名法),其中每个单词的第一个字母大写,包括第一个字母
2.2 文件
PHP 文件只能使用 Unix LF (换行符) 结尾
PHP 文件都必须以非空行结尾,以一个 LF 结尾
在仅包含 PHP 代码的文件中,必须省略结尾的 ?> 标记
2.3 代码行
行长度不得有硬限制。
行长度的软限制必须为 120 个字符。
行的长度不应超过 80 个字符;超过该长度的行应拆分为多个后续行,每个行的长度不应超过 80 个字符。
行尾不能有尾随空格。
可以添加空行以提高可读性并指示相关的代码块,除非明确禁止。
每行不能有多个语句。
2.4 缩进#
每个缩进级别使用 4 个空格的缩进,并且不能使用缩进标签
2.5 关键词和类型
关键词和类型
必须
小写
未来版本
必须
小写
类型关键字
必须
缩写
使用 bool 而不是 boolean,使用 int 而不是 integer 等等
3. 声明、命名空间以及导入
PHP 文件开始标签: <?php。
文件级文档块。
一个或多个声明语句。
命名空间声明语句。
一个或多个基于类的 use 声明语句。
一个或多个基于方法的 use 声明语句。
一个或多个基于常量的 use 声明语句。
其余代码。
————————————————
原文作者:PHP 技术论坛文档:《PHP PSR 标准规范()》
转自链接:https://learnku.com/docs/psr/psr-12-extended-coding-style-guide/5789
版权声明:翻译文档著作权归译者和 LearnKu 社区所有。转载请保留原文链接
深度不能超过两层的复合名称空间
4. 类,属性,和方法
实例化一个类时,后面的圆括号 必须 写出
new Foo();
4.1 继承和实现
关键字 继承 和 实现 必须 在类名的同一行声明
类的左花括号 必须 另起一行;右花括号 必须 跟在类主体的下一行。
类的左花括号 必须 独自成行,且 不得 在其上一行或下一行存在空行。
右花括号 必须 独自成行,且 不得 在其上一行存在空行。
<?php
namespace Vendor\Package;
use FooClass;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;
class ClassName extends ParentClass implements \ArrayAccess, \Countable
{
// 常量,属性,方法
}
如果有接口, 实现 接口和 继承父类 可以 分为多行,前者每行需缩进一次。当这么做时,第一个接口 必须 写在下一行,且每行 必须 只能写一个接口。
<?php
namespace Vendor\Package;
use FooClass;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;
class ClassName extends ParentClass implements
\ArrayAccess,
\Countable,
\Serializable
{
// 常量,属性,方法
}
4.2 使用 trait
在类里面用于实现 trait 的关键字 use 必须 在左花括号的下一行声明。
<?php
namespace Vendor\Package;
use Vendor\Package\FirstTrait;
class ClassName
{
use FirstTrait;
}
每个导入类的 trait 必须 每行一个包含声明,且每个包含声明 必须 有其 use 导入语句。
<?php
namespace Vendor\Package;
use Vendor\Package\FirstTrait;
use Vendor\Package\SecondTrait;
use Vendor\Package\ThirdTrait;
class ClassName
{
use FirstTrait;
use SecondTrait;
use ThirdTrait;
}
在类文件中,如果在使用’use Trait’之后没有其他内容了 ,类名右大括号必须另起一行。
<?php
namespace Vendor\Package;
use Vendor\Package\FirstTrait;
class ClassName
{
use FirstTrait;
}
如有其他内容,两者之间需空一行。
<?php
namespace Vendor\Package;
use Vendor\Package\FirstTrait;
class ClassName
{
use FirstTrait;
private $property;
}
当使用’ insteadof ‘和’ as ‘运算符时,它们必须如图所示使用,注意缩进、间距和另起一行。
<?php
class Talker
{
use A, B, C {
B::smallTalk insteadof A;
A::bigTalk insteadof C;
C::mediumTalk as FooBar;
}
}
4.3 属性和常量
属性 必须 声明可见性
关键字 var 不得 用于声明属性。
每条声明语句 不得 声明多于一个属性。
属性名 不得 用单个下划线开头表明其受保护的或私有的可见性。也就是说,一个下划线开头显然是没有意义的。
类型声明和属性名之间 必须 有一个空格。
————————————————
原文作者:PHP 技术论坛文档:《PHP PSR 标准规范()》
转自链接:https://learnku.com/docs/psr/psr-12-extended-coding-style-guide/5789
版权声明:翻译文档著作权归译者和 LearnKu 社区所有。转载请保留原文链接
<?php
namespace Vendor\Package;
class ClassName
{
public $foo = null;
public static int $bar = 0;
}
4.4 方法和函数
方法命名后面 一定不可 使用空格
方法 必须 事先声明类型
4.5 方法和函数参数#
在参数列表中, 不得 在每个逗号前存在空格,且 必须 在每个逗号后有一个空格。
方法和函数中带有默认值的参数 必须 放在参数列表的最后。
参数列表 可以 分为多行
<?php
namespace Vendor\Package;
class ClassName
{
public function aVeryLongMethodName(
ClassTypeHint $arg1,
&$arg2,
array $arg3 = []
) {
// 方法主体
}
}
定义一个返回值类型声明时,冒号后面的类型声明 必须 用空格符隔开
冒号和声明 必须 在同一行,且跟参数列表后的结束括号之间没有空格。
在可空类型声明中,问号和类型声明之间不能有空格。
5. 流程控制
流程控制关键词之后 必须 要有一个空格
左括号后面 不能 有空格
右括号前面 不能 有空格
右括号与左大括号之间 必须 要有一个空格
流程主体 必须 要缩进一次
流程主体 必须 在左大括号之后另起一行
右大括号 必须 在流程主体之后另起一行
————————————————
原文作者:PHP 技术论坛文档:《PHP PSR 标准规范()》
转自链接:https://learnku.com/docs/psr/psr-12-extended-coding-style-guide/5789#a4a88b
版权声明:翻译文档著作权归译者和 LearnKu 社区所有。转载请保留原文链接
5.1 if, elseif, else
5.2 switch, case
子主题
5.3 while, do while
子主题
子主题
5.4 for
子主题
子主题
子主题
6. 运算符
递增 / 递减运算符和操作数之间 不得 有任何空格
类型转换运算符的圆括号内部 不得 有任何空格:
二进制 算术,比较,赋值,按位,逻辑、字符串和类型运算符必须在前后跟至少一个空格:
7. 闭包(Closures
闭包声明时必须在 function 关键字后留有 1 个空格,并且在 use 关键字前后各留有 1 个空格
子主题
8. 匿名类
子主题
PSR-17 HTTP 工厂
PSR18
0 条评论
下一页