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;
}