2010-04-09 15 views
8

lo tanto, si se intenta hacer una clase anidada como esto:PHP Las clases anidadas funcionan ... ¿algo así?

//nestedtest.php 

class nestedTest{ 
    function test(){ 
     class E extends Exception{} 
     throw new E; 
    } 
} 

obtendrá un error Fatal error: Class declarations may not be nested in [...]

pero si usted tiene una clase en un archivo separado de este modo:

//nestedtest2.php 

class nestedTest2{ 
    function test(){ 
     include('e.php'); 
     throw new E; 
    } 
} 

//e.php 
class E Extends Exception{} 

Entonces, ¿por qué la segunda forma hacky de hacerlo funcionar, pero la forma no hacky de hacerlo no funciona?

Respuesta

18

Desde el manual (http://php.net/manual/en/function.include.php):

Cuando se incluye un archivo, el código que contiene hereda el ámbito de variable de la línea en la que la incluyen ocurre. Cualquier variable disponible en esa línea en el archivo de llamada será disponible dentro del archivo llamado, desde que apuntan hacia adelante. Sin embargo, todas las funciones y clases definidas en el archivo incluido tienen el alcance global.

+1

+1 no sabía que – soulmerge

+0

Por lo tanto, tienen un alcance global, y puedo llamar a todos los funciones privadas y protegidas que la clase tiene ... – SeanJA

+0

@SeanJA: como tienen alcance global, _no_ podrán llamar a los métodos no públicos de la clase que contenía el include() –

1

La segunda forma no es anidar las clases. Solo tiene sus dos declaraciones en un archivo, que es diferente de su primer ejemplo. En PHP puede tener múltiples declaraciones de clase en un archivo, es una decisión de la organización no un requisito.

+1

Aún así, tiene un punto: incluye el código dentro de una función. –

+1

@Pekka Es por cómo funciona include: * Cuando se incluye un archivo, el código que contiene hereda el alcance variable de la línea en la que ocurre la inclusión. Cualquier variable disponible en esa línea en el archivo de llamada estará disponible dentro del archivo llamado, desde ese punto en adelante. Sin embargo, todas las funciones y clases definidas en el archivo incluido tienen el alcance global. * Consulte http://de3.php.net/manual/en/function.include.php – Gordon

+1

No importa porque están en el mismo archivo. Puede obtener el mismo efecto colocando la clase Exception en otro archivo e incluyéndola o usando __autoload. –

1

No hay una buena razón para definir una clase dentro de un método. La 2ª manera "funciona" solo en el sentido de que no arroja un error: la clase todavía existe en el mismo ámbito/espacio de nombres que todas las otras clases definidas. Entonces, en realidad no estás "anidando" una clase en este escenario.

Por cierto, la razón por la que funciona es porque una clase es simplemente una definición, no hay ejecución involucrada en la definición de una clase. Entonces ese archivo (e.php) se analiza tan pronto como lo incluye, y luego su clase queda disponible para el contexto de ejecución actual. Solo las partes ejecutables del código (es decir, throw new E;) pertenecerán en realidad al alcance de la persona que llama.

+0

Esto en realidad surgió porque estaba preocupado de que la segunda forma no funcionara porque la primera forma no ... cuando lo hizo, estaba un poco perplejo. – SeanJA

Cuestiones relacionadas