php spl_autoload_register 和 composer autoloader 可以一起工作吗?

Can php spl_autoload_register & composer autoloader work together?

经过一些研究,我无法找到解决我的问题的方法。我正在使用一个 API,它是我通过 composer 下载的名称空间。 API 具有依赖性,我允许作曲家为我管理和自动加载。除此之外,我还有大约 10 个 类 是我使用 php 的 spl_autoload_register 自动加载的。最近,我开始混合 类 来完成一个项目的一部分,但整个事情都变得一团糟。我的自定义 类 不能使用作曲家 类,反之亦然。有没有一种方法可以用来自动加载 类 ,它们位于两个单独的文件夹中,并且用两个单独的 outloader 加载。

这是我目前使用的代码。 vender/autoload.php 与典型的作曲家自动加载器没有什么不同。感谢您的帮助。

require 'vendor/autoload.php';
require 'functions/general.php';
require 'include/mailgun.php';

function my_autoloader($class) {
    require 'classes/' . $class . '.php';
}
spl_autoload_register('my_autoloader');

嗯,实际上作曲家利用 spl_autoload_register,所以答案是 'yes',他们可以。 autoloader stack 支持自动加载机制 - 基本上,如果 class 在一个自动加载器被 运行 后的 运行 时间内没有出现,下一个一个被使用,直到栈 运行s out of autoloaders 并且 PHP 报告一个关于它找不到的 class 的错误。每个 spl_autoload_register 调用基本上都会添加新的自动加载器,因此内存中可能有很多自动加载器。这个故事的要点是无法加载的自动加载器class什么都不做,自动加载代码块没有采取任何行动就结束了,因此下一个自动加载器可能会负责class加载中。您唯一需要实现的是检查您的自动加载器它可以处理当前的 class 加载(在需要它之前检查该文件是否存在就足够了,尽管您应该考虑在命名空间的情况下可能的目录嵌套),以及所有内容以后应该能顺利工作:

function my_autoloader($class) {
    $path = sprintf('classes/%s.php', $class);
    if (file_exists($path)) {
        require 'classes/' . $class . '.php';
    }
}

如果这是一个小项目,其中包含两个或三个文件夹中的文件,您可以使用简单的 if 语句。

function my_autoloader($class) {
    if(file_exists('functions/'.$class.'.php')){
      require 'functions/'$class.'.php';
    } else if(file_exists('vendor/'.$class.'.php')){
      require 'vendor/'.$class.'.php';
    } //add more as needed
}
spl_autoload_register('my_autoloader');

对于较大的应用程序,我建议为您的 classes 文件和 classes 命名它们的内容或用途,并按照它们的名称将它们放在特定的文件夹中示例:controllers/userController.php for userController class functions/generalFunctions.php generalFunctions class 然后你可以检查名称,如果它有控制器那么你从控制器中包含它文件夹。在 my_autoloader 函数中或在单独的文件中创建一个数组,如.

loadMap.php

return [
   'controller' => 'path/to/controllers/',
   'function' => 'path/to/functions/',
   'helper' => 'path/to/helpers',
   'etc' => 'path/to/etc/'
]

filewithautoloadfunction.php

function my_autoloader($class){
  $loadMap = require 'path/to/loadMap.php';

  foreach($loadMap as $key => $path){
   if(stripos($key, $class){
    require_once $path.$class.'.php';
   }
  }
}

spl_autoload_register('my_autoloader');

根据@Etki 和@Sarah Wilson 给我的想法进行进一步研究后,我提出了以下解决方案。谢谢你们的意见。

require 'vendor/autoload.php';
require 'functions/general.php';
require 'include/mailgun.php';


function autoLoader ($class) {
  if (file_exists(__DIR__.'/classes/'.$class.'.php')) {
    require __DIR__.'/classes/'.$class.'.php';
  }
}
spl_autoload_register('autoLoader');

提示:我在 autoLoader 函数中将 __DIR__ 添加到文件路径的开头。