ホームページ  >  記事  >  バックエンド開発  >  PHP の PSR 仕様とは何ですか?

PHP の PSR 仕様とは何ですか?

PHPz
PHPzオリジナル
2016-06-13 12:02:492939ブラウズ

PHP における PSR 仕様とは、PHP Standard Recommendations の略で、PHP FIG 団体によって策定された PHP 開発の実用的な標準仕様です。

PHP の PSR 仕様とは何ですか?

PSR は、PHP Standard Recommendations の略で、PHP FIG 団体によって策定された PHP の仕様であり、PHP 開発のための実用的な標準です。

PHP FIG は、Framework Interoperability Group の略称で、2009 年に数人のオープンソース フレームワーク開発者によって設立されました。 Laravel、Joomla、Drupal、Composer、Phalcon、Slim、Symfony、Zend Framework など)、「公式」組織ではありませんが、PHP コミュニティの大部分を代表しています。

プロジェクトの目的は、フレームワークの作成者またはフレームワークの代表者間の議論を通じて、最小限の制限レベルのコラボレーション標準を開発することです。各フレームワークは、各社独自の開発を妨げないよう、統一されたコーディング標準に従います。 PHP の開発は、プログラマーにとってのこの長年の問題を解決します。

これまでに、php-fig は 5 つの仕様をリリースしました:

  • PSR-0: 自動ロード標準、2014-10-21 標準廃止され、PSR-4 に置き換えられました。詳細は不明です。コーディング スタイル (より厳密)

  • PSR-3: ロガー インターフェイス

  • PSR -4:

  • PSR-1
  • PHP タグ:

  • PHP コードを に配置する必要があります。 php ?> タグまたは = ? > ラベル内。

エンコーディング: PHP ファイルは BOM フリーの UTF-8 エンコーディングを使用する必要があります。

副作用:

PHP ファイルでは、シンボル (クラス、関数、定数など) を定義したり、固有の副作用 (出力結果、プロセス データなど) のみを使用して操作を実行したりできます。 、など)、しかし同時にはできません。これら 2 つのことを行うには、PHP ファイルの単一の関数を持たせるようにしてください。運用する際は、変数、クラス、関数の宣言を分離し、include ファイルや require ファイルを通じて使用するようにしてください。

以下は仕様に準拠しません:

以下は仕様に準拠します:

名前空間とクラス:

名前空間とクラスは、PSR-4 オートローダー標準に従う必要があります。

