2009-10-17 181 views
38

Me preguntaba si está permitido crear una instancia de una clase dentro de otra clase.¿Puedo instanciar una clase de PHP dentro de otra clase?

O, ¿tengo que crearlo afuera y luego pasarlo a través del constructor? Pero luego lo habría creado sin saber si lo necesitaría.

Ejemplo (una clase de base de datos):

class some{ 

if(.....){ 
include SITE_ROOT . 'applicatie/' . 'db.class.php'; 
$db=new db 

Respuesta

29

No se puede definir una clase en otra clase. Debe incluir archivos con otras clases fuera de la clase. En su caso, eso le dará dos clases de nivel superior db y some. Ahora en el constructor de some puede decidir crear una instancia de db. Por ejemplo:

include SITE_ROOT . 'applicatie/' . 'db.class.php'; 

class some { 

    public function __construct() { 
     if (...) { 
      $this->db = new db; 
     } 
    } 

} 
+10

Recomendaría usar 'require' en lugar de' include'. –

+2

Esto también parece una buena situación para utilizar el patrón de diseño de inyección de dependencia. – Ejaz

+6

@ rink.attendant.6 'require_once' es aún mejor: D –

2

Es imposible crear una clase en otra clase en PHP. Crear un objeto (una instancia de una clase) en otro objeto es algo diferente.

+0

¿Cómo harías para hacer algo similar a esto? –

13

Solo quería señalar que es posible cargar una definición de clase dinámicamente dentro de otra definición de clase.

Lukas tiene razón en que no podemos definir una clase dentro de otra clase, pero podemos incluir() o requerir() dinámicamente, ya que cada función y clase definida en el archivo incluido tendrá un alcance global. Si necesita cargar una clase o función dinámicamente, simplemente incluya los archivos en una de las funciones de la clase. Usted puede hacer esto:

function some() 
{ 
    require('db.php'); 
    $db = new Db(); 
    ... 
} 

http://php.net/manual/en/function.include.php

+1

Para una carga de clase dinámica, recomendaría usar 'require_once' o' include_once' - de esa manera se asegurará de que no lo haya incluido/requerido más de una vez :) –

+2

en este caso debe usar "include_once" porque "require" will llamar cuando ese archivo (donde la función está definida) se incluye en el sistema. pero puede usar include o include_once en la sub-rutina. se ejecutará cuando el puntero entre en esa sub-rutina –

2

No, no es posible. Las clases de anidación y la agregación de objetos son mecanismos diferentes. Anidar clases significa nombres de clase de anidación, de hecho. La clase A anidada en la clase B se llamaría "B \ A" (?). Desde v5.3 puede anidar nombres de clase (y algunos otros nombres) en espacios de nombres.

16

Las personas que dicen que es posible 'crear una clase dentro de una clase' parecen querer decir que es posible crear un objeto/instancia dentro de una clase. No he visto un ejemplo de una definición de clase real dentro de otra definición de clase, lo que se vería así:

class myClass{ 

    class myNestedClass{ 

    } 

} 

/* THIS IS NOT ALLOWED AND SO IT WON'T WORK */ 

Dado que la pregunta era '¿Es posible crear una clase dentro otra clase', me ahora solo puedo suponer que NO es posible.

+0

Sin embargo, hay ejemplos en otros lenguajes de programación, y las clases anidadas son útiles: http://docs.oracle.com/javase/tutorial/java/javaOO/nested. html –

1

Esto es posible en PHP 7 con Anonymous classes.

Véase el ejemplo de the docs:

class Outer 
{ 
    private $prop = 1; 
    protected $prop2 = 2; 

    protected function func1() 
    { 
     return 3; 
    } 

    public function func2() 
    { 
     return new class($this->prop) extends Outer { 
      private $prop3; 

      public function __construct($prop) 
      { 
       $this->prop3 = $prop; 
      } 

      public function func3() 
      { 
       return $this->prop2 + $this->prop3 + $this->func1(); 
      } 
     }; 
    } 
} 

echo (new Outer)->func2()->func3(); 
// Output: 6 

Este es un ejemplo simple que muestra el uso de las clases anónimas, pero no desde dentro de una clase:

// Pre PHP 7 code 
class Logger 
{ 
    public function log($msg) 
    { 
     echo $msg; 
    } 
} 

$util->setLogger(new Logger()); 

// PHP 7+ code 
$util->setLogger(new class { 
    public function log($msg) 
    { 
     echo $msg; 
    } 
}); 
+0

¿Func3 no está disponible globalmente en la instancia de clase 'externa'? –

+1

@ChrisO Nope. 'print_r (get_class_methods ('Outer'));' prints' Array ([0] => func2) ' –

+0

Eso es muy malo, pero es algo de todos modos. Solo un poco más de sintaxis, gracias. :) –

0

(Editar) Ok la pregunta y la ejemplo de lo que estás tratando de lograr es confuso. Parece que en su ejemplo está tratando de DEFINIR una clase dentro de otra clase.

El nombre correcto para esto es NESTED CLASS y no es posible en PHP. Entonces, para su ejemplo, la respuesta es "NO". No en PHP de todos modos. Otros idiomas permitirán "clases anidadas". Java es un ejemplo.

Por ejemplo, esto no funciona en PHP

class outer_class{ 
    class inner_class{ 
     ... 
    } 
    ... 
} 

Ahora la pregunta planteada es crear una instancia de una clase en otra clase.

Para esto, la respuesta es "SÍ", puede INSTANTIAR un "objeto" dentro de una "clase". Lo hacemos todo el tiempo

class simple_class{ 

    protected $instanceOfOtherClass; 

    public function instanciateObject_KeepingAReferenceToIt(){ 
     // create an instance of OtherClass and associate it to $this->instanceOfOtherClass 
     $this->instanceOfOtherClass = new OtherClass(); 
    } 

    public function instanciateObject_Without_KeepingAReferenceToIt(){ 
     // create an instance of OtherClass and return it 
     return new OtherClass(); 
    } 
} 

Una clase incluso se puede crear una instancia. Eso es lo que hace el famoso singleton y muchos otros Creational patterns. Lamentablemente, algunas personas creen que saber dependency injection significa que nunca volverán a llamar a NEW en un método. INCORRECTO.

Ayuda a comprender la diferencia entre una clase y un objeto. A class es una plantilla de código de programa extensible para crear objetos. Un object se refiere a una instancia particular de una clase.

Cuestiones relacionadas