MB: Autoloader Klasse verstehen können?

moin community,

mich macht dieses Klassenkonstrukt stutzig.

class Autoloader {
  
  private function __construct() {
    spl_autoload_register( [ $this, 'load' ] );
  }
  
  public function register() : void {
    new Autoloader;
  }
  
  private function load( string $name ) : void {
    /* Code */
  }
}

Autoloader::register();

was mir klar ist:

  1. Die Klasse Autoloader wird mit öffentlicher Methode register() aufgerufen.
  2. Die Methode register() instanziiert ihre eigene Klasse Autoloader-Klasse (zu vergleichen mit Singleton nehme ich an)

Zur Frage:

  1. spl_autoload_register() benötigt ja callable Funktions-Objkte. Was hat ein numerisches Array mit Funktionsobjekten zutun und warum Funktioniert das [ $this, 'load' ]?
  2. Warum muss eine anonyme Instanz erzeugt werden damit Autoload funktioniert, warum reicht die Klassenmethode register() als aufruf nicht?

Ich habe die Sinnhaftigkeit von diesen Konstrukten nicht ganz verstanden :/.

vlg MB

  1. Tach!

    class Autoloader {
      
      private function __construct() {
        spl_autoload_register( [ $this, 'load' ] );
      }
      
      public function register() : void {
        new Autoloader;
      }
      
      private function load( string $name ) : void {
        /* Code */
      }
    }
    
    Autoloader::register();
    

    was mir klar ist:

    1. Die Klasse Autoloader wird mit öffentlicher Methode register() aufgerufen.

    Ja.

    1. Die Methode register() instanziiert ihre eigene Klasse Autoloader-Klasse (zu vergleichen mit Singleton nehme ich an)

    Was etwas umständlich ist, das so zu tun, aber auch nicht ganz schlecht. Doch dazu später mehr.

    register() sollte das Schlüsselwort static bekommen, denn das wird ja nur statisch aufgerufen. PHP5 würde das auch mit einer Strict-Meldung ahnden, PHP7 gar eine Deprecated-Warnung ausgeben.

    1. spl_autoload_register() benötigt ja callable Funktions-Objkte. Was hat ein numerisches Array mit Funktionsobjekten zutun und warum Funktioniert das [ $this, 'load' ]?

    Das ist die Art und Weise, wie man unter PHP die Methode einer Instanz als Callable/Callback übergibt: "A method of an instantiated object is passed as an array containing an object at index 0 and the method name at index 1." Anderweitig kann man keine Referenz auf eine Methode notieren.

    1. Warum muss eine anonyme Instanz erzeugt werden damit Autoload funktioniert, warum reicht die Klassenmethode register() als aufruf nicht?

    Man muss nicht (mehr), aber das ist eben eine mögliche Variante. Heutzutage könnte man in register direkt das spl_autoload_register() aufrufen und eine an Ort und Stelle definierte anonyme Funktion übergeben.

    class Autoloader {
      
      public function register() : void {
        spl_autoload_register( function ( string $name ) {
          /* Code */
        });
      }
      
    }
    

    Der Nachteil daran ist aber, dass die Verschachtlungstiefe steigt (hier aber nur um eine Ebene), und dass die Übergabe und das eigentliche Tun auf einem Haufen zu liegen kommt, statt getrennt abgelegt zu sein wie in der von dir gezeigten Lösung.

    Die Erstellung einer Klasse ist aber bei dieser Variante auch nicht wirklich erforderlich. Der Aufruf von spl_autoload_register() mit anonymer Funktion wäre ausreichend. Vielleicht wollte es der Autor nur besonders hübsch machen mit seinem Klassenkonstrukt.

    Eine Alternative, die nur mit statischen Methoden auskommt, wäre:

    class Autoloader {
      
      public static function register() : void {
        spl_autoload_register( [ 'Autoloader', 'load' ] );
        /* oder: spl_autoload_register( [ Autoloader::class, 'load' ] ); */
      }
      
      private static function load( string $name ) : void {
        /* Code */
      }
    }
    

    dedlfix.

    1. nabend dedlfix,

      herzlichen Dank! Ich habs verstanden!

      vlg MB