[PHP之道]代码约束摘要


PSR 是 PHP Standard Recommendations 的简写,由 PHP FIG 组织制定的 PHP 规范,是 PHP 开发的实践标准。

基础编码规范 PSR-1

  • PHP代码文件 必须不带 BOMUTF-8 编码;

  • 类的命名 必须 遵循 StudlyCaps 大写开头的驼峰命名规范;

  • 类中的 常量所有字母必须 大写,单词间用下划线分隔;

  • 方法名称 必须 符合 camelCase 式的小写开头驼峰命名规范。

  • 一份 PHP 文件中 应该 要不就只定义新的声明,如类、函数或常量等不产生 副作用 的操作,要不就只书写会产生 副作用 的逻辑操作,但 不该 同时具有两者。

反例:

<?php

// 「副作用」:修改 ini 配置
ini_set('error_reporting', E_ALL);

// 「副作用」:引入文件
include "file.php";

// 「副作用」:生成输出
echo "<html>\n";

// 声明函数
function foo()
&#123;
    // 函数主体部分
&#125;

编码风格规范 PSR-2

  • 所有PHP文件 必须 以一个空白行作为结束。

  • 代码 必须 使用 4个空格符 的缩进,一定不可tab键

  • PHP所有 关键字 必须 全部 小写。常量 truefalsenull必须 全部小写。

  • 关键词 extends 和 implements 必须 写在类名称的同一行。

  • 类的开始花括号({) 必须 写在函数声明后自成一行,结束花括号(})也 必须 写在函数主体后自成一行。

  • 方法的开始花括号({) 必须 写在函数声明后自成一行,结束花括号(})也 必须 写在函数主体后自成一行。

  • 类的属性和方法 必须 添加访问修饰符(privateprotected 以及 public),abstract 以及 final 必须 声明在访问修饰符之前,而 static 必须 声明在访问修饰符之后。

  • 所有方法都 必须 添加访问修饰符。

  • 方法的参数, 有默认值的参数,必须 放到参数列表的末尾。

示例:

<?php

namespace Vendor\Package;

use FooInterface;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;

class Foo extends Bar implements FooInterface
&#123;
    public function sampleFunction($a, $b = null)
    &#123;
        if ($a === $b) &#123;
            bar();
        &#125; elseif ($a > $b) &#123;
            $foo->bar($arg1);
        &#125; else &#123;
            BazClass::bar($arg2, $arg3);
        &#125;
    &#125;

    final public static function bar()
    &#123;
        // 方法的内容
    &#125;
&#125;

日志接口规范

  • LoggerInterface 接口对外定义了八个方法,分别用来记录 RFC 5424 中定义的八个等级的日志:debug、 info、 notice、 warning、 error、 critical、 alert 以及 emergency
  • 记录信息参数 可以 携带占位符,实现者 可以 根据上下文将其它替换成相应的值。
  • 每个记录函数都接受一个上下文数组参数,用来装载字符串类型无法表示的信息。 一定不可 抛出异常,或产生PHP出错、警告或提醒信息(error、warning、notice)。
  • 如需通过上下文参数传入了一个 Exception 对象,必须 以 exception 作为键名。
<?php

/**
* 用上下文信息替换记录信息中的占位符
*/
function interpolate($message, array $context = array())
&#123;
  // 构建一个花括号包含的键名的替换数组
  $replace = array();
  foreach ($context as $key => $val) &#123;
      $replace['&#123;' . $key . '&#125;'] = $val;
  &#125;

  // 替换记录信息中的占位符,最后返回修改后的记录信息。
  return strtr($message, $replace);
&#125;

// 含有带花括号占位符的记录信息。
$message = "User &#123;username&#125; created";

// 带有替换信息的上下文数组,键名为占位符名称,键值为替换值。
$context = array('username' => 'bolivar');

// 输出 "Username bolivar created"
echo interpolate($message, $context);
<?php

namespace Psr\Log;

/**
 * 日志记录实例
 *
 * 日志信息变量 —— message,**必须** 是一个字符串或是实现了 __toString() 方法的对象。
 *
 * 日志信息变量中 **可以** 包含格式如 “&#123;foo&#125;” (代表 foo) 的占位符,
 * 它将会由上下文数组中键名为「foo」的键值替代。
 *
 * 上下文数组可以携带任意的数据,唯一的限制是,当它携带的是一个 exception 对象时,它的键名 **必须** 是 "exception"。
 *
 * 详情可参阅: https://github.com/PizzaLiu/PHP-FIG/blob/master/PSR-3-logger-interface-cn.md
 */
