2010-09-28 16 views
9

Ejemplo:¿Hay alguna forma de usar CLASS_EXISTS y __autoload sin CRASH en el script?

ClassName.php

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

En otro archivo ...

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

La salida de este código es: Esto se bloqueará todo

lugar de esto: ClassName doe existe sn't ....

función de carga automática:

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

obviusly es necesario el uso de autocarga porque la clase no se ha cargado! –

+0

Muestra tu función de carga automática ... Debería mostrar 'ClassName does exists ...' after the 'This crash all', ya que no le importa por defecto si la clase no está cargada. Sospecho que estás matando la ejecución en la función '__autoload' si no encuentras la clase, y no deberías ... – ircmaxell

+0

Del código que se da los resultados no pueden reproducirse. Así que publique un poco más de código. – tplaner

Respuesta

1

Use class_exists dentro de la función de carga automática, entonces no se te ocurra volver a usar. Ese es el punto del autocargador.

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? No, no lo es ... Hay muchos usos para class_exists. Una de ellas es ver si la clase es cargable para empezar (para ver si está disponible). Además, no hay ninguna razón para llamar 'class_exists' dentro de la función de carga automática, ya que sabes que aún no lo hace (a menos que alguien lo llame manualmente, pero no deberían hacerlo de todos modos). Ah, y si fuera tú, haría una comprobación para determinar si el archivo existe realmente antes de simplemente hacer un 'requisito' ciego sobre él. De lo contrario, perderá la capacidad de verificar si una clase es cargable (lo que puede ser útil para adaptadores, etc.) ... – ircmaxell

+0

En mi ejemplo, todos los archivos de clase están en el mismo directorio. Pero sí, la verificación de archivos es una buena idea. – AutoSponge

0

Lo que sucede es bastante lógico. Su función __autoload probablemente solo incluya ClassName.php, por lo que ejecutará la instrucción echo que haya obtenido allí.

Si está tratando de decidir si hay una definición de clase en un archivo, puede leer el contenido del archivo (usando file_get_contents o una función similar) y luego escanear estos contenidos para una definición de clase utilizando expresiones regulares o usando token_get_all (ver Determining what classes are defined in a PHP class file).

+0

bien, cómo incluir ClassName.php sin ejecutar instrucciones de eco ...... –

+1

Eso simplemente no es posible, incluido el código que ejecutará ** cualquier cosa ** que no esté contenido en una función o una clase. Entonces, o no incluyen el archivo ni colocan las instrucciones de eco dentro de una función/clase. – wimvds

+0

Pero no sé si el archivo tendrá una clase o simplemente es una secuencia de comandos porque tengo una lista de archivos, lo que debo hacer es saber cuáles de estos nombres de archivo son o no clases. –

12

Ok, así es como funciona internamente.

Cuando intenta utilizar una clase que no existe, llama a cada una de las devoluciones de llamada spl_autoload una por una hasta que exista la clase (y la función __autoload es una de ellas). Si no existe al final de la cadena, aumenta el error de clase no encontrada.

Cuando llama al class_exists sin el segundo parámetro (que le dice que no intente cargarlo si no existe), llama a la cadena de spl_autoload devoluciones de llamada hasta que encuentra la clase o se llama al último método . Luego vuelve si encontró la clase.

Por lo tanto, todo depende de lo que esté haciendo en la función de autocarga. Si haces algo como:

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

Mata la ejecución y no funcionará según lo previsto. En su lugar, debe hacer:

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

Eso es todo lo que necesita hacer.

Ahora, no desea que se ejecute el archivo. Esta bien. Hay una solución fácil para eso. No coloque ese archivo en el mismo directorio que las clases cargadas automáticamente. Derrota el propósito de la carga automática.

La única otra solución sería almacenar un mapa de nombres de clase a nombres de archivo, y basar su carga automática fuera de eso. De lo contrario, siempre ejecutará el archivo (ya que eso es lo que le pedirá que haga) ...

10

El uso de class_exists golpeará el autocargador de manera predeterminada y es por eso que está viendo su problema. Puede omitir el autocargador registrado configurando el segundo parámetro en falso.

class_exists('foo', false) 

From PHP Documentation

+0

No estoy seguro de por qué esto fue downvoted cuando se trata de documentación real. –

+0

Porque no omite el autocargador estableciendo el segundo parámetro en falso. Simplemente omita el error que se plantea si DESPUÉS de que la clase todavía no se carga. –

+2

Eso no tiene ningún sentido de la documentación en absoluto. ¿Por qué lo llamarían 'autoload' con un bool val? –

Cuestiones relacionadas