[spl_autoload()] Format der Pfadangabe für set_include_path()

Raisch

extraordinary bit
Hallo Community,

ich habe bis heute __autoload() zum einbinden meiner Klassen verwendet und wollte jetzt auf spl_autoload() umsteigen. Dies gestaltet sich nun doch schwieriger als erwartet.

Nun ist meine Frage, gibt es für set_include_path() ein vorgeschriebenes Format wie der Pfad anzugeben ist?

Ich habe mir zu allen Funktionen das Manual angeschaut und keine befriedigende Antwort gefunden, evtl könnt ihr mich ja erleuchten. :D

Meine Autoloadklasse sieht im Moment so aus:
PHP:
abstract class RsAutoLoad
{
    private static $path = null;
    private static $ext = null;

    public static function init()
    {
        self::$path = array (
            'class'     => './.include/class/',
            'abstract'  => './.include/class/abstract/',
            'interface' => './.include/class/interface/'
        );
        self::$ext = array (
            'class'     => '.class.php',
            'abstract'  => '.abstract.php',
            'interface' => '.interface.php'
        );

        spl_autoload_register( 'RsAutoLoad::loadClass' );
        spl_autoload_register( 'RsAutoLoad::loadAbstact' );
        spl_autoload_register( 'RsAutoLoad::loadInterface' );
    }

    public static function loadClass( $class )
    {
        set_include_path(
            self::$path['class'].PATH_SEPARATOR.get_include_path()
        );
        spl_autoload_extensions( self::$ext['class'] );
        spl_autoload( $class );
    }

    public static function loadAbstact( $class )
    {
        set_include_path(
            self::$path['abstract'].PATH_SEPARATOR.get_include_path()
        );
        spl_autoload_extensions( self::$ext['abstract'] );
        spl_autoload( $class );
    }

    public static function loadInterface( $class )
    {
        set_include_path(
            self::$path['interface'].PATH_SEPARATOR.get_include_path()
        );
        spl_autoload_extensions( self::$ext['interface'] );
        spl_autoload( $class );
    }
}

RsAutoLoad::init();

Gruß
 
Zuletzt bearbeitet:
Die einzige Vorgabe ist, das Pfad-Angaben durch den PATH_SEPARATOR zu trennen sind, der auch gleich das Betriebssystem-spezifische Charakter enthält. Du kannst also den Include-Path mit einem Implode auf dein self::$path anwenden (habe implode noch nie auf assoziative Array angewendet, könnte also falsch sein, aber im Manual gibts dafür sicher ne Lösung bei den Hints):

PHP:
    public static function init()
    {
        self::$path = array (
            'class'     => './.include/class/',
            'abstract'  => './.include/class/abstract/',
            'interface' => './.include/class/interface/'
        );
        self::$ext = array (
            'class'     => '.class.php',
            'abstract'  => '.abstract.php',
            'interface' => '.interface.php'
        );

        spl_autoload_register( 'RsAutoLoad::loadClass' );
        spl_autoload_register( 'RsAutoLoad::loadAbstact' );
        spl_autoload_register( 'RsAutoLoad::loadInterface' );

        set_include_path( get_include_path() . PATH_SEPARATOR . 
                implode(PATH_SEPARATOR, self::$path) );
    }
 
Die einzige Vorgabe ist, das Pfad-Angaben durch den PATH_SEPARATOR zu trennen sind, der auch gleich das Betriebssystem-spezifische Charakter enthält. Du kannst also den Include-Path mit einem Implode auf dein self::$path anwenden (habe implode noch nie auf assoziative Array angewendet, könnte also falsch sein, aber im Manual gibts dafür sicher ne Lösung bei den Hints):

Das mit dem PATH_SEPARATOR ist mir durchaus klar, dies habe ich ja so, wie oben im Code zu sehen, schon umgesetzt.

Desweiteren möchte ich auch nicht immer alle drei Pfade in den include-Pfad speichern, weshalb ich das auch in die jeweiligen Methoden ausgelagert habe und nicht in init() aufrufe.

Ich denke, ich sollte meine Frage(n) etwas konkretisieren:
Das ich relative Pfade verwenden kann weiß ich. Wie aber sollte dieser aussehen?
  1. ./pfad/zum/ordner/
  2. ./pfad/zum/ordner
  3. /pfad/zum/ordner/
  4. /pfad/zum/ordner
  5. pfad/zum/ordner/
  6. pfad/zum/ordner
