psr 规范
引言: PSR 是 PHP Standard Recommendations 的简写, 由 PHP FIG 组织制定的 PHP 规范, 是 PHP 开发的实践标准. 这些规范的目的是: 通过框架作者或者框架的代表之间讨论, 以最低程度的限制, 制定一个协作标准, 各个框架遵循统一的编码规范, 避免各家自行发展的风格阻碍了 PHP 的发展, 解决这个程序设计师由来已久的困扰. 截止到笔者文章 psr 在用的共 11 套规范, 下面介绍了其中四个和已经弃用的 psr0 规范.
PSR-0 (Autoloading Standard) 自动加载标准 (2014 年 10 月 21 起被官方弃用 由 psr4 替代)
PSR-1 (Basic Coding Standard) 基础编码标准
PSR-2 (Coding Style Guide) 编码风格向导
PSR-3 (Logger Interface) 日志接口
PSR-4 (Improved Autoloading) 自动加载的在用版本.
# 注: 另有 psr6(缓存接口规范)psr7(HTTP 消息接口规范)psr11,psr13,psr15,psr16,psr17 本文不做介绍
附上官网地址 https://www.php-fig.org/psr/
psr0(官方已废弃)
自动加载标准
一个完全合格的 namespace 和 class 必须符合这样的结构:"<Vendor Name>(<Namespace>)*<Class Name>"
每个 namespace 必须有一个顶层的 namespace("Vendor Name" 提供者名字)
每个 namespace 可以有多个子 namespace
当从文件系统中加载时, 每个 namespace 的分隔符 (/) 要转换成 DIRECTORY_SEPARATOR(操作系统路径分隔符)
在类名中, 每个下划线要转换成 DIRECTORY_SEPARATOR(操作系统路径分隔符). 在 namespace 中, 下划线是没有 (特殊) 意义的.
当从文件系统中载入时, 合格的 namespace 和 class 一定是以 .php 结尾的 verdor name,namespaces,class 名可以由大小写字母组合而成(大小写敏感的)
注: 因为已经废弃, 这里不再多做介绍
psr4
这里先介绍 psr4, 好和上面的 psr0 作对比, 因为他是升级版的 PSR-0 自动加载规范
PSR4 是关于由文件路径自动载入对应的类的相关规范, 本规范是可互操作的. 可以作为任一自动 (包括 PSR-0) 载入规范的补充, 此外, PSR4 还包括自动载入的类对应的文件存放路径规范.
此处的 "类" 泛指所有的 class 类, 接口, traits 可复用代码块以及其他类似结构.
一个完整的类名需要具有以下结构
<命名空间>(<子命名空间>)*<类名>
完整的类名必须要有一个顶级命名空间, 被称为 "Vendor namespace"
完整的类名可以有一个或多个子命名空间
完整的类名必须有一个最终的类名
完整的类名中任意一部分中的下划线都是没有特殊意义的
完整的类名可以由任意大小写字母组成
所有类名都必须是大小写敏感的
当根据完整的类名载入相应的文件
完整的类名中, 去掉最前面的命名空间分隔符, 前面连续的一个或多个命名空间和子命名空间, 作为 "命名空间前缀", 其必须至少对应一个基础目录.
紧接命名空间前缀后的子命名空间必须与相对应的 "基础目录" 的子目录相匹配, 其中的命名空间分隔符作为目录分割符
末尾的类名必须与对应的. php 为后缀的文件同名
自动加载器 (autoloader) 的实现一定不能抛出异常, 一定不能触发任一级别的错误信息以及不应该有返回值.
例如:
- # 完整的类名为
- \a\b\c\Log
- # 命名空间前缀前缀为:
- a\b
- # 前缀对应的基础目录为:
- ./vendor
- # 文件实际目录为:
- ./vendor/c/Log.php
- # 注: 即把去掉最前面的命名空间分隔符后的 a\b\c\Log 中的命名空间前缀替换成基础目录, 然后把命名空间分隔符替换成目录分隔符, 并把文件名补上后缀 .php .
PSR-4 和 PSR-0 最大的区别是对下划线 (underscore) 的定义不同. PSR-4 中, 在类名中使用下划线没有任何特殊含义. 而 PSR-0 则规定类名中的下划线_会被转化成目录分隔符.
psr1 基本代码规范
PHP 源文件必须只使用 <?php 和 <?= 这两种标签.(php 标记有多种方式)
源文件中 php 代码的编码格式必须是不带字节顺序标记 (BOM) 的 UTF-8.(注: PHP 在设计时就没有考虑 BOM 的问题, 也就是说他不会忽略 UTF-8 编码的文件开头 BOM 的那三个字节导致出现奇怪的错误.)
一个源文件建议只用来做声明 (类(class), 函数(function), 常量(constant) 等)或者只用来做一些引起从属效应的操作(例如: 输出信息, 包含文件, 修改. ini 配置等), 但不能同时使用两者.
注:"从属效应"(side effects)一词的意思是, 仅仅通过包含文件, 不直接声明类, 函数和常量等, 而执行的逻辑操作. "从属效应" 包含却不仅限于: 生成输出, 直接的 require 或 include, 连接外部服务, 修改 ini 配置, 抛出错误或异常, 修改全局或静态变量, 读或写文件等. 这个很多人都不遵守, 但是基本上所有框架里都不会把修改. ini 配置和声明类或函数放到一起, 比如框架 index.php 入口文件只定义宏常量和修改. ini 等
命名空间 (namespace) 和类(class) 必须遵守 PSR0 或 psr4 标准.
类名 (class name) 必须使用骆驼式(StudlyCaps) 写法(注: StudlyCaps 即首字母大写驼峰式).
类 (class) 中的常量必须只由大写字母和下划线组成.
方法名 (method name) 必须使用驼峰式(cameCase) 写法.
psr2 代码风格
代码必须遵循 PSR-1 中的编码规范
代码必须使用四个空格符而不是 tab 键进行缩进.
每行的字符数应该软性保持在 80 个内, 理论上不可多于 120 个, 但一定不能硬性限制
每个 namespace 命名空间声明语句和 use 语句块后面, 必须插入一个空白行
类的开始花括号必须在类声明后自成一行, 结束花名号也必须在类主体后自成一行
函数的开始花括号必须在函数声明后自成一行, 结束花名号也必须在函数主体后自成一行
类的属性和方法必须添加访问修饰符(private protected 以及 public),abstract 以及 final 必须声明在访问修饰符之前, 而 static 必须声明在访问修饰符之后.
控制结构的关键字后必须要有一个空格符, 而调用方法或函数时则一定不能有.
控制结构的开始花括号必须写在声明的同一行, 而结束花括号必须写在主体后自成一行.
控制结构的开始左括号后和结束右括号前, 都一定不能有空格符.
示例代码
- <?php
- namespace Vendor\Package;
- use FooInterface;
- use BarClass as Bar;
- use OtherVendor\OtherPackage\BazClass;
- class Foo extends Bar implements FooInterface
- {
- public function sampleMethod($a, $b = null)
- {
- if ($a === $b) {
- bar();
- } elseif ($a> $b) {
- $foo->bar($arg1);
- } else {
- BazClass::bar($arg2, $arg3);
- }
- }
- final public static function bar()
- {
- // method body
- }
- }
通常还有以下几点需要注意
对于 php 文件:
所有的 php 文件都必须以 Unix LF(换行)作为结束符
所有的 php 文件都必须以一个单独的空行结尾
纯 PHP 代码源文件的关闭标签?>必须省略.
关键字和 True/False/Null
php 的关键字, 必须小写
php 产量 true ,false,null 也必须小写
命名空间
命名空间 (namespace) 的声明后面必须有一行空行.
所有的导入 (use) 声明必须放在命名空间 (namespace) 声明的下面.
一句声明中, 必须只有一个导入 (use) 关键字.
在导入 (use) 声明代码块后面必须有一行空行.
例如:
- <?php
- namespace Vendor\Package;
- use FooClass;
- use BarClass as Bar;
- use OtherVendor\OtherPackage\BazClass;
- // ... additional PHP code ...
控制结构
if ,else ,elseif ,while ,do while ,switch case ,for, foreach,try catch 等. 这一类的写法规范也是经常容易出现问题的, 也要规范一下. 在关键字和后面的判断条件中间应该加空格, 在判断条件和左大括号之间也要加空格.
psr3 日志接口规范
本规范的主要目的, 是为了让类库以简单通用的方式接收一个 Psr\Log\LoggerInterface 对象, 来记录日志信息. 框架以及 CMS 内容管理系统如有需要, 可以扩展接口以用于它们自己的
目的, 但须遵循本规范, 才能在使用第三方的类库文件时, 保证日志接口仍能正常对接.
LoggerInterface 接口对外定义了八个方法, 分别用来记录 RFC 5424 中定义的八个级别: debug,info,notice,warning,error,critical,alert,emergency.
第九个方法 - log, 其第一个参数为日志的等级, 可使用一个预定义好的等级常量作为参数来调用此方法, 必须与直接调用以上八个方法具有相同的效果. 如果传入的等级常量参数没有预先定义, 就必须抛出 Psr\Log\InvalidArgumentException 类型的异常, 在不确定的情况下, 使用者不该使用未支持的等级常量来调用此方法. 如果有用过 monolog 就应该对这里有较深的理解.
例如, 日志等级可以定义如下:
- <?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';
- }
日志这里想必大家接触的也不多, 如果想了解可以看一看 monolog 的源码.
本文到此就结束, 希望大家 get 到了想要的知识.
来源: https://www.cnblogs.com/vinter/p/9505154.html