spl_autoload с пространством имен php

Я делаю небольшую структуру для запланированной работы, которая запускается внешним процессом nodejs. Я хотел бы использовать автозагрузчик, но по какой-то причине данные не доходят до него. Я также использую пространства имен. Вот как выглядит структура моей папки:

Library
  |_ Core
     |_ JobConfig.php
  |_ Utilities
     |_ Loader.php
  |_ Scheduled
     |_ SomeJob.php
  |_ Config.php

мой Config.php просто есть некоторые определения и экземпляр моего Loader.php,

Loader.php выглядит так:

public function __constructor()
{
    spl_autoload_register(array($this, 'coreLoader'));
    spl_autoload_register(array($this, 'utilitiesLoader'));
}

private function coreLoader($class)
{
    echo $class;
    return true;
}

private function utilitiesLoader($lass)
{
    echo $class;
    return true;
}

Так что для моего SomeJob.php Я в том числе Config.php и затем попытайтесь создать экземпляр JobConfig.php, если он не работает. Мои пространства имен похожи Library\Core\JobConfig и так далее. Я не уверен, что это лучший подход без возможности загружать вещи. Но я не вижу эхо от загрузчика, пока он не вышел из строя.

Редактировать:

Я попробовал sugestion от @Layne, но не сработало. Я все еще получаю класс, не найденный, и кажется, что класс не попал в стек spl. Вот ссылка на код

2 ответа

Решение

Если вы на самом деле используете пространства имен так же, как вы используете структуру каталогов, это должно быть довольно просто.

<?php
namespace Library {
    spl_autoload_register('\Library\Autoloader::default_autoloader');

    class Autoloader {
        public static function default_autoloader($class) {
            $class = ltrim($class, '\\');

            $file = __DIR__ . '/../';
            if ($lastNsPos = strrpos($class, '\\')) {
                $namespace = substr($class, 0, $lastNsPos);
                $class     = substr($class, $lastNsPos + 1);
                $file .= str_replace('\\', '/', $namespace) . '/';
            }

            $file .= $class . '.php';
            include $file;
        }
    }
}

Поместите это в свой каталог библиотеки и потребуйте его на более высоком уровне. Надеюсь, я этого не испортил, не проверял.

РЕДАКТИРОВАТЬ: фиксированный путь.

Используйте этот класс для индексации вашего проекта, просто замените WP_CONTENT_DIR с другим уровнем каталогов для сканирования php-файлов этот класс автоматически включает файлы:

    <?php

class autoloader
{

    public static function instance()
    {
        static $instance = false;
        if( $instance === false )
        {
            // Late static binding
            $instance = new static();
        }

        return $instance;
    }

    /**
     * @param $dir_level directory level is for file searching
     * @param $php_files_json_name name of the file who all the PHP files will be stored inside it
     */
    private function export_php_files($dir_level, $php_files_json_name)
    {

        $filePaths = array(mktime());
        /**Get all files and directories using iterator.*/
        $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir_level));

        foreach ($iterator as $path) {
            if (is_string(strval($path)) and pathinfo($path, PATHINFO_EXTENSION) == 'php') {
                $filePaths[] = strval($path);
            }
        }

        /**Encode and save php files dir in a local json file */
        $fileOpen = fopen($dir_level . DIRECTORY_SEPARATOR . $php_files_json_name, 'w');
        fwrite($fileOpen, json_encode($filePaths));
        fclose($fileOpen);
    }

    /**
     * @param $php_files_json_address json file contains all the PHP files inside it
     * @param $class_file_name name of the class that was taken from @spl_autoload_register_register plus .php extension
     * @return bool Succeeding end of work
     */
    private function include_matching_files($php_files_json_address, $class_file_name)
    {
        static $files;
        $inc_is_done = false;

        if ($files == null) {
            $files = json_decode(file_get_contents($php_files_json_address), false);
        }

        /**Include matching files here.*/
        foreach ($files as $path) {
            if (stripos($path, $class_file_name) !== false) {
                require_once $path;
                $inc_is_done = true;
            }
        }
        return $inc_is_done;
    }

    /**
     * @param $dir_level directory level is for file searching
     * @param $class_name name of the class that was taken from @spl_autoload_register
     * @param bool $try_for_new_files Try again to include new files, that this feature is @true in development mode
     * it will renew including file each time after every 30 seconds @see $refresh_time.
     * @return bool Succeeding end of work
     */
    public function request_system_files($dir_level, $class_name, $try_for_new_files = false)
    {
        $php_files_json = 'phpfiles.json';
        $php_files_json_address = $dir_level . DIRECTORY_SEPARATOR . $php_files_json;
        $class_file_name = $class_name . '.php';
        $files_refresh_time = 30;

        /**Include required php files.*/
        if (is_file($php_files_json_address)) {

            $last_update = json_decode(file_get_contents($php_files_json_address), false)[0];

            if ((mktime() - intval($last_update)) < $files_refresh_time || !$try_for_new_files) {
                return $this->include_matching_files($php_files_json_address, $class_file_name);
            }

        }

        $this->export_php_files($dir_level, $php_files_json);
        return $this->include_matching_files($php_files_json_address, $class_file_name);

    }

    /**
     * Make constructor private, so nobody can call "new Class".
     */
    private function __construct()
    {
    }

    /**
     * Make clone magic method private, so nobody can clone instance.
     */
    private function __clone()
    {
    }

    /**
     * Make sleep magic method private, so nobody can serialize instance.
     */
    private function __sleep()
    {
    }

    /**
     * Make wakeup magic method private, so nobody can unserialize instance.
     */
    private function __wakeup()
    {
    }


}

/**
 * Register autoloader.
 */
try {
    spl_autoload_register(function ($className) {
        $autoloader = autoloader::instance();

        return $autoloader->request_system_files(WP_CONTENT_DIR, $className, true);
    });
} catch (Exception $e) {
    var_dump($e);
    die;
}
Другие вопросы по тегам