interface LoggerInterface
&#123;
    /**
     * 系统不可用
     *
     * @param string $message
     * @param array $context
     * @return null
     */
    public function emergency($message, array $context = array());

    /**
     *  **必须** 立刻采取行动
     *
     * 例如:在整个网站都垮掉了、数据库不可用了或者其他的情况下, `应该` 发送一条警报短信把你叫醒。
     *
     * @param string $message
     * @param array $context
     * @return null
     */
    public function alert($message, array $context = array());

    /**
     * 紧急情况
     *
     * 例如:程序组件不可用或者出现非预期的异常。
     *
     * @param string $message
     * @param array $context
     * @return null
     */
    public function critical($message, array $context = array());

    /**
     * 运行时出现的错误,不需要立刻采取行动,但必须记录下来以备检测。
     *
     * @param string $message
     * @param array $context
     * @return null
     */
    public function error($message, array $context = array());

    /**
     * 出现非错误性的异常。
     *
     * 例如:使用了被弃用的API、错误地使用了API或者非预想的不必要错误。
     *
     * @param string $message
     * @param array $context
     * @return null
     */
    public function warning($message, array $context = array());

    /**
     * 一般性重要的事件。
     *
     * @param string $message
     * @param array $context
     * @return null
     */
    public function notice($message, array $context = array());

    /**
     * 重要事件
     *
     * 例如:用户登录和SQL记录。
     *
     * @param string $message
     * @param array $context
     * @return null
     */
    public function info($message, array $context = array());

    /**
     * debug 详情
     *
     * @param string $message
     * @param array $context
     * @return null
     */
    public function debug($message, array $context = array());

    /**
     * 任意等级的日志记录
     *
     * @param mixed $level
     * @param string $message
     * @param array $context
     * @return null
     */
    public function log($level, $message, array $context = array());
&#125;

缓存接口规范

  • 所有存进实现类库的数据,都 必须 能做到原封不动的取出。
  • 实在无法「完整取出」存入的数据的话,实现类库 必须 把「缓存丢失」标示作为返回,而不是损坏了的数据。
  • 缓存系统里的错误 一定不可 导致应用程序故障
<?php

namespace Psr\Cache;

/**
 * CacheItemInterface 定了缓存系统里对缓存项操作的接口
 */
interface CacheItemInterface
&#123;
    /**
     * 返回当前缓存项的「键」
     *
     * 「键」由实现类库来加载,并且高层的调用者(如:CacheItemPoolInterface)
     *  `应该` 能使用此方法来获取到「键」的信息。
     *
     * @return string
     *   当前缓存项的「键」
     */
    public function getKey();

    /**
     * 凭借此缓存项的「键」从缓存系统里面取出缓存项。
     *
     * 取出的数据 **必须** 跟使用 `set()` 存进去的数据是一模一样的。
     *
     * 如果 `isHit()` 返回 false 的话,此方法必须返回 `null`,需要注意的是 `null`
     * 本来就是一个合法的缓存数据,所以你 `应该` 使用 `isHit()` 方法来辨别到底是
     * "返回 null 数据" 还是 "缓存里没有此数据"。
     *
     * @return mixed
     *   此缓存项的「键」对应的「值」,如果找不到的话,返回 `null`
     */
    public function get();

    /**
     * 确认缓存项的检查是否命中。
     *
     * 注意: 调用此方法和调用 `get()` 时 **一定不可** 有先后顺序之分。
     *
     * @return bool
     *   如果缓冲池里有命中的话,返回 `true`,反之返回 `false`
     */
    public function isHit();

    /**
     * 为此缓存项设置「值」。
     *
     * 参数 $value 可以是所有能被 PHP 序列化的数据,序列化的逻辑
     * 需要在实现类库里书写。
     *
     * @param mixed $value
     *   将被存储的可序列化的数据。
     *
     * @return static
     *   返回当前对象。
     */
    public function set($value);

    /**
     * 设置缓存项的准确过期时间点。
     *
     * @param \DateTimeInterface $expiration
     *
     *   过期的准确时间点,过了这个时间点后,缓存项就 **必须** 被认为是过期了的。
     *   如果明确的传参 `null` 的话,**可以** 使用一个默认的时间。
     *   如果没有设置的话,缓存 `应该` 存储到底层实现的最大允许时间。
     *
     * @return static
     *   返回当前对象。
     */
    public function expiresAt($expiration);

    /**
     * 设置缓存项的过期时间。
     *
     * @param int|\DateInterval $time
     *   以秒为单位的过期时长,过了这段时间后,缓存项就 **必须** 被认为是过期了的。
     *   如果明确的传参 `null` 的话,**可以** 使用一个默认的时间。
     *   如果没有设置的话,缓存 `应该` 存储到底层实现的最大允许时间。
     *
     * @return static
     *   返回当前对象
     */
    public function expiresAfter($time);