<?php
// 改变设置
ini_set(&#39;error_reporting&#39;, E_ALL);

// 加载文件
include "file.php";

// 打印输出
echo "<html>\n";

// 声明
function foo()
{
    // function body
}
クラス名:

各クラスには独自の名前空間があり、最上位の名前空間の下にあります。クラス名には CamelCase を使用する必要があります。
<?php
// 声明
function foo()
{
    // function body
}

// 条件判断
if (! function_exists(&#39;bar&#39;)) {
    function bar()
    {
        // function body
    }
}

PHP 5.3 以降では、正式な名前空間を使用する必要があります。例:

PHP 5.3 以降では、Vendor_ で始まる疑似名前空間規則を使用する必要があります。例:

定数:

定数はすべて大文字で、アンダースコア (_) で区切る必要があります。例:

<?php
// PHP 5.3 及以后
namespace Vendor\Model;

class Foo
{
}

クラスのメソッド:

<?php
// PHP 5.3以下
class Vendor_Model_Foo
{
}
クラスのメソッドは、小文字で始まるキャメルケースで名前を付ける必要があります。

PSR-2

<?php
namespace Vendor\Model;

class Foo
{
    const VERSION = &#39;1.0&#39;;
    const DATE_APPROVED = &#39;2012-06-01&#39;;
}

PSR-2 は PSR-1 の PHP 拡張機能です。

PSR-1 の実装:

PSR-2 コード標準を使用する前に、まず PSR-1 コード標準を実装する必要があります。

ファイルとコード行:

PHP ファイルは Unix スタイルの改行 (LF、ラインフィード) を使用し、最後に空白行を含める必要があります。ファイルには PHP コードのみが含まれているため、閉じることはできません。 PHP Tag?> を使用する場合、コードの各行は 80 文字を超えてはならず、各行の末尾にスペースを入れてはならず、1 行に 1 つのステートメントのみを含めることができ、適切な場所に空白行を追加して改善することができます。コードの読みやすさ。 終了タグを追加しないと、予期しない出力エラーを回避できます。終了タグが追加され、終了タグの後に空白行がある場合、その空白行が出力とみなされ、予期しない出力が発生します。 。 エラー。

インデント:

は 4 つのスペースでインデントする必要があり、インデントにタブ文字 (Tab キー) は使用できません。

異なるエディターでも、スペースのレンダリング効果は基本的に同じですが、タブ文字の幅は異なります。

キーワード:

PHP キーワードは小文字である必要があり、true、false、および null も小文字である必要があります。

名前空間と use 宣言:

ここで、名前空間宣言の後には空行が必要であり、use 宣言は名前空間の後に配置する必要があり、名前空間を個別に導入するために use を使用する必要があります。 、使用後 空行が必要です。例:

クラスの継承と実装:

extends およびimplements キーワードはクラス名と同じ行になければなりません、クラス、インターフェイス、および特性の定義本体の先頭にあります。左括弧はクラス名の後の新しい行で開始する必要があり、閉じ括弧も新しい行で開始する必要があります。例:

実装後に実装されるインターフェースが多く、行が非常に長い場合は、次のように、必要なクラスを 1 つずつ開始し、スペースを 4 つインデントします。

<?php
namespace Vendor\Package;

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

// ... additional PHP code ...

Visibility:

クラス内のすべての属性とメソッドは、public、private、protected を含めて可視性を宣言する必要があります。古いバージョンの PHP では、宣言できる属性は 1 つだけです。行、例:

<?php
namespace Vendor\Package;

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

class ClassName extends ParentClass implements \ArrayAccess, \Countable
{
    // constants, properties, methods
}

メソッド:

类中的所有方法也应该定义可见性,方法名后面不能有空格,方法体的括号位置和类定义体的括号位置一样,都要新起一行,结束括号也要新起一行。方法参数的起始圆括号之后没有空格,结束括号之前也没有空格,有多个参数是,每个参数的逗号后面加一个空格,例如:

<?php
namespace Vendor\Package;

class ClassName
{
    public function fooBarBaz($arg1, &$arg2, $arg3 = [])
    {
        // method body
    }
}

如果参数比较多,需要换行时,可以如下:

<?php
namespace Vendor\Package;

class ClassName
{
    public function aVeryLongMethodName(
        ClassTypeHint $arg1,
        &$arg2,
        array $arg3 = []
    ) {
        // method body
    }
}

abstract、final和static:

现在,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
bar();
$foo->bar($arg1);
Foo::bar($arg2, $arg3);

如果参数比较多,一行放不下时,如下处理:

<?php
$foo->bar(
    $longArgument,
    $longerArgument,
    $muchLongerArgument
);

PHP的控制结构:

PHP的控制结构包括if、else、elseif、switch、case、while、do while、for、foreach、try和catch。如果这些关键词后面有一对原括号,开始括号前必须有一个空格,与方法和类的定义体不同,控制结构关键词后面的起始括号应该和控制结构关键词写在同一行,例如:

<?php
$gorilla = new \Animals\Gorilla;
$ibis = new \Animals\StrawNeckedIbis;

if ($gorilla->isWake() === true) {
    do {
        $gorilla->beatChest();
    } while ($ibis->isAsleep() === true);
    
    $ibis->flyAway();
}

PHP闭包函数:

闭包函数在声明时,function关键词后必须有一个空格,同时use关键词前后也必须有一个空格。起始大括号不需要另起新行,详细的如下代码:

<?php
$closureWithArgs = function ($arg1, $arg2) {
    // body
};

$closureWithArgsAndVars = function ($arg1, $arg2) use ($var1, $var2) {
    // body
};

闭包函数有多个参数时,处理方式和方法的参数一样:

<?php
$longArgs_noVars = function (
    $longArgument,
    $longerArgument,
    $muchLongerArgument
) {
    // body
};

$noArgs_longVars = function () use (
    $longVar1,
    $longerVar2,
    $muchLongerVar3
) {
    // body
};

$longArgs_longVars = function (
    $longArgument,
    $longerArgument,
    $muchLongerArgument
) use (
    $longVar1,
    $longerVar2,
    $muchLongerVar3
) {
    // body
};

$longArgs_shortVars = function (
    $longArgument,
    $longerArgument,
    $muchLongerArgument
) use ($var1) {
    // body
};

$shortArgs_longVars = function ($arg) use (
    $longVar1,
    $longerVar2,
    $muchLongerVar3
) {
    // body
};

注意:以上规则同样适用于将闭包作为函数或方法的参数,如下:

<?php
$foo->bar(
    $arg1,
    function ($arg2) use ($var1) {
        // body
    },
    $arg3
);

到2019-08-10,PSR-2已被官方废弃

PHP の PSR 仕様とは何ですか?

PSR-3

与PSR-1和PSR-2不同,PSR-3规定了一套通用的日志记录器接口(Psr\Log\LoggerInterface),为了符合PSR-3规范,框架必须实现该规范中的接口,这样可以更多的兼容第三方应用。PSR-3规范中包含了9个方法,每个方法都对应了RFC 5424协议的一个日志级别,而且都接受两个参数$message和$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".
 *
 * See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md
 * for the full interface specification.
 */
interface LoggerInterface
{
    /**
     * System is unusable.
     *
     * @param string $message
     * @param array $context
     * @return void
     */
    public function emergency($message, array $context = array());

    /**
     * Action must be taken immediately.
     *
     * Example: Entire website down, database unavailable, etc. This should
     * trigger the SMS alerts and wake you up.
     *
     * @param string $message
     * @param array $context
     * @return void
     */
    public function alert($message, array $context = array());

    /**
     * Critical conditions.
     *
     * Example: Application component unavailable, unexpected exception.
     *
     * @param string $message
     * @param array $context
     * @return void
     */
    public function critical($message, array $context = array());

    /**
     * Runtime errors that do not require immediate action but should typically
     * be logged and monitored.
     *
     * @param string $message
     * @param array $context
     * @return void
     */
    public function error($message, array $context = array());

    /**
     * Exceptional occurrences that are not errors.
     *
     * Example: Use of deprecated APIs, poor use of an API, undesirable things
     * that are not necessarily wrong.
     *
     * @param string $message
     * @param array $context
     * @return void
     */
    public function warning($message, array $context = array());

    /**
     * Normal but significant events.
     *
     * @param string $message
     * @param array $context
     * @return void
     */
    public function notice($message, array $context = array());

    /**
     * Interesting events.
     *
     * Example: User logs in, SQL logs.
     *
     * @param string $message
     * @param array $context
     * @return void
     */
    public function info($message, array $context = array());

    /**
     * Detailed debug information.
     *
     * @param string $message
     * @param array $context
     * @return void
     */
    public function debug($message, array $context = array());

    /**
     * Logs with an arbitrary level.
     *
     * @param mixed $level
     * @param string $message
     * @param array $context
     * @return void
     */
    public function log($level, $message, array $context = array());
}

关于message参数:

$message必须是一个字符串或者是含有__toString()方法的对象,$message应该包含占位符,例如{placeholder_name},占位符由{、占位符名称和}组成,不能包含空格,占位符名称可以由A-Z, a-z, 0-9, _组成,第三方实现可以用$context参数来替换占位符,占位符名称必须和$context数组的key对应。如下例子是使用$context中的值替换$message中的占位符:

<?php

/**
 * Interpolates context values into the message placeholders.
 */
function interpolate($message, array $context = array())
{
    // build a replacement array with braces around the context keys
    $replace = array();
    foreach ($context as $key => $val) {
        // check that the value can be casted to string
        if (!is_array($val) && (!is_object($val) || method_exists($val, &#39;__toString&#39;))) {
            $replace[&#39;{&#39; . $key . &#39;}&#39;] = $val;
        }
    }

    // interpolate replacement values into the message and return
    return strtr($message, $replace);
}

// a message with brace-delimited placeholder names
$message = "User {username} created";

// a context array of placeholder names => replacement values
$context = array(&#39;username&#39; => &#39;Bolivar&#39;);

// echoes "User Bolivar created"
echo interpolate($message, $context);

关于context参数:

$context是一个数组参数,用于构造复杂的日志消息,$context中的值不能抛出任何PHP异常或错误。如果$context中包含Exception对象,则该对象的key必须为exception。

PSR-3日志记录器的使用

推荐使用monolog/monolog,这样可以让我们不需要浪费更多的时间在编写一个日志记录器了。Monolog组建完全实现了PSR-3接口,而且便于使用自定义的消息格式化程序和处理程序扩展功能,通过Monolog可以把日志消息写入文本文件、系统日志和数据库中,还能通过电子邮件发送,并且还支持Slack和远程服务器。如下展示了如何设置Monolog,并把日志消息写入文本文件:

use Monolog/Logger;
use Monolog/Handler/StreamHandler;

// 创建日志记录器
$log = new Logger(&#39;myApp&#39;);
$log->pushHandler(new StreamHandler(&#39;logs/development.log, Logger::DEBUG));
$log->pushHandler(new StreamHandler(&#39;logs/production.log&#39;, Logger::WARNING));

// 使用日志记录器
$log->debug("This is a debug message");
$log->warning("This is a warning message");

PSR-4

PSR-4规范描述了一个标准的自动加载器策略,指在运行时按需查找PHP类、接口或Traits。支持PSR-4自动加载器标准的PHP组建和框架,使用同一个自动加载器就能找到相关代码,然后将其载入PHP解释器。有了这个功能,就可以把现代PHP生态系统中很多客户操作的组件联系起来。

编写一个PSR-4自动加载器

PSR-4规范不要求改变代码的实现方式,只建议如何使用文件系统目录结构和PHP命名空间组织代码,PSR-4规范以来PHP命名空间和文件系统目录结构查找并加载PHP类、接口和Traits,这正是PSR-4的精髓所在。下面我们来自己手动实现一个PSR-4自动加载器:

<?php
/**
 * 使用SPL组册这个自动加载函数后,遇到下述代码时这个函数会尝试   从/path/to/project/src/Baz/Qux.php文件中加载\Foo\Bar\Baz\Qux类:
 *  new \Foo\Bar\Baz\Qux;
 * @param string $class 完全限定的类名。
 * @return void
 **/
spl_autoload_register(function ($class) {
    // 项目的命名空间前缀
    $prefix = &#39;Foo\\Bar\\&#39;;
    
    // 目录前缀对应的根目录
    $base_dir = __DIR__ . &#39;/src/&#39;;
    
    // 判断传入的类是否使用了这个命名空间前缀
    $len = strlen($prefix);
    if (strncmp($prefix, $class, $len) !== 0) {
        // 没有使用,交给注册的下一个自动加载器处理
        return;
    }
    
    // 获取去掉前缀后的类名
    $relative_class = substr($class, $len);
    
    // 把命名空间前缀替换成根目录,
    // 在去掉前缀的类名中,把命名空间分隔符替换成目录分隔符,
    // 然后在后面加上.php
    $file = $base_dir . str_replace(&#39;\\&#39;, &#39;/&#39;, $relative_class) . &#39;.php&#39;;
    
    // 如果该文件存在,就将其导入
    if (file_exists($file)) {
        require $file;
    }
});

更多相关知识,请访问 PHP中文网!!

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。