2010-09-28 2 views
9

Beispiel:Es gibt eine Möglichkeit, CLASS_EXISTS und __autoload ohne CRASH das Skript zu verwenden?

ClassName.php

<?php echo "This will crash all"; ?> 

In einer anderen Datei ...

foreach ($FILENAMES_WITHOUT_DOT_PHP as $name => $value) { 
    if (class_exists($value)) { 
     echo "ClassName exists..."; 
    } 
    else { 
     echo "ClassName doesn't exists...."; 
    } 
} 

Der Ausgang dieses Codes ist: Dies wird alle Stattdessen

abstürzen davon: ClassName doe sn't existiert ....

Autoload-Funktion:

function __autoload($var_class) 
{ 
    require_once("$var_class.php") ; 
} 
+0

obviusly ist notwendig, automatischen Laden zu verwenden, da die Klasse nicht geladen wird! –

+0

Zeigen Sie Ihre Autoload-Funktion ... Es sollte 'ClassName existiert nicht ....' nach dem 'Dies wird alle abstürzen 'angezeigt werden, da es nicht wichtig ist, wenn die Klasse nicht geladen wird. Ich vermute, dass Sie die Ausführung in der "__autoload" -Funktion töten, wenn Sie die Klasse nicht finden, und Sie sollten nicht ... – ircmaxell

+0

Aus dem Code, der gegeben wird, können die Ergebnisse nicht reproduziert werden. Also poste etwas mehr Code. – tplaner

Antwort

1

Verwenden class_exists in der Autoload-Funktion, dann tun Sie es nicht immer wieder verwenden. Das ist der Punkt des Autoloaders.

class App { 
    static private $_instance = NULL; 

    public function __construct() { 
     spl_autoload_register('app::autoLoader'); 
    } 

    public function __destruct() { 
    } 

    public static function getInstance() { 
     if(self::$_instance == NULL) { 
      self::$_instance = new App(); 
     } 
     return self::$_instance; 
    } 

    public static function autoLoader($class) { 
     $className = stripslashes($class); 
     if (class_exists($className)) { 
      return; 
     } 
     require $className.'.class.php'; 
    } 
} 
+4

HUH? Nein, ist es nicht ... Es gibt viele Verwendungen für class_exists. Eine davon ist zu sehen, ob die Klasse zu Beginn geladen werden kann (um zu sehen, ob sie verfügbar ist). Außerdem gibt es keinen Grund, 'class_exists' aus der Autoload-Funktion heraus aufzurufen, da Sie wissen, dass dies nicht bereits der Fall ist (es sei denn, jemand ruft sie manuell an, aber sie sollten dies nicht tun). Oh, und wenn ich du wäre, würde ich ein wenig nachprüfen, um festzustellen, ob die Datei tatsächlich existiert, bevor ich eine blinde "Bitte" darauf mache. Andernfalls verlieren Sie die Fähigkeit zu überprüfen, ob eine Klasse ladbar ist (was für Adapter usw. nützlich sein kann) ... – ircmaxell

+0

In meinem Beispiel befinden sich alle Klassendateien im selben Verzeichnis. Aber ja, Dateicheck ist eine gute Idee. – AutoSponge

0

Was passiert, ist ziemlich logisch. Ihre __autoload-Funktion enthält wahrscheinlich nur ClassName.php, so dass die Echo-Anweisung, die Sie dort erhalten haben, ausgeführt wird.

Wenn Sie versuchen zu entscheiden, ob eine Klassendefinition in einer Datei vorhanden ist, können Sie den Inhalt der Datei lesen (file_get_contents oder eine ähnliche Funktion) und dann diese Inhalte nach einer Klassendefinition mit regulären Ausdrücken oder durchsuchen mit token_get_all (siehe Determining what classes are defined in a PHP class file).

+0

gut, wie ClassName.php ohne Ausführen von Echo-Anweisungen enthalten ...... –

+1

Das ist einfach nicht möglich, einschließlich Code wird ** alles **, die nicht in einer Funktion oder einer Klasse enthalten ist ausgeführt werden. Also, entweder die Datei nicht enthalten oder die echo-Anweisungen in eine Funktion/Klasse einfügen. – wimvds

+0

Aber ich weiß nicht, ob die Datei eine Klasse haben wird oder ein einfaches Skript ist, weil ich eine Liste von Dateien habe, was ich tun muss, um zu wissen, welche dieser Dateinamen Klassen sind oder nicht. –

12

Ok, also hier ist, wie es intern funktioniert. Wenn Sie versuchen, eine Klasse zu verwenden, die nicht existiert, ruft sie nacheinander alle spl_autoload Callbacks auf, bis die Klasse existiert (und die __autoload Funktion ist eine davon). Wenn es am Ende der Kette nicht existiert, wird der Fehler Klasse nicht gefunden ausgelöst.

Wenn Sie class_exists ohne den zweiten Parameter nennen (was es nicht zu versuchen, erzählt zu laden, wenn es nicht vorhanden ist), ruft er die Kette von spl_autoload Rückrufen bis er entweder die Klasse findet, oder die letzte Methode wird aufgerufen, . Dann kehrt es zurück, wenn es die Klasse gefunden hat.

Es hängt also alles davon ab, was Sie in der Autoload-Funktion tun. Wenn Sie etwas tun wie:

function __autoload($class) { 
    $filename = PATH_TO_CLASSES . $class . '.php'; 
    if (!file_exists($class)) { 
     die('Could not find '.$class); 
    } 
    require_once $filename; 
} 

Es wird Ausführung beenden und es wird nicht wie vorgesehen funktionieren. Stattdessen sollten Sie tun:

function __autoload($class) { 
    $filename = PATH_TO_CLASSES . $class . '.php'; 
    if (file_exists($class)) { 
     require_once $filename; 
    } 
} 

Das ist alles, was Sie tun müssen.

Jetzt möchten Sie nicht, dass die Datei ausgeführt wird. Das ist gut. Dafür gibt es eine einfache Lösung. Legen Sie diese Datei nicht in dasselbe Verzeichnis wie Ihre automatisch geladenen Klassen. Es vereitelt den Zweck des Autoloading.

Die einzige andere Lösung wäre, eine Zuordnung von Klassennamen zu Dateinamen zu speichern und daraus das Autoloading abzuleiten. Sonst würde es immer die Datei ausführen (da das ist was du verlangst) ...

10

Wenn Sie class_exists verwenden, wird der Autoloader standardmäßig aktiviert. Aus diesem Grund sehen Sie Ihr Problem. Sie können den registrierten Autoloader umgehen, indem Sie den zweiten Parameter auf false setzen.

class_exists('foo', false) 

From PHP Documentation

+0

Ich bin mir nicht sicher, warum dies bei der tatsächlichen Dokumentation abgelehnt wurde. –

+0

Da Sie den Autoloader nicht umgehen, indem Sie den zweiten Parameter auf false setzen. Sie umgehen einfach den Fehler, der ausgelöst wird, wenn NACHDEM die Klasse immer noch nicht geladen wurde. –

+2

Das ergibt aus der Dokumentation überhaupt keinen Sinn. Warum würden sie es mit einem bool val "autoload" nennen? –