Muss die Pfadangabe relativ von der Datei in welcher er aufgerufen wird, relativ von Root der Webseite oder relativ vom Root meines Webspaces angegeben werden?
Root Webspace: /mmm/nn/foo/bar/htdocs/ (nicht über Browser erreichbar)
Root Webseite: /mmm/nn/foo/bar/htdocs/raisch/ (http://domain.tld)
Pfad der Datei: /mmm/nn/foo/bar/htdocs/raisch/v2/datei.php (http://domain.tld/v2/datei.php)

Oder sollte man den Pfad lieber absolut mit $_SERVER['DOCUMENT_ROOT'] angeben?

Gruß
 
Grundsätzlich bedeutet relativer Pfad immer relativ zur aktuellen Datei, also der Datei, in der der Include gemacht werden soll. Wenn du bspw. einen Ordner includes im DocRoot hast und einen modules ebenfalls im DocRoot, und in modules möchtest du einen Include auf eine Datei im Ordner includes machen, so musst du das über ../includes/datei.php machen, da ../includes nicht im INCLUDE_PATH ist.

Daher ist es ratsam, den absoluten Pfad zu includes zu verwenen, wie du es im letzten Absatz schon angedeutet hast. Denn dann brauchst du nur alle Ordner absolut in den INCLUDE_PATH mit aufnehmen, in denen inkludierbare Scripts drin sind, und brauchst dann im include() nur den Namen des jeweiligen Scripts (ohne Pfad) anzugeben.

Ich würde bei der Angabe der absoluten Verzeichnispfade darauf achten, möglichst die Pfade zuerst einzutragen, bei denen es am wahrscheinlichsten ist, dass das jeweilige Script gefunden wird, da im worst-case alle Pfade durchsucht werden müssen. Der erste Fund wird hergenommen, auch dieses sollte dir bewusst sein.

Ich hoffe, das war einigermaßen verständlich und nachvollziehbar.
 
Danke saftmeister,

diese Antwort war ausführlich und verständlich.

Ich habe das Problem gefunden, es hatte nur nichts mit dem Pfad zu tun. -.-

Das Problem war, da ich die Dateinamen der Klassen immer mit Groß- und Kleinbuchstaben erstelle (eben genau wie den Klassennamen), dadurch hat spl_autoload() die Dateien nicht gefunden. Es sind eben manchmal die kleinen Sachen die man im Manual überließt.

Ich habe nun alle Dateinamen in Kleinbuchstaben umgewandelt und es funktioniert.

Die Klasse habe ich noch minimal geändert:
PHP:
abstract class RsAutoLoad
{
    private static $path = null;
    private static $ext = null;

    public static function init()
    {
        $root = $_SERVER['DOCUMENT_ROOT'].'/raisch/v2/';

        self::$path = array (
            'class'     => $root.'.include/class/',
            'abstract'  => $root.'.include/class/abstract/',
            'interface' => $root.'.include/class/interface/'
        );
        self::$ext = array (
            'class'     => '.class.php',
            'abstract'  => '.abstract.php',
            'interface' => '.interface.php'
        );

        spl_autoload_register( 'RsAutoLoad::loadClass'     );
        spl_autoload_register( 'RsAutoLoad::loadAbstact'   );
        spl_autoload_register( 'RsAutoLoad::loadInterface' );
    }

    public static function loadClass( $class )
    {
        set_include_path(
            self::$path['class'].PATH_SEPARATOR.get_include_path()
        );
        spl_autoload_extensions( self::$ext['class'] );
        spl_autoload( $class );
    }

    public static function loadAbstact( $class )
    {
        set_include_path(
            self::$path['abstract'].PATH_SEPARATOR.get_include_path()
        );
        spl_autoload_extensions( self::$ext['abstract'] );
        spl_autoload( $class );
    }

    public static function loadInterface( $class )
    {
        set_include_path(
            self::$path['interface'].PATH_SEPARATOR.get_include_path()
        );
        spl_autoload_extensions( self::$ext['interface'] );
        spl_autoload( $class );
    }
}

RsAutoLoad::init();
Hat noch jemand eine Idee wie man das verbessern kann?

Gruß
 
Zurück