PSR-1:2.3。副作用:配置文件中的变量

Fab*_*ert 4 php standards psr-1 php-fig

PSR-1包括建议2.3。副作用

一个文件应该声明新的符号(类、函数、常量等)并且不会引起其他副作用,或者它应该执行带有副作用的逻辑,但不应该两者都做。

考虑一个 config.php 文件中的这个例子(我自己的):

/**
 * Parsing the database URL.
 * DATABASE_URL is in the form:
 *  postgres://user:password@hostname:port/database
 * e.g.:
 *  postgres://u123:pabc@ec2.eu-west-1.compute.amazonaws.com:5432/dxyz
 */
$url = parse_url(getenv('DATABASE_URL'));
define('DB_HOST', $url['host']);
define('DB_NAME', substr($url['path'], 1)); // get rid of initial slash
define('DB_USER', $url['user']);
define('DB_PASSWORD', $url['pass']);

Run Code Online (Sandbox Code Playgroud)

如果我这样做,我实际上没有尊重建议。phpcs理所当然地会抱怨它,因为变量:

FILE: config.php
-----------------------------------------------------------------------------------------------------------------
FOUND 0 ERRORS AND 1 WARNING AFFECTING 1 LINE
-----------------------------------------------------------------------------------------------------------------
 1 | WARNING | A file should declare new symbols (classes, functions, constants, etc.) and cause no other side
   |         | effects, or it should execute logic with side effects, but should not do both. The first symbol
   |         | is defined on line 17 and the first side effect is on line 162.
-----------------------------------------------------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)

另一种选择是这样的:

define('DB_HOST', parse_url(getenv('DATABASE_URL'))['host']);
define('DB_NAME', substr(parse_url(getenv('DATABASE_URL'))['path'], 1));
define('DB_USER', parse_url(getenv('DATABASE_URL'))['user']);
define('DB_PASSWORD', parse_url(getenv('DATABASE_URL'))['pass']);
Run Code Online (Sandbox Code Playgroud)

没有变量,没问题。但这是湿的,难以阅读。

我知道建议就是这样,它说“应该”,而不是“必须”。但这仍然困扰着我……一方面,任何时候我检查文件 phpcs 都会抱怨它,但每行只报告一次,为添加更多在配置文件中没有位置的“副作用”敞开大门。

我对这整个 PSR 事情还是陌生的。

我是否错过了任何巧妙的方法来摆脱变量,同时保持可读性?

一个推论是:坚持遵循建议的严肃项目如何处理这个问题?

Pet*_*ete 5

1. 没事,别着急

你已经在你的问题中提到了它,但这个建议是应该的,而不是必须的。如果这是整个项目中唯一的 PSR-1 问题:干得好!

但你的问题是:其他项目如何做到这一点?

2. 远离配置定义

全局常量,如果使用不当,就会成为依赖磁铁。它们引入了耦合并使您的代码更难以消化。这个问答很好地解释了为什么你应该远离它们

改用依赖注入(是的,标量配置常量也是依赖项)。

3. 案例研究:Symfony

基于Symfony的项目使用:

  • YAML(推荐)或 XML 配置文件来配置依赖注入容器,以及
  • environment variables,设置特定于应用程序应运行的每个环境的配置选项。这些环境变量在特定于环境的.env文件中定义。

例如,要在 Symfony 项目中配置数据库服务,您需要创建一个包含以下内容的 YAML 文件:

services:
    My\Database\Factory: # <-- the class we are configuring
        arguments:
            $url: '%env(DATABASE_URL)' # <-- configure the $url constructor argument
Run Code Online (Sandbox Code Playgroud)

Symfony 将其编译为 PHP 代码,将DATABASE_URL环境变量注入到需要它的类中。

然后DATABASE_URL,您将在My\Database\Factory类的构造函数中进行解析,并使用结果来构造您的数据库类。

优点:

  • 配置与代码分离
  • 配置容易改变
  • 配置易于阅读

缺点:

  • 依赖注入和使用 DI 容器有一个学习曲线,需要改变构建对象的方式。