У меня есть следующий код php:
index.php
<?php spl_autoload_extensions(".php"); spl_autoload_register(); use modules\standard as std; $handler = new std\handler(); $handler->delegate(); ?>
модули \ стандартной \ handler.php
<?php namespace modules\standard { class handler { function delegate(){ echo 'Hello from delegation!'; } } } ?>
В Windows 7, запущенной WAMP, код выдает сообщение «Привет от делегирования!». однако под Linux я получаю следующее:
Неустранимая ошибка: spl_autoload (): Модули классов \ standard \ handler не могут быть загружены в /var/www/index.php в строке 15
Windows работает под управлением PHP 5.3.0 под WAMP, а Linux работает с пакетом 5.3.2 dotdeb под Ubuntu 9.10.
Является ли это проблемой конфигурации в моем Linux-модуле или просто разница в том, как пространства имен и автозагрузка обрабатываются в разных операционных системах
Автозагрузчик SPL чрезвычайно примитивен – он не знает пространства имен, поэтому он пытается загрузить файл с именем \ in, а в Linux / Unix – разделитель путей / нет.
Герман Радтке говорит, что он представил патч:
http://www.hermanradtke.com/blog/hidden-features-with-spl_autoload-and-namespaces/
: s
Я надеюсь, что это будет реализовано в ближайшее время.
Пока я использую это обходное решение:
<?php set_include_path( './classes/' . PATH_SEPARATOR . get_include_path() ); spl_autoload_extensions( '.php , .class.php' ); spl_autoload_register(); function linux_namespaces_autoload ( $class_name ) { /* use if you need to lowercase first char * $class_name = implode( DIRECTORY_SEPARATOR , array_map( 'lcfirst' , explode( '\\' , $class_name ) ) );/* else just use the following : */ $class_name = implode( DIRECTORY_SEPARATOR , explode( '\\' , $class_name ) ); static $extensions = array(); if ( empty($extensions ) ) { $extensions = array_map( 'trim' , explode( ',' , spl_autoload_extensions() ) ); } static $include_paths = array(); if ( empty( $include_paths ) ) { $include_paths = explode( PATH_SEPARATOR , get_include_path() ); } foreach ( $include_paths as $path ) { $path .= ( DIRECTORY_SEPARATOR !== $path[ strlen( $path ) - 1 ] ) ? DIRECTORY_SEPARATOR : ''; foreach ( $extensions as $extension ) { $file = $path . $class_name . $extension; if ( file_exists( $file ) && is_readable( $file ) ) { require $file; return; } } } throw new Exception( _( 'class ' . $class_name . ' could not be found.' ) ); } spl_autoload_register( 'linux_namespaces_autoload' , TRUE , FALSE ); ?>
function __autoload($class_name) { $paths[] = dirname(__FILE__) . "/../libs/misc/"; $paths[] = dirname(__FILE__) . "/../../libs/misc/"; $paths[] = dirname(__FILE__) . "/../../libs/helpers/"; $paths[] = dirname(__FILE__) . "/../../libs/simpleimage/"; foreach($paths as $path) { if(file_exists($path.strtolower($class_name).'.class.php')){ require_once($path.strtolower($class_name).'.class.php'); } } }
function __autoload($class_name) { $class_name = strtolower(str_replace('\\', DIRECTORY_SEPARATOR, $class_name)); include $class_name . '.php'; }
srttolower
на Apache, потому что это (в отличие от IIS) случайный.
Это обычная проблема возникает при автозагрузке. Исправление состоит в использовании константы DIRECTORY_SEPARATOR в функции автозагрузки.
Таким образом, ваша функция автозагрузки будет выглядеть следующим образом.
<?php spl_autoload_register(function($className) { $className = str_replace("\", DIRECTORY_SEPARATOR, $className); include_once $_SERVER['DOCUMENT_ROOT'] . '/class/' . $className . '.php'; });
Если вам нужно больше узнать об автозагрузке пространства имен / класса, посетите здесь
Благодарю.