[OOP] Autoload und Interfaces

Parantatatam

mag Cookies & Kekse
Hallo Tutorianer,

ich bastle gerade an einem etwas umfangreicheren Autoloader, welcher aus den Namespaces und dem Klassennamen je den Dateipfad und Dateinamen ableiten soll, soweit kein Problem. Ich gehe aber noch einen Schritt weiter und verwende verschiedene Dateiendungen für "normale" Klassen, abstrakte Klassen und Interfaces. Dabei ist das Unterscheiden zwischen den Klassen kein Problem, da abstrakte Klassen mit Abstract im Namen anfangen. Leider scheitert es an den Interfaces. Diese sind zwar von meiner Namenskonvention her so aufgebaut, dass sie mit einem i anfangen, aber damit könnte auch eine "normale" Klasse anfangen.

Deshalb war meine Überlegung, dass man mit Klassenreflektion direkt beim Laden einer Klasse die zugehörigen Interfaces ermitteln könnte und diese dann nachgeladen werden. Soweit zur Theorie, nun zur Praxis: PHP springt, sobald er eine Klassendeklaration mit Interfaces sieht, wieder an den Anfang des Autoloaders und versucht das Interface genau wie eine Klasse zu laden, allerdings kann ich somit nicht kennzeichnen, dass es sich bei dem Aufruf um ein Interface handelt. Ich könnte zwar mit static ermitteln, ob ein Prozess vollständig ausgeführt wurde oder ob dazwischen gesprungen wurde, aber damit würde ich auch Vererbung abdecken und bei mehreren Interfaces alle nach dem zweiten ignorieren.

Eine Möglichkeit wäre jetzt die Klasse mit file() zu laden, auf den Beginn der Klasse zu warten und dann die Interfaces auslesen, was ich aber für eine sehr unsaubere Variante halte, welche durch den Gebraucht von namespace und use erschwert wird. Eine andere Möglichkeit wäre mehrere Autoload-Funktionen zu nutzen, welche aber auch zu Fehlinterpretationen führen würde.

Was ich bisher habe:
PHP:
class Autoload {
  public static function Library($class, $interface = false) {
    $modules = explode('\\', $class);
    
    array_walk($modules, function(&$module) {
      $module = underscore($module);
    }
    
    $filename  = array_pop($modules);
    $directory = implode('/', $modules);

    if($interface === true)
      $type = 'interface';
    elseif(strstr($filename, '_', true) === 'abstract')
      $type = 'abstract';
    else
      $type = 'class';
    
    $file = $directory . '/' . $filename . '.' . $type . '.php';
    
    if(file_exists($file) === false)
      return false;
    
    require_once $file;
    
    $interfaces = interfaces($class);
    
    array_walk($interfaces, function($interface) {
      Autoload::Library($interface, true);
    }
  }
}

Dabei lädt interfaces() die Interfaces einer geladenen Klasse und underscore() wandelt den Klassennamen in einen Dateinamen um nach dem Prinzip MeineKlasseBlub zu meine_klasse_blub.

Jedenfalls muss das noch anders gehen, denn wenn ein Interface nicht geladen werden kann, dann meldet PHP folgendes: Fatal error: Interface 'xxx' not found in xxx on line x
 
Zuletzt bearbeitet:
Zurück