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

Php PSR-1:2.3。副作用:配置文件中的变量,php,standards,psr-1,php-fig,Php,Standards,Psr 1,Php Fig,包括建议: 一个文件应该声明新的符号(类、函数、常量等),并且不会产生其他副作用,或者它应该执行带有副作用的逻辑,但不应该同时执行这两个操作 考虑config.php文件中的以下示例(我自己的): /** *正在分析数据库URL。 *数据库URL的格式为: * postgres://user:password@主机名:端口/数据库 *例如: * postgres://u123:pabc@ec2.eu-west-1.compute.amazonaws.com:5432/dxyz */ $url

包括建议:

一个文件应该声明新的符号(类、函数、常量等),并且不会产生其他副作用,或者它应该执行带有副作用的逻辑,但不应该同时执行这两个操作

考虑config.php文件中的以下示例(我自己的):

/**
*正在分析数据库URL。
*数据库URL的格式为:
*  postgres://user:password@主机名:端口/数据库
*例如:
*  postgres://u123:pabc@ec2.eu-west-1.compute.amazonaws.com:5432/dxyz
*/
$url=parse_url(getenv('DATABASE_url'));
定义('DB_HOST',$url['HOST']);
定义('DB_NAME',substr($url['path'],1));//去掉初始斜杠
定义('DB_USER',$url['USER']);
定义('DB_PASSWORD',$url['pass']);
如果我这样做,我实际上是不尊重这个建议的。威尔理所当然地抱怨,因为变量:

文件:config.php
-----------------------------------------------------------------------------------------------------------------
发现影响1行的0个错误和1个警告
-----------------------------------------------------------------------------------------------------------------
1 |警告|文件应声明新符号(类、函数、常量等),并且不会导致其他方面的错误
||效果,或者它应该执行带有副作用的逻辑,但不应该同时执行这两个功能。第一个符号
||在第17行定义,第一个副作用在第162行。
-----------------------------------------------------------------------------------------------------------------
另一种选择是:

define('DB_HOST',parse_url(getenv('DATABASE_url'))['HOST']);
定义('DB_NAME',substr(parse_url(getenv('DATABASE_url'))['path'],1));
定义('DB_USER',parse_url(getenv('DATABASE_url'))['USER']);
定义('DB_PASSWORD',解析_url(getenv('DATABASE_url'))['pass']);
没有变量,就没有问题。但这是湿的,很难阅读

据我所知,这项建议只是说“应该”,而不是“必须”。但这仍然困扰着我……首先,每当我检查文件时,phpcs都会抱怨它,但每行只报告一次,为添加更多配置文件中没有位置的“副作用”打开了大门

我对PSR这整件事还是新手

在保持可读性的同时,我是否错过了任何摆脱变量的聪明方法

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

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

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

2.远离用于配置的定义 如果不正确使用全局常量,则它们是依赖项磁铁。它们引入了耦合,使代码更难理解

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

3.案例研究:Symfony -基于以下内容的项目使用:

  • 将YAML(推荐)或XML配置文件添加到依赖项注入容器,以及
  • ,以设置特定于应用程序应在其中运行的每个环境的配置选项。这些环境变量在特定于环境的.env文件中定义
例如,要在Symfony项目中配置数据库服务,您需要创建一个包含以下内容的YAML文件:

服务:
我的\数据库\工厂:#如方法中所述:

应用程序有时会将配置存储为代码中的常量。这违反了12个因素,这要求将配置与代码严格分离。配置在不同的部署中有很大差异,而代码则没有

12因素应用程序将配置存储在环境变量中。环境变量很容易在部署之间进行更改,而无需更改任何代码

关于最佳实践,您走的是正确的道路,您只需要纠正一些错误

1.使用变量作为环境变量 您希望将常量用于不可用的对象。数据库名称的值可能因环境而异。它不是常量,而是(环境)变量,您应该使用
$dbName=getenv('DB_NAME')

相反,π是一个常数,它永远不会改变,可以硬编码

您可以查看诸如Composer或Symfony组件之类的开源项目的源代码,您将看到仅用于填充变量的
getenv()

2.直接使用配置中预期的元素
在您的情况下,不应将完整的数据库URL用作单个配置项。您应该按照配置的预期,将环境变量中的每个元素分开,如
DB\u HOST
DB\u NAME
DB\u PORT

我不会在defines中使用任何函数。你不能保证结果总是一样的。在本例中,我将使用具有硬编码值的不同配置文件,如live.conf.php和dev.conf.php。根据环境的不同,您可以包含一个或另一个文件,但我会将凭据提交给git,这从来都不是一个好主意。在prod中本地使用.env和Heroku,不想停止使用它们。概念是拥有完全不同的配置。您可以.git忽略它们,只需将example.conf.php放到存储库中。您是否使用依赖项注入容器(DI容器)?/常量在项目中的最佳使用:常量应该在.env文件中找到,或者作为类常量。因此没有
define()
。/您真的需要解析数据库url吗?建议:定义所需的.env常量(
DB\u DSN
DB\u USER
DB\u PASSWORD
,等等),并在需要的地方直接使用它们。@dakis感谢关于避免
def的提示