&#125;
<?php

namespace Psr\Cache;

/**
 * CacheItemPoolInterface 生成 CacheItemInterface 对象
 */
interface CacheItemPoolInterface
&#123;
    /**
     * 返回「键」对应的一个缓存项。
     *
     * 此方法 **必须** 返回一个 CacheItemInterface 对象,即使是找不到对应的缓存项
     * 也 **一定不可** 返回 `null`。
     *
     * @param string $key
     *   用来搜索缓存项的「键」。
     *
     * @throws InvalidArgumentException
     *   如果 $key 不是合法的值,\Psr\Cache\InvalidArgumentException 异常会被抛出。
     *
     * @return CacheItemInterface
     *   对应的缓存项。
     */
    public function getItem($key);

    /**
     * 返回一个可供遍历的缓存项集合。
     *
     * @param array $keys
     *   由一个或者多个「键」组成的数组。
     *
     * @throws InvalidArgumentException
     *   如果 $keys 里面有哪个「键」不是合法,\Psr\Cache\InvalidArgumentException 异常
     *   会被抛出。
     *   
     * @return array|\Traversable
     *   返回一个可供遍历的缓存项集合,集合里每个元素的标识符由「键」组成,即使即使是找不到对
     *   的缓存项,也要返回一个「CacheItemInterface」对象到对应的「键」中。
     *   如果传参的数组为空,也需要返回一个空的可遍历的集合。
     */
    public function getItems(array $keys = array());

    /**
     * 检查缓存系统中是否有「键」对应的缓存项。
     *
     * 注意: 此方法应该调用 `CacheItemInterface::isHit()` 来做检查操作,而不是
     * `CacheItemInterface::get()`
     *
     * @param string $key
     *   用来搜索缓存项的「键」。
     *
     * @throws InvalidArgumentException
     *   如果 $key 不是合法的值,\Psr\Cache\InvalidArgumentException 异常会被抛出。
     *
     * @return bool
     *   如果存在「键」对应的缓存项即返回 true,否则 false
     */
    public function hasItem($key);

    /**
     * 清空缓冲池
     *
     * @return bool
     *   成功返回 true,有错误发生返回 false
     */
    public function clear();

    /**
     * 从缓冲池里移除某个缓存项
     *
     * @param string $key
     *   用来搜索缓存项的「键」。
     *
     * @throws InvalidArgumentException
     *   如果 $key 不是合法的值,\Psr\Cache\InvalidArgumentException 异常会被抛出。
     *
     * @return bool
     *   成功返回 true,有错误发生返回 false
     */
    public function deleteItem($key);

    /**
     * 从缓冲池里移除多个缓存项
     *
     * @param array $keys
     *   由一个或者多个「键」组成的数组。
     *   
     * @throws InvalidArgumentException
     *   如果 $keys 里面有哪个「键」不是合法,\Psr\Cache\InvalidArgumentException 异常
     *   会被抛出。
     *
     * @return bool
     *   成功返回 true,有错误发生返回 false
     */
    public function deleteItems(array $keys);

    /**
     * 立刻为「CacheItemInterface」对象做数据持久化。
     *
     * @param CacheItemInterface $item
     *   将要被存储的缓存项
     *
     * @return bool
     *   成功返回 true,有错误发生返回 false
     */
    public function save(CacheItemInterface $item);

    /**
     * 稍后为「CacheItemInterface」对象做数据持久化。
     *
     * @param CacheItemInterface $item
     *   将要被存储的缓存项
     *
     * @return bool
     *   成功返回 true,有错误发生返回 false
     */
    public function saveDeferred(CacheItemInterface $item);

    /**
     * 提交所有的正在队列里等待的请求到数据持久层,配合 `saveDeferred()` 使用
     *
     * @return bool
     *  成功返回 true,有错误发生返回 false
     */
    public function commit();
&#125;

参考文档

工具推荐


Author: Itaken
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint polocy. If reproduced, please indicate source Itaken !
  TOC目录