Ankündigung

Einklappen
Keine Ankündigung bisher.

'use' keyword in Namespaces. Wie arbeitet er?

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • 'use' keyword in Namespaces. Wie arbeitet er?

    Hallo miteinander

    Ich möchte gerne genau verstehen wie in einer Datei eine bestimmte Klasse mittels 'use' statement gefunden wird.

    Gemäss der Doku und Google habe ich folgendes herausgefunden:

    -use importiert namespaces

    -Beliebig viele Importierungen möglich

    -Erstellt alias (auch „Importieren / Importregel“ genannt). Ähnlich wie einen symbolischen Link auf eine Datei oder ein Verzeichnis. Arten davon:
    --Klassenname
    ----use My\Full\Classname as Another
    --Globale Klasse importieren
    ----use ArrayObject
    --Namespace
    ----use My\Full\NSname; // Gleich wie My\Full\NSname as NSname
    --Interfacename
    --Funktionen (>= PHP 5.6)
    ----use function My\Full\functionName ; // Mit alias: My\Full\functionName as func
    --Konstanten (>= PHP 5.6)
    ----use const My\Full\CONSTANT


    Was ich immer noch nicht verstehe, wie wird jetzt eine Klasse gefunden? Werden verschiedene Such-Versuche gemacht? Wird zuerst der pseudo-Pfad im use statement mit der Dateien-Hierarchie abgeglichen, und wenn nichts gefunden wird, in allen PHP files nach einen Namespace gesucht der genau gleich benannt wurde (gemäss der Aussage 'use' importiert Namespaces), und diese Klasse darin zugänglich macht?

    Mich verwirrt das im ZendFramework2. Ich habe hier meinen Controller, im Dateikopf steht
    Code:
    namespace Objects\Controller;
    
    use Zend\Mvc\Controller\AbstractActionController;
    use Objects\Model\Objects;
    Der Pfad im oberen use Statement existiert in der Datei-Hierarchie ab hier: [ROOT]/vendor/ZF2/library/[hier]
    Und der Pfad im unteren use Statment ab hier: [ROOT]/module/Objects/src/[hier]

    Woher weiss 'use' wo er die Klasse findet?

  • #2
    PHP hat damit garnichts zutun. PHP bildet mithilfe der Use-Statements nur den kompletten Klassenpfad mit Namespace. Das laden der dazugehörigen Datei gibt er dann an den Autoloader weiter, welcher vom jeweiligen Framework zur Verfügung gestellt wird. Wie ZF2 das allerdings genau macht kann ich dir auch nicht sagen.
    [QUOTE=nikosch]Macht doch alle was Ihr wollt mit Eurem Billigscheiß. Von mir aus sollen alle Eure Server abrauchen.[/QUOTE]

    Kommentar


    • #3
      Zitat von tkausl Beitrag anzeigen
      PHP hat damit garnichts zutun. PHP bildet mithilfe der Use-Statements nur den kompletten Klassenpfad mit Namespace. Das laden der dazugehörigen Datei gibt er dann an den Autoloader weiter, welcher vom jeweiligen Framework zur Verfügung gestellt wird. Wie ZF2 das allerdings genau macht kann ich dir auch nicht sagen.
      Hallo tkausl

      Also wird intern das Statement im 'use' am Namespace als Suffix angehängt? Oder kannst du deinen ersten Satz noch genauer erklären?
      Ist das mit importieren gemeint, oder was ist genau damit gemeint?
      Ist es also nicht so das 'use' eine Datei zur Verfügung stellt ähnlich wie include?

      Kommentar


      • #4
        Klassen-Pfade ( des Namespaces ) werden von autoloadern in Dateipfade übersetzt. Damit man sich dabei nicht das Hemd zerreißt und Smilies auf die Nasenflügel malt nimmt man dazu einen fertigen Autoloader. Composer bringt einen mit:

        https://getcomposer.org/doc/01-basic...md#autoloading

        Es gibt Autoloader Standards, im moment ist PSR-4 total hipp:

        http://www.php-fig.org/psr/psr-4/
        [URL="https://gitter.im/php-de/chat?utm_source=share-link&utm_medium=link&utm_campaign=share-link"]PHP.de Gitter.im Chat[/URL] - [URL="https://raindrop.io/user/32178"]Meine öffentlichen Bookmarks[/URL] ← Ich habe dir geholfen ? [B][URL="https://www.amazon.de/gp/wishlist/348FHGUZWTNL0"]Beschenk mich[/URL][/B].

        Kommentar


        • #5
          Zitat von Sansire Beitrag anzeigen
          Hallo tkausl

          Also wird intern das Statement im 'use' am Namespace als Suffix angehängt? Oder kannst du deinen ersten Satz noch genauer erklären?
          Ist das mit importieren gemeint, oder was ist genau damit gemeint?
          Ist es also nicht so das 'use' eine Datei zur Verfügung stellt ähnlich wie include?
          du kannst das wunderbar nachvollziehen wenn du mal eine methode in deiner index.php erstellst

          PHP-Code:
          function __autoload($className){
          var_dump($className);

          dann siehste den gesamten pfad nach dem use , diesen kannste nehmen und ein include/require dann anwenden. (passiert aber automatisch, siehe tr0ys antwort)
          apt-get install npm -> npm install -g bower -> bower install <package> YOLO [URL]https://www.paypal.me/BlackScorp[/URL] | Mein Youtube PHP Kanal: [url]https://www.youtube.com/c/VitalijMik[/url]

          Kommentar


          • #6
            Zum Beispiel einfach so als Test-Script unabhängig von deinem ZF2-Projekt:

            Code:
            <?php
            
            use foo\bar\baz as xyz;
            
            spl_autoload_register(function ($class) {
                var_dump($class); // string(19) "foo\bar\baz\MyClass"
            });
            
            new xyz\MyClass();
            Dazu wird hier halt noch ein Fehler ausgelöst, weil die Autoloader-Funktion in diesem Beispiel eben aus dem Inhalt von $class keinen Pfad für das Dateisystem macht und dann inkludiert. Deshalb wird die Klasse dann nicht gefunden. Das soll hier aber egal sein.

            function __autoload geht auch (und ist für die kleine Demo meinetwegen auch okay), aber stattdessen sollte immer spl_autoload_register genutzt werden. Siehe Doku:

            - http://php.net/manual/en/function.sp...d-register.php

            Entscheidend ist: Der use-Mechanismus verwaltet lediglich Aliase für die aktuelle Quellcode-Datei, um Übersicht zu schaffen und Tipparbeit zu sparen.

            Man kann sich das als eine Art Precompiler-Makro vorstellen, das vor der eigentlichen Auswertung erst mal die Aliase auflöst und in den Code dann etwa das hier schreibt:
            new \foo\bar\baz\MyClass();

            Mit der Zuordnung zum Dateisystem oder gar dem tatsächlichen Inkludieren hat das im Grunde also gar nichts zu tun. In Hinblick auf die Doku halte ich deshalb auch „Aliasing“ für den wesentlich passenderen Begriff.

            (Man sollte allerdings auch beachten, dass Begriffe wie „Import“ oder „Include“ in verschiedenen Programmiersprachen nur grob deckungsgleich verwendet werden, weil die Sprachen unterschiedliche Mechanismen nutzen, um Code zusammenzufügen.)



            Also: Jeder Klassenname in einer PHP-Datei wird automatisch in die „fully qualified“-Form (FQCN, fully qualified class name) gebracht, bevor es darum geht, den zugehörigen Code tatsächlich „physikalisch“ zu laden.

            Dieser FQCN ist dann die Eingabe für das Autoloading. Das ist ein Sammelbegriff für alle Funktionen/Callbacks, die per spl_autoload_register bekannt gemacht wurden. Diese Callbacks werden dann der Reihe nach aufgerufen, bis die Klasse geladen ist. Jedes Callback kann sich den FQCN ansehen und entscheiden, ob es für diesen Namespace zuständig ist. Falls ja, kann es den FQCN nach beliebigen Regeln in einen Pfad übersetzen und diesen per include-Aufruf laden. Falls nein, macht das Callback einfach gar nichts und das nächste Callback auf dem Stack wird aufgerufen.

            Dein ZF2-Beispiel hat also grob diese Logik implementiert:

            Code:
            <?php
            
            use Zend\Mvc\Controller\AbstractActionController;
            use Objects\Model\Objects;
            
            
            spl_autoload_register(function ($fqcn) {
                if (0 !== strpos($fqcn, 'Zend\\')) {
                    // Nicht mein Namespace
                    return;
                }
            
                $path = ROOT . '/vendor/ZF2/library/' . str_replace('\\', '/', $fqcn) . '.php';
            
                include $path;
            });
            
            
            spl_autoload_register(function ($fqcn) {
                if (0 !== strpos($fqcn, 'Objects\\')) {
                    // Nicht mein Namespace
                    return;
                }
            
                $path = ROOT . '/module/Objects/src/' . str_replace('\\', '/', $fqcn) . '.php';
            
                include $path;
            });
            
            
            new AbstractActionController(); // läuft in erstes Callback
            
            new Objects(); // läuft in zweites Callback
            (Wobei die Autoloader natürlich nicht in jeder Datei einzeln angegeben werden müssen, sondern weit vorne in einer Bootstrap-Datei oder so stehen.)

            Weil das etwas umständlich und unübersichtlich wird, wenn jede Komponente ihre eigene Autoloader-Logik definiert, wie sie FQCNs ins Dateisystem mappt, haben sich da gewisse Standards etabliert. Grundsätzlich sind die Regeln ganz simpel:

            1. Jeder Ober-Namespace(etwa ZF2, Objects, …) ist mit einem Wurzelverzeichnis verknüpft.
            2. An dieses Wurzelverzeichnis wird dann der FQCN angehängt, wobei Backslashes durch Slashes ersetzt werden und am Ende ein ".php" angefügt wird.

            (In den Details noch etwas komplizierter. Das ist dann etwa hier nachzulesen: https://github.com/php-fig/fig-stand...-autoloader.md)

            Daher kommt dann auch diese Entsprechung mit Namespace=Verzeichnis. Ist gut nachzuvollziehen, ist aber völlig willkürlich. Den PHP-Interpreter würde es in keiner Weise stören, wenn das gänzlich anders zugeordnet wäre. (Es gibt etwa auch noch Classmaps, die einfach eine Map von FQCNs zu Pfaden verwalten und im Autoloader-Callback prüfen, ob ein Key existiert.)

            Diese PSR-0/PSR-4-Sache ist das, worauf sich ein großer Teil der PHP-Welt geeinigt hat.

            Dann gibt es noch das hier im Thread ebenfalls bereits verlinkte Package-Management-Tool Composer, das glaube ich auch vom ZF2 genutzt wird. Das hat unter anderem die Funktionalität, automatisch einen passenden Autoloader für alle per Composer geladenen Packages zu erstellen. Der Package-Autor kann in einer entsprechenden Config-File in seinem Package angeben, dass das Package zum Beispiel Namespace X nach PSR-4-Logik mit Verzeichnis Y verknüpft. Composer fasst das dann alles zusammen, bastelt den entsprechenden Code für spl_autoload_register und verpackt es so, dass in der Anwendung selbst nur noch einmal
            require __DIR__ . '/vendor/autoload.php';

            geschrieben werden muss, womit dann sämtliches Autoloading für alle per Composer eingebundenen Packages erledigt ist.

            Mehr zu Composer etwa hier: http://php-de.github.io/jumpto/composer/


            PS: Falls sich das jetzt sehr kompliziert liest, liegt das bloß daran, dass hier drei oder vier Sachen durchgegangen wurden, die alle getrennt betrachtet werden können und für sich ganz überschaubar sind.

            Kommentar


            • #7
              Zuerst mal, vielen dank an alle für die zügigen Antworten.

              Zitat von tr0y Beitrag anzeigen
              Klassen-Pfade ( des Namespaces ) werden von autoloadern in Dateipfade übersetzt. Damit man sich dabei nicht das Hemd zerreißt und Smilies auf die Nasenflügel malt nimmt man dazu einen fertigen Autoloader. Composer bringt einen mit:

              https://getcomposer.org/doc/01-basic...md#autoloading

              Es gibt Autoloader Standards, im moment ist PSR-4 total hipp:

              http://www.php-fig.org/psr/psr-4/
              Hab ichs richtig verstanden. 'use' macht also KEIN include/require ähnlichen Effekt, er stellt nicht eine Datei zur Verfügung? Das wird NUR vom Autoloading bzw. expliziten includes/requires gemacht?

              Zitat von BlackScorp Beitrag anzeigen
              du kannst das wunderbar nachvollziehen wenn du mal eine methode in deiner index.php erstellst

              PHP-Code:
              function __autoload($className){
              var_dump($className);

              dann siehste den gesamten pfad nach dem use , diesen kannste nehmen und ein include/require dann anwenden. (passiert aber automatisch, siehe tr0ys antwort)
              Kann ich leider nicht nachvollziehen.

              index.php vom Framework
              PHP-Code:
              <?php
              /**
               * This makes our life easier when dealing with paths. Everything is relative
               * to the application root now.
               */
              chdir(dirname(__DIR__));

              // Decline static file requests back to the PHP built-in webserver
              if (php_sapi_name() === 'cli-server' && is_file(__DIR__ parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH))) {
                  return 
              false;
              }

              // Setup autoloading
              require 'init_autoloader.php';
              use 
              test;
              function 
              __autoload($className){
                  
              var_dump($className);
              }
              // Run the application!
              Zend\Mvc\Application::init(require 'config/application.config.php')->run();
              Ausgabe der Funktion:
              Warning: The use statement with non-compound name 'test' has no effect in C:\Program Files (x86)\Zend\ZendServer\data\apps\http\__default__\0 \myobs\0.1_20\public\index.php on line 15
              string(29) "Zend\Loader\AutoloaderFactory" string(30) "Zend\Loader\StandardAutoloader"
              Die Warning versteh ich überhaupt nicht was das sein soll (da mich ‘use’ mich gerade immer mehr verwirrt). Er findet keine Klasse, oder keine Datei (oder eben keine Datei weil das nichts mit ihm zu tun hat sondern ist ne Sache vom Autoloading?) die im ‘use’ Statement Pseudo-Pfad definiert ist?

              Es werden also 2 Klassennamen ausgegeben die mit einem Namespace prefixed sind. Nur das habe ich hier verstanden.

              Zitat von mermshaus Beitrag anzeigen
              Entscheidend ist: Der use-Mechanismus verwaltet lediglich Aliase für die aktuelle Quellcode-Datei, um Übersicht zu schaffen und Tipparbeit zu sparen.
              In den von mir entdeckten vordefinierten ZF2 use Statements sind keine Aliase versehen. Der Alias ist doch nur das nach dem ‘as’ oder?

              Zitat von mermshaus Beitrag anzeigen
              Code:
              <?php
              
              use Zend\Mvc\Controller\AbstractActionController;
              use Objects\Model\Objects;
              
              
              spl_autoload_register(function ($fqcn) {
                  if (0 !== strpos($fqcn, 'Zend\\')) {
                      // Nicht mein Namespace
                      return;
                  }
              
                  $path = ROOT . '/vendor/ZF2/library/' . str_replace('\\', '/', $fqcn) . '.php';
              
                  include $path;
              });
              
              
              spl_autoload_register(function ($fqcn) {
                  if (0 !== strpos($fqcn, 'Objects\\')) {
                      // Nicht mein Namespace
                      return;
                  }
              
                  $path = ROOT . '/module/Objects/src/' . str_replace('\\', '/', $fqcn) . '.php';
              
                  include $path;
              });
              
              
              new AbstractActionController(); // läuft in erstes Callback
              
              new Objects(); // läuft in zweites Callback
              Also jeder ‘use’ versucht eine Datei zu laden. Richtig?
              Und passiert das im PHP Prozess wirklich direkt nach den ‘use’ statements und vor dem restlichen Code?

              Dann verstehe ich aber den Zusammenhang nicht mehr mit dieser Aussage:

              Zitat von mermshaus Beitrag anzeigen
              Mit der Zuordnung zum Dateisystem oder gar dem tatsächlichen Inkludieren hat das im Grunde also gar nichts zu tun. In Hinblick auf die Doku halte ich deshalb auch „Aliasing“ für den wesentlich passenderen Begriff.

              Kommentar


              • #8
                Hallöchen,

                schau doch einfach mal was hier passiert:

                Code:
                <?php
                
                use Just\A\Path\To\MyClass;
                
                spl_autoload_register(function($class){
                	printf('Please load "%s" now!', $class);
                	// Ausgabe: Please load "Just\A\Path\To\MyClass" now!
                });
                
                // Hier wird der Autoloader angestoßen
                $object = new MyClass;
                Der Autoload-Mechanismus wird erst dann angestoßen, wenn die Klasse auch tatsächlich verwendet wird. In mein Beispiel wird versucht eine Instanz der Klasse MyClass zu erzeugen. Das klappt natürlich nur wenn die Klasse auch bekannt ist. An dieser Stelle springt der Autoloader ein und versucht die Klasse zu laden. Obwohl dort new MyClass steht, wird dem Autoloader die Zeichenkette "Just\A\Path\To\MyClass" übergeben. Nun kann der Autoloader also ableiten wo sich die Klasse befindet.

                Viele Grüße,
                lotti
                [SIZE="1"]Atwood's Law: any application that can be written in JavaScript, will eventually be written in JavaScript.[/SIZE]

                Kommentar


                • #9
                  ok ich versuchs mal anders zu erläutern,

                  also du kannst so eine instanz einer klasse erstellen

                  PHP-Code:
                  $foo = new \Test\Foo\Bar\Baz(); // \Test\Foo\Bar\Baz(); 
                  nun möchtest du aber sagen wir meherere instanzen der klasse anlegen, folglich machst du sowas

                  PHP-Code:
                  $foo1 = new \Test\Foo\Bar\Baz();// \Test\Foo\Bar\Baz();
                  $foo2 = new \Test\Foo\Bar\Baz();// \Test\Foo\Bar\Baz();
                  $foo3 = new \Test\Foo\Bar\Baz();// \Test\Foo\Bar\Baz(); 
                  nun macht es aber kein spaß das ganze einzutippen also kann man dann sowas machen

                  PHP-Code:
                  use \Test\Foo\Bar\Baz//use \Test\Foo\Bar\Baz;

                  $foo1 = new Baz();
                  $foo2 = new Baz();
                  $foo3 = new Baz(); 
                  nun kann es auch manchmal passieren dass du gleiche klassennamen hast aber in unterschiedlichen namespaces

                  PHP-Code:
                  use \Test\Foo\Bar\Baz//use \Test\Foo\Bar\Baz;
                  use \Test\Foo\Baz\Baz;//use \Test\Foo\Baz\Baz;

                  $foo1 = new Baz();
                  $foo2 = new Baz();
                  $foo3 = new Baz(); 
                  das würde nicht funktionieren weil bei der verwendung der code nicht wüsste welches Baz er benutzen soll, da muss man alias benutzen

                  PHP-Code:
                  use \Test\Foo\Bar\Baz as BarBaz//use \Test\Foo\Bar\Baz as BarBaz; 
                  use \Test\Foo\Baz\Baz as BazBaz;//use \Test\Foo\Baz\Baz as BazBaz;

                  $foo1 = new BarBaz();
                  $foo2 = new BazBaz();
                  $foo3 = new BazBaz(); 
                  so, das ist das mit dem use und alias und wozu das da ist.

                  jetzt kommt der autoloader, in php wird die methode __autoload bzw die methoden die man beim spl_autoload_register eingetragen hat, aufgerufen sobald du eine instanz anlegst oder eine konstante einer klasse benutzt oder eine statische methode einer klasse aufrufst halt irgendwas mit einer klasse machen.

                  PHP-Code:
                  use \Test\Bat\Foo\Baz as BarBaz;
                  use \
                  Test\Foo\Baz\Baz as BazBaz;

                  $foo1 = new BarBaz();
                  $foo2 = new BazBaz();
                  $foo3 = new BazBaz();

                  function 
                  __autoload($className){
                  var_dump($className); //hier wird dann entweder  \Test\Bat\Foo\Baz oder \Test\Foo\Baz\Baz stehen, je nachdem welche instanz erstellt wurde. 


                  hier habe ich autoload methode benutzt weil es einfach ist, spl_autoload_register ist besser da man auch andere autoload logiken einbinden kann.

                  in der autoload methode kannst du nun den klassennamen in ordnerstruktur+dateiname umwandeln und ein require_once benutzen.

                  ablauf:
                  du erstellst eine instanz
                  autoload wird getriggered
                  klassenname wird in ordnerstruktur gemappt/umgewandelt whatever
                  gefundene datei wird einmalig eingebunden


                  ich hoffe dass ist jetzt verständlich, use hat nichts direkt mit dem autoloader zu tun, du kannst use ohne autoloader nutzen , musst eben die datei händisch includen

                  edit: der syntaxhighligher lässt backslashes entfernen, ich lerne es auch nicht..
                  apt-get install npm -> npm install -g bower -> bower install <package> YOLO [URL]https://www.paypal.me/BlackScorp[/URL] | Mein Youtube PHP Kanal: [url]https://www.youtube.com/c/VitalijMik[/url]

                  Kommentar


                  • #10
                    code-tags nutzen statt php-tags, blackscorp.
                    [URL="https://gitter.im/php-de/chat?utm_source=share-link&utm_medium=link&utm_campaign=share-link"]PHP.de Gitter.im Chat[/URL] - [URL="https://raindrop.io/user/32178"]Meine öffentlichen Bookmarks[/URL] ← Ich habe dir geholfen ? [B][URL="https://www.amazon.de/gp/wishlist/348FHGUZWTNL0"]Beschenk mich[/URL][/B].

                    Kommentar


                    • #11
                      Zitat von tr0y Beitrag anzeigen
                      code-tags nutzen statt php-tags, blackscorp.
                      kommentare scheinen es auch zu tun
                      apt-get install npm -> npm install -g bower -> bower install <package> YOLO [URL]https://www.paypal.me/BlackScorp[/URL] | Mein Youtube PHP Kanal: [url]https://www.youtube.com/c/VitalijMik[/url]

                      Kommentar


                      • #12
                        Hab ichs richtig verstanden. 'use' macht also KEIN include/require ähnlichen Effekt, er stellt nicht eine Datei zur Verfügung? Das wird NUR vom Autoloading bzw. expliziten includes/requires gemacht?
                        Ja.

                        PHP-Code:
                        <?php

                        use foo// Warning:  The use statement with non-compound name 'foo' has no effect
                        Heißt, dass das use an der Stelle zweckfrei ist, weil du – mit oder ohne – immer new foo(); schreiben würdest.

                        Ansonsten bezieht sich der erste Abschnitt meines vorherigen Beitrags direkt auf BlackScorps Post darüber. Da war nämlich nicht wirklich gemeint, den entsprechenden Code in die Index-Datei deines ZF2-Projekts einzutragen, sondern zu Demonstrationszwecken einfach in irgendeine neue Datei, die gar nichts damit zu tun hat.

                        In den von mir entdeckten vordefinierten ZF2 use Statements sind keine Aliase versehen. Der Alias ist doch nur das nach dem ‘as’ oder?
                        Uff. Manchmal wird es wirklich zu Slapstick[1], irgendwelche Sachen zu erklären, weil auch die Doku in der Wahl der Begriffe nicht so richtig hilft… Zudem ist es echt nicht so schwierig, du hast dich bloß irgendwie verrannt. Und wie gesagt: Manche Formulierungen anderer Leute (vermutlich inklusive mir) helfen da leider auch nicht gerade.

                        Insgesamt kann man diese use-Funktionalität als Aliasing-Mechanismus beschreiben. – Aber mir kommt gerade ein Gedanke. Die beiden folgenden Zeilen sind funktional identisch:
                        use Foo\Bar;
                        use Foo\Bar as Bar;

                        Für "Foo\Bar" wird in beiden Fällen für die Datei, in der die use-Zeile steht, ein Alias "Bar" angelegt.

                        Also jeder ‘use’ versucht eine Datei zu laden. Richtig?
                        Nein. use ist ein Aliasing-Mechanismus. Der macht wirklich gar nichts, außer es in der Datei zu ermöglichen, nicht jeden Klassennamen immerzu vollständig qualifiziert (inklusive aller Namespaces, als FQCN) angeben zu müssen.

                        Und passiert das im PHP Prozess wirklich direkt nach den ‘use’ statements und vor dem restlichen Code?
                        Das passiert überhaupt nicht. Die Aliase, die von use eingeführt werden können, werden zur Compile-Zeit in FQCNs umgewandelt. Durch use wird wirklich nichts geladen.

                        Autoloading – das nichts mit use zu tun hat – passiert dann erst zur Laufzeit, wenn die Ausführung auf einen noch nicht geladenen Klassennamen stößt (z. B. in new-Statements oder bei Typehints).


                        1: Dann auch noch das Syntaxhighlighting hier im Forum, das die Backslashes in [php][/php]-Tags schluckt… Das läuft von einer Sache, die man missverstehen kann und/oder erklären müsste, zur nächsten.

                        Kommentar


                        • #13
                          Hallo miteinander, vielen Dank nochmals für die zügigen und konkreten Antworten.

                          Zitat von lottikarotti Beitrag anzeigen
                          Hallöchen,

                          schau doch einfach mal was hier passiert:

                          Code:
                          <?php
                          
                          use Just\A\Path\To\MyClass;
                          
                          spl_autoload_register(function($class){
                          	printf('Please load "%s" now!', $class);
                          	// Ausgabe: Please load "Just\A\Path\To\MyClass" now!
                          });
                          
                          // Hier wird der Autoloader angestoßen
                          $object = new MyClass;
                          Der Autoload-Mechanismus wird erst dann angestoßen, wenn die Klasse auch tatsächlich verwendet wird. In mein Beispiel wird versucht eine Instanz der Klasse MyClass zu erzeugen. Das klappt natürlich nur wenn die Klasse auch bekannt ist. An dieser Stelle springt der Autoloader ein und versucht die Klasse zu laden. Obwohl dort new MyClass steht, wird dem Autoloader die Zeichenkette "Just\A\Path\To\MyClass" übergeben. Nun kann der Autoloader also ableiten wo sich die Klasse befindet.

                          Viele Grüße,
                          lotti
                          Ok durch use werden die abgerufenen Klassennamen nur prefixiert/umbenannt gemäss den qualifizierungs Regelungen, und wenn der letzte Name im use Pfad der abgerufene Klassenname ist. Richtig?

                          Und ja ich seh es, die Meldung im loader erscheint nur wenn ich bei diesem Beispiel eine Instanzierung versuche. Finde ich gutes beispiel, nun sehe ich das autoloading wird erst bei einem Klassenaufruf angestossen.

                          Nach den Umbenennungen wird erst dann das Script abgearbeitet und bei jeder Klassenverwendung entscheidet ein individueller Autoloader wie und ob eine Datei eingebunden wird.
                          Mit individuell meine ich zum Beispiel: ZF machts anders als Symfony, der machts anders als eine eigene Applikation etc.
                          Im Gegensatz zu den ‘use’ qualified regeln: Bei dem sind die Regeln definiert wie was umgeschrieben wird. Richtig?

                          Zitat von BlackScorp Beitrag anzeigen
                          ich hoffe dass ist jetzt verständlich, use hat nichts direkt mit dem autoloader zu tun, du kannst use ohne autoloader nutzen , musst eben die datei händisch includen
                          Ich würde sagen auf jeden Fall ja, wenn meine obigen Aussagen stimmen?

                          Zitat von mermshaus Beitrag anzeigen
                          Insgesamt kann man diese use-Funktionalität als Aliasing-Mechanismus beschreiben. – Aber mir kommt gerade ein Gedanke. Die beiden folgenden Zeilen sind funktional identisch:
                          use Foo\Bar;
                          use Foo\Bar as Bar;

                          Für "Foo\Bar" wird in beiden Fällen für die Datei, in der die use-Zeile steht, ein Alias "Bar" angelegt.
                          Also man könnte sagen: Foo\Bar ist ein längerer Alias für den Klassenaufruf class Bar die dann umgeschrieben wird. Und as Bar ist der kurz Alias für den langen Alias für den Klassenaufruf.
                          Also kurz gesagt as Bar ist ein Alias des Aliases. Oder?

                          Kommentar


                          • #14
                            Ok durch use werden die abgerufenen Klassennamen nur prefixiert/umbenannt gemäss den qualifizierungs Regelungen, und wenn der letzte Name im use Pfad der abgerufene Klassenname ist. Richtig?

                            Und ja ich seh es, die Meldung im loader erscheint nur wenn ich bei diesem Beispiel eine Instanzierung versuche. Finde ich gutes beispiel, nun sehe ich das autoloading wird erst bei einem Klassenaufruf angestossen.

                            Nach den Umbenennungen wird erst dann das Script abgearbeitet und bei jeder Klassenverwendung entscheidet ein individueller Autoloader wie und ob eine Datei eingebunden wird.
                            Mit individuell meine ich zum Beispiel: ZF machts anders als Symfony, der machts anders als eine eigene Applikation etc.
                            Im Gegensatz zu den ‘use’ qualified regeln: Bei dem sind die Regeln definiert wie was umgeschrieben wird. Richtig?
                            Ja, ist alles richtig genug, denke ich.

                            Also man könnte sagen: Foo\Bar ist ein längerer Alias für den Klassenaufruf class Bar die dann umgeschrieben wird.
                            „Foo\Bar“ ist der vollständige Klassenname (FQCN) mit Namespaces. „Bar“ wird dann per use zum lokalen Alias dafür. (Und „Bar“ ist auch gleichzeitig der Klassenname ohne Namespaces.)

                            Und as Bar ist der kurz Alias für den langen Alias für den Klassenaufruf.
                            Hm… Weiß ich jetzt nicht, wie du das meinst.

                            Also kurz gesagt as Bar ist ein Alias des Aliases. Oder?
                            Jain. Also, so kompliziert muss man sich das gar nicht machen, denke ich.

                            Denk dir einfach bei einem use ProjectX\MyClass; immer noch das as MyClass dazu. ProjectX\MyClass ist der Klassenname, MyClass ist das lokale Alias.

                            Dann ist das vom Schema her nämlich genau wie ein use Project\MyClass as Foo;.

                            Kommentar


                            • #15
                              Zitat von Sansire Beitrag anzeigen
                              Ich würde sagen auf jeden Fall ja, wenn meine obigen Aussagen stimmen?
                              Ja fast, Zend 2 hat den Gleichen Autoloading mechanismus wie Symfony 2 und genauso wie Laravel usw

                              Vor ein paar jahren haben sich die Entwickler zusammengesetzt und haben einen Standard entwickelt PSR

                              http://www.php-fig.org/psr/psr-0/ der 0er und der 4er bestimmen wie der Autoload mechanismus funktionieren soll, dadurch kann man Module aus Symfony im Zend verwenden und andersrum genauso. Zusätzlich hat man die möglichkeit seine ordnerstruktur nach dem PSR zu richten und seine klassen im Zend zu verwenden oder in seinem eigenen projekt nur teile anderer Frameworks einzusetzen.

                              Vielleicht wird noch einiges klarer wenn man zurück an die PHP 5.2er version denkt. Damals gab es keine Namespaces und Zend 1 nutzte zb die Ordnerstruktur direkt im klassennamen

                              PHP-Code:
                              class Zend_Utils_SomeFolder_Classname{} 
                              wenn man eine instanz davon anlegen wollte, hat man es dann so gemacht
                              PHP-Code:
                              $foo = new Zend_Utils_SomeFolder_Classname
                              dabei hat der autoload mechanismus ledeglich die unterstriche des klassennamen in DIRECTORY_SEPERATOR ersetzt, hinten .php drangehängt und es dann included. Nun sieht aber so ein klassenname ja nicht schön aus und deshalb gibt es namespaces
                              apt-get install npm -> npm install -g bower -> bower install <package> YOLO [URL]https://www.paypal.me/BlackScorp[/URL] | Mein Youtube PHP Kanal: [url]https://www.youtube.com/c/VitalijMik[/url]

                              Kommentar

                              Lädt...
                              X