我正在处理一个敏捷的PHP项目,该项目分为几个库和插件,并使用作曲家自动加载。 我遇到的问题是,每个库都有几乎相同的配置文件,如下所示:
<?php
define('ROOT', __DIR__); // root dir
define('APP', ROOT . DS . 'app'); // app directory
在我的所有软件包中都有这样的东西,它正在产生常量冲突。
那么我怎样才能做一些更干净的事情,其中每个包都有自己的路径和链接,而不会与其他包以及作曲家包发生任何冲突,谢谢。
你可以通过使用命名空间和类常量来简单地解决这个问题。
例如:
LibA:
<?php
namespace libraryA;
class Config
{
const ROOT = __DIR__;
const DS = '/';
const APP = self::ROOT . self::DS . 'appA';
}
LibB:
<?php
namespace libraryB;
class Config
{
const ROOT = __DIR__;
const DS = '/';
const APP = self::ROOT . self::DS . 'appB';
}
您可以在以下任何地方轻松访问:
<?php
use libraryAConfig as AConfig;
use libraryBConfig as BConfig;
var_dump(AConfig::APP, BConfig::APP);
这样,它们将保持独立,并且代码将更具可读性。
这只是一个例子,您实际上不必为每个配置类重新声明DS
和ROOT
。 您可以只使用 1 个父类来包含这些全局常量。
PHP 中实际上有三种类型的用户定义常量:
- 用
define()
声明的全局常量,在所有作用域中具有相同的值。这些应该谨慎使用,因为正如你所发现的,很容易以两段代码试图定义相同的常量而告终。但是,您可以检查常量是否已经存在,如果您确定它在两个地方用于相同的目的,例如if ( ! defined('MAGIC') ) { define('MAGIC', 'xyzzy'); }
类 - 常量,在类定义中使用
const
声明,并使用语法ClassName::FOO
进行访问。这些是更明确的范围,并且由于类可以自动加载,因此无需显式include
具有定义的文件。该类又可以位于命名空间中,以便在包之间进行额外的分离。但是,您可以基于什么来定义它们存在限制,例如,与define()
不同,它们不能是函数调用的结果。 - 命名空间常量,在顶部具有
namespace
声明的文件中用const
声明。这些可以使用完全限定名称(如FooBarMAGIC
)引用,也可以在特定文件中使用use const FooBarMAGIC
或use const FooBarMAGIC as BAR_MAGIC
别名为较短的名称。它们使您不必创建一个原本为空的类来放入常量,但不幸的是无法自动加载,因此您仍然需要显式include
一个文件来定义它们。