11 Stimmen

Namespace Autoload funktioniert unter Windows, aber nicht unter Linux

Ich habe den folgenden php-Code:

index.php

<?php
spl_autoload_extensions(".php");
spl_autoload_register();

use modules\standard as std;

$handler = new std\handler();
$handler->delegate();
?>

Module \standard\handler.php

<?php
namespace modules\standard {
    class handler {
        function delegate(){
            echo 'Hello from delegation!';
        }
    }
}
?>

Unter Windows 7 mit WAMP erzeugt der Code die Meldung "Hello from Delegation!", aber unter Linux erhalte ich folgende Meldung:

Schwerwiegender Fehler: spl_autoload(): Klasse Module \standard\handler konnte nicht geladen werden in /var/www/index.php in Zeile 15

Unter Windows läuft PHP 5.3.0 unter WAMP, und unter Linux läuft das 5.3.2 dotdeb-Paket unter Ubuntu 9.10.

Ist dies ein Konfigurationsproblem auf meiner Linux-Box oder nur ein Unterschied in der Art und Weise, wie Namespaces und Autoloading auf den verschiedenen Betriebssystemen gehandhabt wird

4voto

johannes Punkte 15447

Der SPL-Autoloader ist extrem primitiv - er kennt keine Namespaces, also versucht er, eine Datei mit \ im Namen zu laden, während unter Linux/Unix das Pfadseparator / und nicht .

3voto

imme Punkte 590

Herman Radtke sagt, er habe einen Patch eingereicht:

http://www.hermanradtke.com/blog/hidden-features-with-spl_autoload-and-namespaces/

s

Ich hoffe, dass es bald umgesetzt wird.

Im Moment verwende ich diesen Workaround:

<?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 );
?>

1voto

peternux Punkte 11
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');
        }
    }
}

1voto

the_nuts Punkte 4968
function __autoload($class_name)
{
    $class_name = strtolower(str_replace('\\', DIRECTORY_SEPARATOR, $class_name));

    include $class_name . '.php';
}

El srttolower wird beim Apache benötigt, da er (im Gegensatz zum IIS) case-sensitive ist.

1voto

Supun Kavinda Punkte 1034

Dies ist ein häufiges Problem, das beim automatischen Laden auftritt. Die Lösung ist die Verwendung der Konstante DIRECTORY_SEPARATOR in der Autoload-Funktion.

Ihre Autoload-Funktion wird also wie folgt aussehen

<?php

spl_autoload_register(function($className) {

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

});

Wenn Sie mehr über Namespace/Klassen-Autoloading erfahren möchten, besuchen Sie ici

Danke.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X