Автозагрузка пространства имен работает под Windows, но не в Linux - PullRequest
11 голосов
/ 19 мая 2010

У меня есть следующий 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 код выдает сообщение «Hello from Delegation!» однако под 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-бокса или разница в способах обработки пространств имен и автозагрузки в разных операционных системах

Ответы [ 5 ]

4 голосов
/ 20 мая 2010

Автозагрузчик SPL чрезвычайно примитивен - он не знает пространств имен, поэтому он пытается загрузить файл с \ в его имени, в то время как в Linux / Unix разделитель пути - это / нет.

3 голосов
/ 24 мая 2010

Герман Радтке говорит, что представил патч:

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 );
?>
1 голос
/ 20 декабря 2017

Это распространенная проблема, возникающая при автозагрузке. Исправление заключается в использовании константы DIRECTORY_SEPARATOR в функции автозагрузки.

Таким образом, ваша функция автозагрузки будет выглядеть следующим образом

<?php

spl_autoload_register(function($className) {

    $className = str_replace("\", DIRECTORY_SEPARATOR, $className);
    include_once $_SERVER['DOCUMENT_ROOT'] . '/class/' . $className . '.php';

});

Если вам нужно узнать больше о посещении автозагрузки пространства имен / класса здесь

Спасибо.

1 голос
/ 30 сентября 2014
function __autoload($class_name)
{
    $class_name = strtolower(str_replace('\\', DIRECTORY_SEPARATOR, $class_name));

    include $class_name . '.php';
}

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *.

1 голос
/ 01 февраля 2011
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');
        }
    }
}
...