PHP自动加载器类从两个或三个不同的路径加载文件

vah*_*hed 2 php autoloader

我正在学习使用php autuoloader...
据我所知,我们可以使用__autoloaderspl_autoloader_*自动加载文件.
假设这是我的目录结构:

ROOT
  |
  |
  ADMIN
  |  |
  |  |
  |  DIST
  |     |
  |     SOME_FOLDER
  |     SOME_FOLDER
  |  TPL
  |     |
  |     |
  |     SOME_FOLDER1
  |           |
  |           test.php
  |     SOME_FOLDER2
  |           |
  |           example1.php
  |           example2.php
  |           example3.php
  |
  |
  CLASSES
       |
       basics.php
       class1.php
       class2.php
       class3.php
       class4.php
  |
  index.php
Run Code Online (Sandbox Code Playgroud)


我为CLASSES目录中的自动加载文件创建了这个类:

basics.php:

class MyAutoLoader
{

    public function __construct()
    {

            spl_autoload_register( array($this, 'load') );

    }




    function load( $file )
    {
        //spl_autoload( 'load1' );

        echo 'Try to call  ' . $file . '.php inside ' . __METHOD__ . '<br>';

        require( $file . '.php' );

    }

}
Run Code Online (Sandbox Code Playgroud)

并在index.php我将包括basics.php和文件存储在CLASSES文件夹中的每件事都很好...

require_once("CLASSES/basics.php");
$loaderObject = new MyAutoLoader();
Run Code Online (Sandbox Code Playgroud)


与此代码,我可以宣布class1 ... class3
现在我想有一个autoloder这可能是加载文件SOME_FOLDER2在这种情况下是example1.php,example2.phpexample3.php

我尝试了一些案件,但在文件中SOME_FOLDER2使用自动加载不会加载.

我的尝试:

load2MyAutoLoader类中命名了一个尝试包含文件的函数SOME_FOLDER2

function load2( $file )
{
    //spl_autoload_register('load2');

    echo 'Inside LOADER2 ' . __METHOD__ . '<br>';

    require (  'ADMIN/TPL/' . $file . '.php' );

}
Run Code Online (Sandbox Code Playgroud)



我改变spl_autoload_registerMyAutoLoader构造函数:

$allMethods = get_class_methods( 'MyAutoLoader' );
$allMethods = array_splice( $allMethods, 1 );

foreach( $allMethods as $method )
{

    spl_autoload_register( array($this, $method) );

}
Run Code Online (Sandbox Code Playgroud)

但是没有一个对我不起作用......

请你告诉我我的代码有什么问题或者我对auloader的误解是什么?

Thanks in Advance

Mik*_*lRo 7

我认为你的问题基本上归结为不检查文件是否存在之前require...如果你试图包含的第一个文件夹中不存在该文件,则会产生致命错误.

我不知道你的用例,但这里有一些建议:

你能用一个自动加载器吗?

function my_autoload($class_name) {
    if (is_file('CLASSES/' . $class_name . '.php')) {
        require_once 'CLASSES/' . $class_name . '.php';
    } else if (is_file('ADMIN/TPL/SOME_FOLDER2/' . $class_name . '.php')) {
        require_once 'ADMIN/TPL/SOME_FOLDER2/' . $class_name . '.php';
    }
}
spl_autoload_register("my_autoload");
Run Code Online (Sandbox Code Playgroud)

或者,如果您需要独立声明它们(即两个或更多个自动加载器):

function classes_autoload($class_name) {
    if (is_file('CLASSES/' . $class_name . '.php')) {
        require_once 'CLASSES/' . $class_name . '.php';
    }
}
spl_autoload_register("classes_autoload");

function admin_autoload($class_name) {
    if (is_file('ADMIN/TPL/SOME_FOLDER2/' . $class_name . '.php')) {
        require_once 'ADMIN/TPL/SOME_FOLDER2/' . $class_name . '.php';
    }
}
spl_autoload_register("admin_autoload");
Run Code Online (Sandbox Code Playgroud)

或者使您的自动加载器类通用:

class MyAutoLoader {
    private $path;
    public function __construct($path) {
       $this->path = $path;
       spl_autoload_register( array($this, 'load') );
    }

    function load( $file ) {
        if (is_file($this->path . '/' . $file . '.php')) {
            require_once( $this->path . '/' . $file . '.php' );
        }
    }
}
$autoloader_classes = new MyAutoLoader('CLASSES');
$autoloader_admin = new MyAutoLoader('ADMIN/TPL/SOME_FOLDER2');
Run Code Online (Sandbox Code Playgroud)

如果你不想手动保持子文件夹列表是ADMIN/TPL最新的,你甚至可以做这样的事情来自动加载任何一个(这显然假设ADMIN/TPL包含类的所有子文件夹):

function my_autoload($class_name) {
    if (is_file('CLASSES/' . $class_name . '.php')) {
        require_once 'CLASSES/' . $class_name . '.php';
    } else {
        $matching_files = glob('ADMIN/TPL/*/' . $class_name . '.php');
        if (count($matching_files) === 1) {
            require_once $matching_files[0];
        } else if (count($matching_files) === 0) {
            trigger_error('Could not find class ' . $class_name . '!', E_USER_ERROR);
        } else {
            trigger_error('More than one possible match found for class ' . $class_name . '!', E_USER_ERROR);
        }
    }
}
spl_autoload_register("my_autoload");
Run Code Online (Sandbox Code Playgroud)