【问题标题】:In PHP, is there a way to get all declared classes in a specific namespace?在 PHP 中,有没有办法在特定的命名空间中获取所有声明的类?
【发布时间】:2012-01-21 15:39:50
【问题描述】:

我想获取 PHP 中特定命名空间内所有类的名称。目前,我正在尝试通过对特定命名类列表的反射来做一些魔术,但我想在不提前知道名称的情况下这样做。

我已尝试致电get_declared_classes(),但无论出于何种原因,我所提供的课程都没有出现。我可以拨打get_declared_classes(),在列表中看不到Event,然后立即拨打$x = new Event() 没有问题。像下面这样的东西,我认为应该会导致问题......

if (! in_array('Event', get_declared_classes())) { $x = new Event(); }

...工作正常。我想知道命名这些类并以这种方式检索是否有助于缓解问题。这可能吗?

编辑:为澄清起见,让我补充一点,我目前没有使用命名空间,我也没有专门尝试从上面列出的代码中实现某些目标。我想要的是获取我声明的所有类的名称。尽管在我打电话给get_declared_classes() 之前,它们的所有类声明都已被击中,但它们并没有全部出现在列表中。我希望命名空间可以帮助解决问题。

EDIT2:有几个人指出这些类可能是自动加载的。我通过执行以下操作对此进行了测试。 echo(class_exists('Event')) 返回值 1echo(class_exists('Event', FALSE)) 返回值 0。class_exists 的第二个可选参数是是否自动加载。因此,显然该类正在自动加载。这就是答案。

那么,下一个问题 - 我该如何防止这种情况发生?我使用的框架实际上并没有给我太多的低级控制。有没有办法强制自动加载,然后调用get_declared_classes,或者让get_declared_classes 先触发自动加载?

【问题讨论】:

  • 在get_declared_classes不包含Event的场景下,是否加载了Event代码?换句话说,是否包含了包含 Event 的类声明的文件(或者已经在代码流中定义了)?
  • 我没有费心去测试,但我认为这可能是因为你已经使用 use 语句引用了一个 NS,并且数组中的类名将是具有命名空间的完全限定类名。这样虽然new Event 可能会起作用,但它确实引用了\Some\OtherNamespace\Event
  • @Corbin 事件代码肯定已加载。如果没有,$x = new Event() 会失败,对吧?
  • @prodigitalson 我目前没有使用命名空间。
  • @Ryan:不,调用$x = new Event() 可能会使用自动加载然后加载Event 类的代码。

标签: php oop reflection namespaces


【解决方案1】:

你不需要在代码中硬编码,你可以使用变量名:

$class_name = 'Event';
if (!in_array($class_name, get_declared_classes())) {
    $x = new $class_name();
};

在此处查看类似的代码:codepad.org/hCLE4ToA

还有一些类可能不会出现在get_declared_classes() 的结果中,因为它们可能在调用这个函数时没有被加载。如果它们在您尝试实例化它们之后被自动加载,则可能是这种情况。在此处查看有关自动加载类的更多信息:php.net/autoload

它是否回答了您的一些问题?有帮助吗?

【讨论】:

  • 我实际上并没有尝试做我列出的示例。这更能说明我想要的类名没有像我预期的那样出现在列表中,但它可以用于实例化。
  • @Ryan:您确定它可用于实例化,而不是因为它在您尝试实例化时自动加载吗?换句话说:你确定在你调用get_declared_classes()之前已经定义了类吗?
  • 你知道强制自动加载的方法吗?我使用的框架不能给我太多控制,我真的需要那些正在自动加载的类的名称。
  • @Ryan:由于负责自动加载的代码可能非常复杂,我认为除了查看自动加载机制的位置并收集有关类的信息之外别无选择。通常可以根据文件名来完成(例如,文件Zend/Validate/Callback.php 包含Zend 中Zend_Validate_Callback 类的定义),但这可能会很棘手。如果您的框架以某种方式缓存这些路径,您可能会很幸运,最好将类名与它们相关联。一般来说,自动加载有时非常有用,但在这种情况下,它可能会让您有些头疼。
  • 值得注意的是,如果这是一个分布在大量文件中的非常大的类集,如果这是一个频繁执行的操作,它可能会变得非常降低性能。加载文件相当慢。
猜你喜欢
  • 2018-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-10
  • 1970-01-01
  • 2010-09-25
  • 2014-05-10
相关资源
最近更新 更多