强制自动加载特定的类



上一个问题显示了如何强制所有类自动加载。

然而,我只需要强制自动加载一个类。我怎么能这么做呢?

不能

:

  • 涉及更改类的源代码
  • 依赖类源代码的任何部分(方法,变量,修饰符,例如,它必须可以自由地从具体到抽象而不影响它)。

同样,最好不要将类名编码为字符串。(以帮助IDE重构等)。

到目前为止,我发现最好的选择是只使用spl_autoload_call():

spl_autoload_call("Jodes\MyClass");

或对于非命名空间类:

spl_autoload_call("MyClass");

我最近也有同样的需求。做require_once不是一个选择,因为由于一些更复杂的规则,类确实需要由自动加载器定位,没有办法确切地知道带有类的文件的路径。

虽然spl_autoload_call($classname)函数的设计正是为了做到这一点,但它有一个根本性的缺陷:如果您为同一个类名调用它两次,或者即使该类的一些子类已经加载,它也会抛出FATAL ERROR。这是因为在PHP中不可能重新声明类:

<?php
spl_autoload_call('TheClass');
// no problem
spl_autoload_call('TheClass');
// PHP Fatal error:  Cannot declare class TheClass, because the name is already in use in ... on line ...

我对这个问题的解决方案不是依赖于class_exists($classname)的副作用,它不是为这个目的而设计的,而是更可配置的,因此,提供了更多的控制来触发自动装弹器。

更棒的是,它在多次调用或者某些东西已经在继承链中加载时绝对没有问题。它只是有一个副作用(如果您愿意的话),如果类还没有存在,则需要该文件!

<?php
class_exists('TheClass');
// no problem
class_exists('TheClass');
// already exists. No need to autoload it and no fatal errors!

这样,你就有了一种安全的、幂等的方式来通过自动加载器加载类。

并且,如果您不想硬编码包含classname的字符串,从PHP 5.5版本开始,您可以使用::class伪常量,它在编译时被解析为具有完全限定类名(包括名称空间)的字符串:

<?php
class_exists(TheClass::class);

我有完全相同的问题,并尝试了不同的自动加载功能。在Windows PHP 8.1.5版本中,我有以下两个不同的自动加载器:

set_include_path(get_include_path() . PATH_SEPARATOR . 'class/');
spl_autoload_extensions('.class.php');
spl_autoload_register();

$autoloader = function( string $class_name )
{
  $filename = $_SERVER["DOCUMENT_ROOT"].'/class/' . str_replace( '\', '/', $class_name)    . '.class.php';
  require_once $filename;
};
// our class loader
spl_autoload_register( $autoloader );

是一样的。

由于我的应用程序中的一个类文件还创建了一些支持全局函数变量,可以在所述类的构造期间使用,因此我需要在访问所述函数变量和构造之前强制加载类文件。我在特定的类上使用class_exist()

使用spl_auoload_extenions版本,这工作良好;当使用函数变量时,使用spl_autoload_register($autoloader)版本会导致未定义的变量。

相关内容

  • 没有找到相关文章

最新更新