Franz K.: Problem mit __autoload-function

Guten Tag!

Folgendes Spektakel:
index.php hat eine datei inkludet in der die Funktion __autoload enthält.
Danach inkludet index.php die bootstrap.php.
Die bootstrap.php ruft die Controller.php auf welche dann durch __autoload geladen wird.

In der Controller.php soll dann die View.php durch autoload aufgerufen werden.
Problem ist: __autoload greift nicht ein.
Warum nicht?
Die __autoload Funktion ist wirklich fehlerfrei und nimmt auf sämtliche "nicht-geschehnisse" Rücksicht. Jeder Fehler der eintreten könnte wird behandelt. Es wird gecheckt ob die Datei vorhanden ist, falls ja, inkludet, dann wird gecheckt ob die Klasse vorhanden ist oder nicht, falls nicht wird Sie mit eval() erstellt. Usw.. also sämtliches abgedeckt.

Ich hab auch einfach mal echo "ok" reingeschrieben. Das okay müsste nach dem obigen "Spektakel" 2 mal ausgegeben werden. Wird sie aber nicht. Sie wird nur einmal ausgegeben.

Wie kann ich also dafür sorgen das die __autoload welche in der index.php btw geladen wird bevor IRGENDETWAS anderes geladen wird, überall greift?

Hoffe ihr könnt mir da Auskunft geben.

Schönes Wochenende noch,

