2009-09-01 3 views
6

Dies funktioniert nicht:Erweiterte Klasse nicht gefunden, wenn Basisklasse in einer separaten Datei ist enthalten

test.php:

include_once('test-include.php'); 

$main = new mainClass(); 

//====================================================================== 
class mainClass { 
    function __construct() { 
     $test2 = new Test2(); 
     echo $test2->var; 
    } 
} 

//====================================================================== 
class Test2 extends Test1 { // test2 
    var $var = 'b'; 
} 

Test-include.php:

// this does get printed out, so I know the include statement is working 
echo 'DEBUG: this is the test-include.php file<br>'; 

//====================================================================== 
class Test1 { // test1 
    var $var = 'a'; 
} 

Es gibt den folgenden Fehler

PHP Fatal error: Class 'Test2' not found in /path/to/test.php on line 8 

während dieser

funktioniert

test2.php:

// this is in the same position as the include statement in test.php 
//====================================================================== 
class Test1 { // test1 
    var $var = 'a'; 
} 

$main = new mainClass(); 

//====================================================================== 
class mainClass { 
    function __construct() { 
     $test2 = new Test2(); 
     echo $test2->var; 
} 
} 

//====================================================================== 
class Test2 extends Test1 { // test2 
    var $var = 'b'; 
} 

Warum die Basisklasse nicht setzen (Test1) in einer Include-Datei das Kind Klasse verursachen, die es ist, die sich nicht gefunden werden ? Mit anderen Worten, das erste Beispiel schlägt fehl, da es Test2 nicht finden kann, wenn wir versuchen, es zu instanziieren. Diese Art von Sinn macht Sinn, da wir im Code-Ausführungsablauf noch nicht zu Test2 gelangt sind. Im zweiten Beispiel (ohne die include-Anweisung) gibt es keinen Fehler, obwohl es eine ähnliche Situation ist (die Test2-Klasse wurde noch nicht in der Codeausführung erreicht)

Oh, und dies ist unter Version 5.1.6 .

UPDATE:

OK, Daff korrekt ist - wenn ich

$main = new mainClass(); 

bis zum Ende in dem test.php Beispiel bewegen, es funktioniert. Ich würde immer noch gerne wissen, warum es nicht funktioniert, wenn die obige Zeile nicht am Ende ist - es funktioniert ganz gut im Beispiel test2.php, das am Ende nicht die $ main = new mainClass() Zeile hat .

UPDATE 2:

OK, ich habe versucht, require, require_once und include anstelle von include_once mit - keines dieser Arbeit. Und ich fügte der test-include.php-Datei auch eine Test-Echo-Anweisung hinzu, die ausgedruckt wird (außerdem erhalte ich keine Fehlermeldung über eine nicht vorhandene Include-Datei), daher weiß ich, dass die include-Anweisung funktioniert.

+0

sind Sie sicher, die umfassen funktioniert? – Rufinus

+0

Wie schlägt es fehl? Kompilierfehler, Ausführungsfehler, kein Fehler, aber falsche Ergebnisse? – Lucky

+0

Was sehen Sie, wenn Sie "require" verwenden? Was siehst du, wenn du "echo" schreibst Dies ist test-include.php '; " am Anfang von "test-include.php"? Ist "test-include.php" im selben Verzeichnis? Ist es in Ihrem Include-Pfad? – GZipp

Antwort

6

Das sollte etwas mit der Definitionsreihenfolge zu tun haben und JEDE Klasse sollte enthalten sein, bevor Sie tatsächlich mit ihnen arbeiten. Wenn Sie den Anruf von

$main = new mainClass(); 

Am Ende des Skripts setzen es funktioniert gut, auch mit der Datei enthalten, da alle Klassen bereits definiert sind. Schließlich sollten Sie sich die PHP autoload Funktion ansehen, weil Sie dieses Problem mit einer kleinen Funktion loswerden.

+1

Ich denke, ein Teil der Frage ist die Klasse Definition Reihenfolge ist in beiden Beispielen gleich, aber die eine funktioniert und die andere nicht. –

+0

Ja, Alan ist korrekt und ich habe test2.php modifiziert (und getestet), um die Basisklasse (Test1) an die gleiche Stelle zu setzen wie die include-Anweisung in test.php - test2.php funktioniert in diesem Fall immer noch, Es ist also kein Problem mit der Bestellung, es sei denn, PHP-Includes funktionieren nicht so, wie ich es dachte (dh der Code aus der enthaltenen Datei wird dort eingefügt, wo die include-Anweisung war). – Bill

+0

Ok Definition Reihenfolge ist das bessere Wort dafür. Ich empfehle immer noch Autoloading oder zumindest alle Klassen-Dateien vor jeder Verarbeitung beginnt. – Daff

4

OK, ich denke, ich habe das herausgefunden.Nach diesem Bug-Report:

http://bugs.php.net/bug.php?id=30453

PHP 4 erlaubten Klassen definiert werden, nachdem sie aber für PHP 5, in den Worten des End-Plakats auf dem Bug-Thread verwendet:

PHP5 unterstützt es [deklarieren Klassen , nachdem sie verwendet werden] für rückwärts Kompatibilität, aber wir planen nicht Unterstützung für alle Kombinationen.

Also ich vermute, dass dieser spezielle Fall eine dieser nicht unterstützten Kombinationen ist.

0

Verwenden Sie zuerst include_once(), um alle Dateien in Ihrer Indexdatei hinzuzufügen. Wenn Sie eine Klasse erweitern möchten, müssen Sie zuerst diese Elternklasse instanziieren.
Beispiel:

index.php--> 
<?php 
    include_once('parentClass.php'); 
    include_once('childClass.php'); 

    $parentObj = new parent(); 
    $childObj = new child(); 
?> 

child.php--> 
<?php 
    class child extends parent{ 
    function __construct(){ 

    } 
    } 
?> 
Verwandte Themen