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

标签 php standards psr-1 php-fig

PSR-1包括推荐 2.3. Side Effects :

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.



考虑 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']);


如果我这样做,我实际上是不尊重建议。 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.
-----------------------------------------------------------------------------------------------------------------

另一种选择是:

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']);

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

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

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

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

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

最佳答案

1.没关系,别出汗

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

但你的问题是:其他项目是如何进行的?

2. 远离配置的定义

全局常量,如果使用不当,是依赖磁铁。它们引入了耦合,使您的代码更难消化。 This Q&A is a very good read on why you should move away from them .

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

3. 案例研究:Symfony

Symfony基于项目使用:

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

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

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

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

    然后你会解析 DATABASE_URLMy\Database\Factory 的构造函数中类,并使用结果来构造您的数据库类。

    优点:
  • 配置与代码分离
  • 配置易于更改
  • 配置易读

  • 缺点:
  • 依赖注入(inject)和使用 DI 容器有一个学习曲线,需要改变您对构造对象的看法。
  • 关于php - PSR-1:2.3。副作用:配置文件中的变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60854541/

    相关文章:

    php - mysql_connect() : No connection could be made because the target machine actively refused it

    javascript - 尝试使用 Ajax 实现类似功能后出现内部服务器错误 500

    Portlet 的 CSS 最佳实践

    PHP | define() 与 const

    php - PHP存储时间戳的数据库结构

    php - 如何比较两个学说对象?

    html - 是否有提交空选择倍数的标准客户端行为?

    c++ - 赋值运算符的定义有缺陷吗?

    php codesniffer 什么都不返回……我的代码是标准的吗?

    php - 使用 ini_set() 的 PSR-1 兼容替代方案是什么?