Franz

  1. Hello,

    wie lautet Deine __autoload()-Funktion?

    Was enthalten die Dateien

    • bootstrap.php
    • Controller.php
    • View.php

    Ausschließlich Klassen oder auch auszuführenden Code?

    Gibt es Fehlermeldungen?
    Wie ist dein Error_Reporting eingestellt?

    Warum werden die Dateinamen mal klein und mal mit führendem Versalen geschrieben?

    Liebe Grüße aus dem schönen Oberharz

    Tom vom Berg

    --
    Nur selber lernen macht schlau
    http://bergpost.annerschbarrich.de
    1. Hello,

      wie lautet Deine __autoload()-Funktion?

      function __autoload($klasse){  
      	  
      	$file = null;  
      	  
      	// die bösesten zeichen in klassennamen mal sicherheitshalber verbieten  
      	if (strpos ($klasse, '.') !== false || strpos ($klasse, '/') !== false  
      		|| strpos ($klasse, '\\') !== false || strpos ($klasse, ':') !== false) {  
      	  return;  
      	}  
      	  
      	// Aufruf auseinandernehmen  
      	$path=explode('_',$klasse);  
      	  
      	// Path-Size  
      	$pathCount=count($path);  
      	  
      	// Pfad erstellen  
      	for($i= 0; $i<$pathCount; ++$i){  
      		$file.=$path[$i];  
      		$file.=($i==$pathCount-1) ? ".php" : "/";  
      	}  
      	// Klasse inkludieren  
      	if(file_exists($file)){  
      		if(!include_once($file)){  
      			echo "<p>Inkludieren der Datei: ".$file." fehlgeschlagen</p>";	  
      		} else {  
      			if (!class_exists($klasse)){  
      				eval('class '.$klasse.' {  
                    	    public function __construct() {  
                    	        echo "Class ' . $klasse . ' not found.";  
                    	    }  
                   	} ');  
      			}  
      		}  
      	} else {  
      		echo "<p>Inkludieren der Datei: ".$file." fehlgeschlagen</p>";  
      	}  
      }
      

      Was enthalten die Dateien

      • bootstrap.php
      • Controller.php
      • View.php

      Ausschließlich Klassen oder auch auszuführenden Code?

      Alles nur Klassen. Überall auch nur eine.

      Gibt es Fehlermeldungen?

      Nein.

      Wie ist dein Error_Reporting eingestellt?

      display_errors 1

      E_ALL | E_STRICT

      Warum werden die Dateinamen mal klein und mal mit führendem Versalen geschrieben?

      Das ist nur hier so... weil ich grad schnell geschrieben ahtte, nicht drüber nachgedacht. Sie sind eigendl alle nach Camel-Case benannt.

      Gruß, Frank

      1. Ich sollte noch erwähnen das die Strukturen so sind.

        Wenn eine Klasse ORDNER1/ORDNER2/X.php
        liegt, dann heißt diese "ORDNER1_ORDNER2_X"

        1. Hello,

          Ich sollte noch erwähnen das die Strukturen so sind.

          Wenn eine Klasse ORDNER1/ORDNER2/X.php
          liegt, dann heißt diese "ORDNER1_ORDNER2_X"

          Der Nachtrag passt mir gerade gut ins Programm :-)

          Kannst Du mir mal

          // Aufruf auseinandernehmen
              $path=explode('_',$klasse);

          // Path-Size
              $pathCount=count($path);

          // Pfad erstellen
              for($i= 0; $i<$pathCount; ++$i){
                                        ^^^^
                  $file.=$path[$i];
                  $file.=($i==$pathCount-1) ? ".php" : "/";
              }

          in Worten erklären, was da passieren soll?

          Wie haißt z.B. die zu includierende Klasse, wo liegt sie dann und wie soll der Pfad zusammengebaut werden? Auf welchem System läuft das PHP? Mit welchem Compiler wurde es compiliert?

          Liebe Grüße aus dem schönen Oberharz

          Tom vom Berg

          --
          Nur selber lernen macht schlau
          http://bergpost.annerschbarrich.de
          1. Hello,
            »» Ich sollte noch erwähnen das die Strukturen so sind.

            »» Wenn eine Klasse ORDNER1/ORDNER2/X.php
            »» liegt, dann heißt diese "ORDNER1_ORDNER2_X"

            Wie haißt z.B. die zu includierende Klasse,

            ORDNER1_ORDNER2_X

            und sie liegt in ORDNER1/ORDNER2/X.php

            in Worten erklären, was da passieren soll?

            // Aufruf auseinandernehmen
                $path=explode('_',$klasse);

            ORDNER1_ORDNER2_X wird an den Stellen mit "_" getrennt.

            Also habe ich ein Array (ORDNER1, ORDNER2, X)

            // Path-Size
                $pathCount=count($path);

            Wieviele Teile sind das?
            In diesem Fall 3.

            // Pfad erstellen
                for($i= 0; $i<$pathCount; ++$i){
                                          ^^^^
                    $file.=$path[$i];
                    $file.=($i==$pathCount-1) ? ".php" : "/";
                }

            Weil das letzte der Dateiname ist:
            Setze alle im Array vorhandenen Teile mit "/" zusammen.
            Wenn das letzte kommt, stelle ein ".php" hinten dran.

            wo liegt sie dann und wie soll der Pfad zusammengebaut werden?

            Ist wohl geklärt.

            Auf welchem System läuft das PHP? Mit welchem Compiler wurde es compiliert?

            Wenn dus genau wissen willst:
            System: Windows NT BENUTZERNAME 5.1 build 2600  (Windows XP Prof.)
            Apache 2.0
            PHP Version 5.2.9

            Das aktuelle XAMPP ist in Benutzung...

            Gruß!

            1. Hello,

              Wie heißt z.B. die zu includierende Klasse,

              ORDNER1_ORDNER2_X

              und sie liegt in ORDNER1/ORDNER2/X.php

              for($i= 0; $i<$pathCount; ++$i){

              ^^^^

              Ok, also fertig übernommen, angewandte Coding Convention ist also unbekannt. Dachte ich mir.
              Lass Dir bitte mal die Schleife loggen bzw. speichere irgendwo den resultierenden Pfad.

              Ab welcher Pfadtiefe funktioniert die Funktion nicht mehr?
              Wo wird denn auf die neue Klasse zugegriffen?

              Gibt es denn keine Fehlermeldungen?
              Da ich annehme, dass Du das Error_reporting auf volles Rohr gestellt hast, wäre ja die erste Vermutung, dass gar kein Zugriff auf die Klasse vorgenommen wird.

              Woran meinst du denn gemerkt zu haben, dass __autoload() gar nicht aktiv wird?

              Liebe Grüße aus dem schönen Oberharz

              Tom vom Berg

              --
              Nur selber lernen macht schlau
              http://bergpost.annerschbarrich.de
              1. Du wirst es nicht glauben.
                Ohne - das ich irgend etwas getan habe. Geht es plötzlich.
                Frag mich nicht warum.
                Aber ich bin jetzt gerade nicht mehr zuhause, ich werde heute Nacht nochmal ausführlich berichten.

                Lass Dir bitte mal die Schleife loggen bzw. speichere irgendwo den resultierenden Pfad.

                Schon längst gemacht, klappt wunderbar.

                Ab welcher Pfadtiefe funktioniert die Funktion nicht mehr?

                Das ganze ist basierend auf einem MVC Pattern.
                Die Pfadebene war die gleiche.
                Viel eher spielte die Klassenebene eine Rolle:
                Bootstrap->Controller->Model(hier war Ende)

                Wo wird denn auf die neue Klasse zugegriffen?

                Gibt es denn keine Fehlermeldungen?

                Nein gab es keine.

                Da ich annehme, dass Du das Error_reporting auf volles Rohr gestellt hast, wäre ja die erste Vermutung, dass gar kein Zugriff auf die Klasse vorgenommen wird.

                Na logo, E_ALL und E_STRICT

                Woran meinst du denn gemerkt zu haben, dass __autoload() gar nicht aktiv wird?

                Weil nicht das ausgegeben wurde was hätte ausgegeben werden müssen.

                Gruß.

                1. Hello,

                  Woran meinst du denn gemerkt zu haben, dass __autoload() gar nicht aktiv wird?

                  Weil nicht das ausgegeben wurde was hätte ausgegeben werden müssen.

                  Ist ja ulkelig :-)

                  Sollte man auf jeden Fall nochmal genau debuggen.
                  Ich hatte ja Deine wilde Konstruktion mit der For-Schliefe für den Pfad-Zusammenbau in Verdacht.
                  Da Du für den Schleifenkörper ++$i geschrieben hast und nicht $i++.

                  Da spielen manche Installationen nicht mit. Das liegt an unterschiedlichen Calling Conventions unterschiedlicher Compiler.

                  Das solltest Du auch ruhig gegen implode() austauschen ;-)

                  Liebe Grüße aus dem schönen Oberharz

                  Tom vom Berg

                  --
                  Nur selber lernen macht schlau
                  http://bergpost.annerschbarrich.de
            2. Hi,

              // Path-Size
                   $pathCount=count($path);

              Wieviele Teile sind das?
              In diesem Fall 3.

              // Pfad erstellen
                   for($i= 0; $i<$pathCount; ++$i){
                                             ^^^^
                       $file.=$path[$i];
                       $file.=($i==$pathCount-1) ? ".php" : "/";
                   }

              Weil das letzte der Dateiname ist:
              Setze alle im Array vorhandenen Teile mit "/" zusammen.
              Wenn das letzte kommt, stelle ein ".php" hinten dran.

              Aha, also nach dem Motto "lieber kompliziert, als implodiert"?

              MfG ChrisB

              --
              Light travels faster than sound - that's why most people appear bright until you hear them speak.
              1. Hello,

                // Pfad erstellen
                     for($i= 0; $i<$pathCount; ++$i){
                                               ^^^^
                         $file.=$path[$i];
                         $file.=($i==$pathCount-1) ? ".php" : "/";
                     }

                Aha, also nach dem Motto "lieber kompliziert, als implodiert"?

                Ich wollte das erstmal unkommentiert lassen und schauen, wie man das Problem generell debuggen kann.

                [Ich habe da gerade selber noch einige Experimente gemacht und eine Menge Fragen auf der Liste. Wenn es auch noch jemand anders interessiert, motiviert mich das eher, meinen eigenen Zettel abzuarbeiten.

                Bei include und require habe ich heute ohnehin ein vollkommen anderes Verhalten festgestellt, als Andi Gutmans das in seinem eigenen Werk beschreibt. Allerdings ist das Werk auch schon von 2004]

                Liebe Grüße aus dem schönen Oberharz

                Tom vom Berg

                --
                Nur selber lernen macht schlau
                http://bergpost.annerschbarrich.de
              2. echo $begrüßung;

                Aha, also nach dem Motto "lieber kompliziert, als implodiert"?

                Auch das ist noch zu aufwendig. Im Grunde reicht eine einfache Stringersetzung aller _ nach / und ein angehängtes '.php'. Ein Einzeiler also.

                echo "$verabschiedung $name";