PHP全局常量是一种很好的现代开发实践吗?

PHP全局常量是一种很好的现代开发实践吗?,php,unit-testing,dependency-injection,tdd,Php,Unit Testing,Dependency Injection,Tdd,我正在做一个新的项目,有一个相当大的PHP代码库。应用程序使用了相当多的PHP常量(define('FOO','bar')),特别是对于数据库连接参数之类的东西。这些常量都在单个配置文件中定义,该文件基本上由应用程序中的每个类直接定义 几年前,这是非常有意义的,但从那时起,我就遇到了单元测试错误,类之间的紧密耦合真的让我很困扰。这些常量闻起来像全局变量,它们在整个应用程序代码中直接引用 这仍然是个好主意吗?将这些值复制到一个对象中并使用这个对象(即一个Bean,我说的是Bean)通过依赖注入将它

我正在做一个新的项目,有一个相当大的PHP代码库。应用程序使用了相当多的PHP常量(
define('FOO','bar')
),特别是对于数据库连接参数之类的东西。这些常量都在单个配置文件中定义,该文件基本上由应用程序中的每个类直接定义

几年前,这是非常有意义的,但从那时起,我就遇到了单元测试错误,类之间的紧密耦合真的让我很困扰。这些常量闻起来像全局变量,它们在整个应用程序代码中直接引用

这仍然是个好主意吗?将这些值复制到一个对象中并使用这个对象(即一个Bean,我说的是Bean)通过依赖注入将它们传递给与数据库交互的类是否合理?我这样做是否有损于PHP常量的任何好处(比如说速度之类的)

我正在考虑的另一种方法是创建一个单独的配置PHP脚本进行测试。我仍然需要找到一种方法让被测试的类使用沙盒配置脚本而不是全局配置脚本。这仍然感觉脆弱,但可能需要对整个应用程序进行更少的直接修改

这些常量闻起来像全局变量,它们被直接引用[…]。将这些值复制到对象中并[…]通过依赖项注入传递它们是否合理

绝对是!我会更进一步地说,即使是类常量也应该避免。因为它们是公共的,所以它们公开了内部构件,并且它们是API,所以您无法轻松地对它们进行更改,而不会因为紧密耦合而破坏现有的应用程序。配置对象更有意义(只是不要让它成为单例对象)

另见:


使用常量作为数据库连接信息是完全正确的。这可以防止在对象本身中对其进行硬编码,并且由于其为只读,因此无法覆盖这些值


我不喜欢在对象中硬编码我的设置,因为事情可能会改变,但如果你想这样做,那也行。

在我看来,常量只能在两种情况下使用:

  • 实际常量值(即永不改变的事物,
    秒/u小时
  • 依赖于操作系统的值,只要应用程序可以透明地使用该常量,就可以在任何可能的情况下使用
即使这样,我还是会重新考虑类常量是否更合适,以免污染常量空间


在您的情况下,我认为常量不是一个好的解决方案,因为您希望根据它们的使用位置提供替代值。

要回答这个问题,重要的是讨论正在编写的代码的样式

PHP5包括许多有用的OOP特性,其中一个是类常量。如果您使用的是面向对象的方法,而不是污染全局名称空间,或者担心覆盖公共常量,那么应该使用类常量

FOO\u BAR
可能是
FOO::BAR
,最后,它取决于您希望定义常量的范围

如果您正在编写一个更程序化的程序,或者将程序与某些类混合,那么全局常量不是问题。如果由于所使用的常量,您正在处理的代码变得不可管理,请尝试更改。否则,别担心


此外,类常量不允许使用函数返回值,全局常量将允许。当您有一个值在整个程序范围内都不会更改,但需要生成时,这非常好。

我不同意常量,也不同意硬代码:-)

除了性能,我更喜欢ZendFramework中的Zend_Config_Ini

您可以重载节、在内存中以只读方式维护值以及其他内容:


如果您有PHP5.3或更新版本,您可以使用
名称空间

它与
const变量='something'一起工作
不幸的是,它不能与
define('variable','something')一起工作


命名空间中的全局变量被封装。在某些情况下,这比拥有一个对象要好。

#定义常量“很好”
?@Marc B:太爱了!这些常量是(超级)全局变量,只能设置一次。这就是为什么它们被用于配置——不是出于测试的原因,而是(因为没有进行测试)以确保它们不会被其他热腾腾的、奶酪背的意大利面条代码所改变——只是为了确保代码中没有任何部分会改变……;)-因此,为工作选择正确的工具。逐步测试遗留代码是一门艺术。删除常量可能是其中的一部分。这种类型的问题,答案是意见或讨论,不适合堆栈溢出。根据《建议》,你应该只根据你面临的实际问题提出实际的、可回答的问题。“非建设性”的详细原因列出了诸如这个问题可能会征求意见、辩论、争论、投票或扩大讨论的原因。因此,我以“不具建设性”的方式关闭它。好的,我最终确定了重新打开它的3票。我并不是说关闭它是错误的,但社区已经说了。在单元测试时,它成为一个主要问题。最好使用依赖注入。友好的建议可以更好地解释你的第一句话。问题本身的标题和措辞有些矛盾。标题问“常量好吗?”,但正文读起来更像“常量坏吗?”。很难说你站在哪一边。@如果不清楚,迈克很抱歉:“绝对”指的是OP担心常量是全局状态,以及使用配置的想法