【问题标题】:PHP Global namespace aliasesPHP 全局命名空间别名
【发布时间】:2013-11-22 07:23:09
【问题描述】:

这是场景。

我正在我的项目中实现命名空间。

我有自己的自定义桥接库,可以调用 Zend 等其他库来完成繁重的工作。

在我的自定义桥接库中使用完全限定的命名空间没有问题,但我希望在我的控制器、模型和视图中保持代码尽可能简洁。

这是我想使用的一些别名的示例:

use BridgeLibName\Stdlib\Arrays as arr;
use BridgeLibName\Stdlib\Objects as obj;
use BridgeLibName\Stdlib\Strings as str;
use BridgeLibName\Stdlib\Numbers as num;
use BridgeLibName\Stdlib\File as file;
etc.........

示例用法:

$file = new file('path/to/file.txt');
$file->create();

$obj = arr::toObject(['key1'=>'value1']);

是否可以通过任何方式创建可全局访问且不会在每个文件末尾丢弃的别名或常量?

某种可以使这些别名保持不变的引导文件。

【问题讨论】:

  • 不,你不能(至少不是理智的方式)。
  • 如果用假类引用,效果很好。不过在实施时必须非常小心。
  • 使用“假”类是解决非问题恕我直言的可怕解决方案。
  • 我同意这是一个糟糕的解决方案。但是,如果可以用 3 个字符完成,写出 20+ 个字符就更糟了。这使我的代码臃肿且不可读。如果仔细使用,我认为它会非常有用。只要您从未在库中实现它,而只是将其保留在您的应用程序中。编写 BridgeLibName\Stdlib\Arrays::inArray() 与 arr::inArray() 是一个问题。如果根命名空间因某种原因发生更改,这将很难在全局范围内修复。每个控制器或模型文件中的别名都会产生相同的问题。
  • 如果某些东西以您喜欢的方式对您有用。不要让intarnet上的一些随机人告诉你。如果你后来在这个过程中失败了,或者你后来改变了主意,这两种方式都是进步。

标签: php namespaces global-namespace namespace-organisation


【解决方案1】:

当我写这个问题时,我想到了一个解决方案。

您可以通过创建扩展命名空间类的类来伪造它。

示例:

class arr extends BridgeLibName\Stdlib\Arrays{

}

要记住的重要一点:

如果您要扩展类,则必须加载命名空间类。

如果使用过多,这可能会影响性能,因为别名和命名空间只会在需要时加载。

因为我只是用它来桥接其他类,所以桥文件中的逻辑很少。

这些桥接文件依次正确使用别名和命名空间,从而根据需要加载真实文件。

如果你对实现不小心,你可能会加载很多不必要的东西,导致你的应用变得缓慢和臃肿。


我注意到的一件好事是,像 netbeans 这样好的 IDE 似乎也能够使用这种方法进行自动完成。


如果有更好的方法,请告诉我。


刚刚想到了修改这个方法来解决不必要的类实例化的问题。

核心库可以与普通的 psr-0 加载器一起工作。

为了让别名自动加载,我在命名空间类旁边创建了一个名为 include 的附加目录。

在作曲家你这样描述它:

"autoload": {
    "psr-0": {
        "BridgeLibName\\": "."
    },
    "classmap": ["include/"]
}

现在您的库将从正确的命名空间按预期加载,并且您的别名类将根据需要自动加载。

放入包含目录的类现在可以扩展命名空间类(如上所示),并且在使用之前将不再加载。

现在您有了全局别名,而不必通过加载未使用的类来牺牲性能。

【讨论】:

  • 我只是想到了一些事情。如果您需要为库提供遗留支持,我描述的方法实际上非常有用。扩展命名空间类将允许旧系统像使用普通类一样使用类。对于新项目,可以通过删除 composer 中的 classmap 声明轻松关闭此功能。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-07
  • 2018-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-03
相关资源
最近更新 更多