Не получается сделать Autoload с Namespace, я допустил ошибку, но в упор не вижу: PHP: class NamespaceAutoloader { protected $namespacesMap = []; public function addNamespace($namespace, $rootDir) { if (is_dir($rootDir)) { $this->namespacesMap[$namespace] = $rootDir; return true; } return false; } public function register() { spl_autoload_register(array($this, 'autoload')); } protected function autoload($class) { $pathParts = explode('\\', $class); if (is_array($pathParts)) { $namespace = array_shift($pathParts); if (!empty($this->namespacesMap[$namespace])) { $filePath = $this->namespacesMap[$namespace] . '/' . implode('/', $pathParts) . '.php'; require_once $filePath; return true; } } return false; } } Потом Core: PHP: namespace Core; use \NamespaceAutoloader; session_start(); require_once( __DIR__ . '/Autoloader/AutoloaderNameSpace.php' ); $load=new NamespaceAutoloader(); require_once( __DIR__ . '/classes.php' ); classes.php: PHP: $load->addNamespace('test', __DIR__ . '/base/test'); $load->register(); test.php PHP: <? namespace test; class Admin { public function test() { echo "1"; } } index.php PHP: <?include($_SERVER['DOCUMENT_ROOT'].'/system/core/core.php'); Admin::test(); И ошибка: Fatal error: Uncaught Error: Class 'Admin' not found in E:\Server\OpenServer\domains\local.vixed.ru\index.php:3 Stack trace: #0 {main} thrown in E:\Server\OpenServer\domains\local.vixed.ru\index.php on line 3
Посмотри готовый PSR для авто загрузки или через composer. Как Admin должен найтись если он в test namespace? --- Добавлено --- Не надо использовать одинарные <? вместо них <?php, ну исключение для короткой записи echo: <?=$string?>
PHP: <?php # P.s: Заготовка для головастых - не стоит упоминать об отдельных файлов для каждого пространства namespace Aero { class AeroBase { protected static $NAMESPACESMAP = [ App\Application::class => 'Application\C.Application' ]; public static function setPatchMap( string $NAME, string $PATCH ) { self::$NAMESPACESMAP[$NAME] = $PATCH; } public static function autoload( $CLASS ) { if (1) { echo "{$CLASS}<br>" . PHP_EOL; } if ( isset ( self::$NAMESPACESMAP[$CLASS] ) ) { $CLASS = self::$NAMESPACESMAP[$CLASS]; } include dirname ( __FILE__ ) . DIRECTORY_SEPARATOR . strtr ( $CLASS, '\\', DIRECTORY_SEPARATOR ) . '.php'; } } } namespace { spl_autoload_register ( [ \Aero\AeroBase::class, 'autoload' ] ); }
@MouseZver, а теперь можешь объяснить что да как? --- Добавлено --- В ключе ты использовал NameSpace и название класса, а где значение - путь?
Проблема в том, что не работает. PHP: protected static $NAMESPACESMAP = [ Example\ex1::exs => __DIR__ . 'classes_example/ex1.php' ]; PHP: <?//Example #1; namespace Example\ex1; class exs { public static function test() { echo '1'; } } PHP: <?include('namespace.php'); Exs::test(); Код (Text): Exs Aero\Example\ex1 Warning: include(E:\Server\OpenServer\domains\zagotovkis.ru\load_class_namespace\Aero\Example\ex1.php): failed to open stream: No such file or directory in E:\Server\OpenServer\domains\zagotovkis.ru\load_class_namespace\namespace.php on line 28 Warning: include(): Failed opening 'E:\Server\OpenServer\domains\zagotovkis.ru\load_class_namespace\Aero\Example\ex1.php' for inclusion (include_path='.;e:/server/openserver/modules/php/PHP-7;e:/server/openserver/modules/php/PHP-7/PEAR/pear') in E:\Server\OpenServer\domains\zagotovkis.ru\load_class_namespace\namespace.php on line 28 Fatal error: Class 'Aero\Example\ex1' not found in E:\Server\OpenServer\domains\zagotovkis.ru\load_class_namespace\namespace.php on line 23 Если сделать так: \Example\ex1::exs => __DIR__ . 'classes_example/ex1.php' Та же проблема будет.
тестируй как работает наймспейс. Далеко до них как и с тривиальным понятием директорий. Если ложить большой болт на прочтение ошибок, то с таким же успехом можно положить на программирование и идти гамать дальше в игрушки. --- Добавлено --- я не даром прописал пару строк чтобы следить кто что юзнулся PHP: if (1) { echo "{$CLASS}<br>" . PHP_EOL; } --- Добавлено --- namespace Aero; PHP: protected static $NAMESPACESMAP = [ App\Application::class => 'Application\C.Application' ]; App\Application::class - Да, пространство с классом Application Приставка ::class говорит о том что нужно погуглить и прочесть для любопытства "чейт за хрень ?". Данная хрень наследует нынешнее пространство Аеро, тобишь получается автодобавление 'Aero\App\Application' 'Application\C.Application' - Сам путь к классу. Недаром: PHP: if ( isset ( self::$NAMESPACESMAP[$CLASS] ) ) { $CLASS = self::$NAMESPACESMAP[$CLASS]; } И в итоге подключается файл с классом PHP: <?php namespace Aero\App; class Application { }
@MouseZver, но если все классы лежат в одной директории распиханные по папкам с именами своих namespace разве не достаточно одной функции автолоада?
@MouseZver, Я делаю так: - есть в public директории файл config.php в нем строчки PHP: define('FILES', '/home/бла-бла-бла/files/'); spl_autoload_register(function ($some_class) { $some_path = preg_replace('{^\/}', '', strtolower(str_replace('\\', '/', $some_class))); require_once(FILES . 'engin/' . $some_path . '.class.php'); }); - есть три точки входа index.php, ajax.php и get_photo.php - в точках входа реквирю config.php - далее нужно заботиться только о пространствах имен, местоположении и именах самих файлов классов и забыть про автолоад Чем этот метод хуже? Я реально не знаю. Без подвоха. Прошу объяснить зачем нужна регистрация классов в отдельный массив?
тем что ты не сможешь отвязать от пространств и директории. Может класс вовсе лежит в корневом каталоге сайта, но пространство у него совсем другое. использование функций preg_replace strreplace + подключение через require_once - "у тебя ошибку должно выдавать" = Не гуд. --- Добавлено --- не нужна, а возможность - приоритет не слишком велик. Если не зарегистрировано пространство, то оно используется как путь к классу --- Добавлено --- допустим наш класс лежит в папке Application/CMain.php Пространство у него App; class: Main PHP: $A = new \App\Main; Коротко и ясно --- Добавлено --- PHP: [ 'App\Main' => 'Application\CMain' ] --- Добавлено --- Пространство(Любое) => директория
Я не использую другие директории. Все пространства имен совпадают с именами папок. Про replace понятно, но не критично. С include, как раз тоже будет ошибка если класс так и не будет инициализирован. Если использовать больше одной функции, то тут include - я согласен. Как я понял подобный класс удобен если есть несколько разных директорий для классов не связанных именами с пространством имен?
Я о том что есть стек автолоад-функций. Если функций больше чем одна, а нужный файл загрузит не первая функция, тогда require остановит выполнение кода. Если она одна, как в моем случае, то require выдаст ошибку, что файл не найден, а с include будет фатальная ошибка, если файл с классом не найдется и класс не будет инициализирован. В моем случае include и require одинаково отработают. Будет только разница в логах ошибок.
@MouseZver. почему-то я сделал так: Структура: -Application --C.Application.php index.php namespace.php namespace.php: PHP: <?php namespace Aero { class AeroBase { protected static $NAMESPACESMAP = [ App\Application::class => 'Application\C.Application' ]; public static function setPatchMap( string $NAME, string $PATCH ) { self::$NAMESPACESMAP[$NAME] = $PATCH; } public static function autoload( $CLASS ) { if (1) { echo "{$CLASS}<br>" . PHP_EOL; } if ( isset ( self::$NAMESPACESMAP[$CLASS] ) ) { $CLASS = self::$NAMESPACESMAP[$CLASS]; } include dirname ( __FILE__ ) . DIRECTORY_SEPARATOR . strtr ( $CLASS, '\\', DIRECTORY_SEPARATOR ) . '.php'; } } } namespace { spl_autoload_register ( [ \Aero\AeroBase::class, 'autoload' ] ); } C.Application.php: PHP: <?php namespace Aero\App; class Application { public function p() { echo "1"; } } index.php PHP: <?php include('namespace.php'); App\Application::p(); --- Добавлено --- Все равно ошибки: Warning: include(E:\Server\OpenServer\domains\zagotovkis.ru\load_class_namespace\App\Application.php): failed to open stream: No such file or directory in E:\Server\OpenServer\domains\zagotovkis.ru\load_class_namespace\namespace.php on line 29 Warning: include(): Failed opening 'E:\Server\OpenServer\domains\zagotovkis.ru\load_class_namespace\App\Application.php' for inclusion (include_path='.;e:/server/openserver/modules/php/PHP-7;e:/server/openserver/modules/php/PHP-7/PEAR/pear') in E:\Server\OpenServer\domains\zagotovkis.ru\load_class_namespace\namespace.php on line 29 Fatal error: Uncaught Error: Class 'App\Application' not found in E:\Server\OpenServer\domains\zagotovkis.ru\load_class_namespace\index.php:4 Stack trace: #0 {main} thrown in E:\Server\OpenServer\domains\zagotovkis.ru\load_class_namespace\index.php on line 4