tutorials.de Buch-Aktion 05/2012
Like Tree1Danke
  • 1 Beitrag von ZodiacXP
ERLEDIGT
JA
ANTWORTEN
6
ZUGRIFFE
253
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    Tim Bureck Tim Bureck ist offline Mitglied Platin
    Registriert seit
    Apr 2009
    Ort
    Düsseldorf (NRW)
    Beiträge
    508
    Hallo zusammen,

    folgendes Problem: Ich habe eine Klasse, die ein Interface implementiert. Allerdings bekomme ich sobald ich eine Instanz dieser Klasse erstellen möchte den folgenden Fehler:

    Fatal error: Interface 'Command' not found
    Soweit kein Problem, die Definitionen stehen ja auch nicht in derselben Datei und es gibt keine Includes. Allerdings habe ich eine Autoload-Funktion geschrieben, die auch funktioniert:

    PHP-Code:
    function __autoload($className) {
        
    searchClass(CSMTOOLS_DIR.'/library'$className);
    }

    function 
    searchClass($dir$className) {
        if(!
    is_dir($dir)) {
            return 
    false;
        }

        
    $dirInputHandler opendir($dir);
        
    $dirContent scandir($dir);

        while((
    $dirElement readdir($dirInputHandler)) !== false) {
            if(
    $dirElement != "." && $dirElement != ".."
                    
    && $dirElement != ".svn"
                    
    && is_dir($dir."/".$dirElement)) {
                if (
    searchClass($dir."/".$dirElement$className)) {
                    return 
    true;
                }
            } elseif(
    $dirElement != "." && $dirElement != "..") {
                if(
    preg_match("/".$className.".class.php/",
                        
    $dir."/".$dirElement) > 0) {
                    require_once 
    $dir."/".$dirElement;
                    return 
    true;
                }
            }
        }

        
    closedir($dirInputHandler);
        return 
    false;

    Woher weiß ich das? Vorher wurden auch schon Klassen mittels Autoloader geladen. Sobald ich aber an diese Stelle komme:

    PHP-Code:
    abstract class BlockCommand implements Command {
        ...

    tritt der Fehler auf. Die Frage nun:

    Warum klappt das Autoloading hier nicht?

    PS: Die Datei Command.class.php existiert natürlich inklusive des Interfaces Command
     

  2. #2
    Tim Bureck Tim Bureck ist offline Mitglied Platin
    Registriert seit
    Apr 2009
    Ort
    Düsseldorf (NRW)
    Beiträge
    508
    Wenn bis heute Abend niemand eine Idee hat, stelle ich mal mehr Source zu Verfügung.

    Hat vielleicht noch jemand eine Idee wo man sich da schlau machen könnte?
     

  3. #3
    Registriert seit
    Mar 2004
    Beiträge
    1.856
    Blog-Einträge
    2
    Schreibe deine "Funktion" einfach mal in __autoload direkt rein.
    Könnte sein das der Gültigkeitsbereich für das require sich auf die Funktion beschränkt.

    EDIT: Hier noch was zum lesen. Autoload hat Probleme bei extends etc: http://bugs.php.net/bug.php?id=44848
    Geändert von ZodiacXP (04.05.09 um 11:51 Uhr)
     
    Gebe keine Hilfe per PN, Mail, Instant Messenger etc.
    und keine Copy&Paste-Lösungen - ein bisschen selbst nachdenken sollte drin sein. Konstruktivismus 4tw!


    MfG, Zod

    __________________
    rpd Framework: Rapid Web-Engineering in PHP (Manual | Google Code)

  4. #4
    Avatar von Flex
    Flex Flex ist offline (aka Felix Jacobi)
    tutorials.de Moderator
    Registriert seit
    Nov 2001
    Ort
    Wuppertal
    Beiträge
    5.295
    Blog-Einträge
    65
    Das Problem hatte ich auch letztens und bekam es auch nicht durch die autoload Methode gelöst...

    Das Problem scheint irgendein Verzeichniskonflikt zu sein.
    Denn selbst wenn bei mir das Interface auf der gleichen Ebene lag wie die Klasse hat meine autoload Funktion nicht das geladen was ich wollte...

    Ich inkludiere die Dateien jetzt in der Klasse und lade sie nicht dynamisch nach.
     
    KIDS Kinderbetreuungsdienst
    Xing

    "When you play the game of thrones, you win or you die. There is no middle ground."
    by Cersei Lannister in "A Game Of Thrones"

  5. #5
    Tim Bureck Tim Bureck ist offline Mitglied Platin
    Registriert seit
    Apr 2009
    Ort
    Düsseldorf (NRW)
    Beiträge
    508
    Zum Haare raufen.. der Bugreport hat mich nochmal dazu bewegt den Debugger anzuwerfen, der Fehler ist gefunden. Und zwar hat die searchClass($dir, $className) einen kleinen Schönheitsfehler:

    PHP-Code:
    if(preg_match("/".$className.".class.php/",
        
    $dir."/".$dirElement) > 0) { 
    Eigentlich wird zuerst die Klasse InlineCommand, die ebenfalls das Interface Command implementiert, geladen. Nun stößt PHP bereits auf dieses Interface und lädt es. Der reguläre Ausdruck prüft allerdings noch nicht genau genug und findet zuerst... genau, die BlockCommand.class.php.

    Und genau an dieser Stelle ist dann der Fehler aufgetreten, da auf einmal wieder das Interface Command auftritt, aber er denkt wohl, dass er das gerade lädt.

    Die Lösung des Problems ist dann recht simpel:

    PHP-Code:
    if(preg_match("@/".$className.".class.php$@",
        
    $dir."/".$dirElement) > 0) { 
    Ich überprüfe nun wirklich ob es genau die Datei ist, indem ich ein / voranstelle. Mit dem Dollar am Ende stelle ich noch sicher, dass nicht vielleicht ein Verzeichnis so heißt.

    Das war aber auch mal ein blöder Fehler.. Vielen Dank jedenfalls für die Hinweise.
     

  6. #6
    Registriert seit
    Mar 2004
    Beiträge
    1.856
    Blog-Einträge
    2
    Für die Performance noch:
    PHP-Code:
    if (strpos($dir."/".$dirElement"/".$className.".class.php) !== false) 
    Und noch besser:
    Es gibt die Funktion glob, damit kannst du quasi im Verzeichnis direkt suchen:
    http://de.php.net/manual/de/function.glob.php

    Und die Krönung:
    Der DirectoryIterator von PHP:
    http://de.php.net/manual/de/class.directoryiterator.php
    Tim Bureck bedankt sich. 
    Gebe keine Hilfe per PN, Mail, Instant Messenger etc.
    und keine Copy&Paste-Lösungen - ein bisschen selbst nachdenken sollte drin sein. Konstruktivismus 4tw!


    MfG, Zod

    __________________
    rpd Framework: Rapid Web-Engineering in PHP (Manual | Google Code)

  7. #7
    Tim Bureck Tim Bureck ist offline Mitglied Platin
    Registriert seit
    Apr 2009
    Ort
    Düsseldorf (NRW)
    Beiträge
    508
    Okay, danke! Schade, dass der DirectoryIterator nicht soo gut dokumentiert ist, aber das werd ich wohl auch noch hinbekommen. Die Optimierungen kommen allerdings erst später, erstmal soll alles so weit funktionieren.. und damit ich es nicht vergesse wird ein TODO rein geschrieben.

    *als erledigt markier*
    Geändert von Tim Bureck (04.05.09 um 18:26 Uhr) Grund: ich werd's noch hinbekommen, noch!! ;)