2010-01-07 18 views
6

Debería haberle preguntado a alguien esto hace mucho tiempo.Usar correctamente las clases en otras clases en php?

¿Cuál es la mejor manera de usar otras clases dentro de otra clase?

Por ejemplo, digamos que tengo una clase de aplicación:

class Application 
{ 
    public function displayVar() { 
     echo 'hello world'; 
    } 
} 

y una clase de base de datos

class Database 
{ 
    // connects to db on construct 
    public function query() { 
     // queries db 
    } 
} 

Ahora, quiero agregar una función a mi clase de aplicación que utiliza una función de la clase db

class Application 
{ 
    public function displayVar() { 
     echo 'hello world'; 
    } 
    public function getVar() { 
     global $db; 
     $sql = foo; 
     $db->query($sql); 
    } 
} 

es así, tengo

$db = new Database(); 
$app = new Application(); 
$app->getVar('var'); 

¿Hay una forma mejor de hacerlo? Realmente lo que estoy buscando es la forma estándar de hacerlo, no otra forma de manipularlo.

+1

Sí, esa pregunta es profundizando en esto. Es posible que desee comprobarlo Ciudadano. –

+0

Na, la respuesta aquí es exactamente lo que estaba buscando. – Citizen

Respuesta

12

Hay un par de maneras de hacer eso. Las variables globales son, sin duda, una de las formas y también menos valoradas. Puede crear un Singleton y todas las demás clases que necesiten acceso a la base de datos llamarán a este singleton.

final class Database { 
    private static $connection; 

    public static function getInstance() { 
     if(self::$connection == NULL) { 
      self::$connection = // init your database connection 
     } 
     return self::$connection; 
    } 
} 

Y utilice este objeto de conexión de base de datos en cualquier clase que lo necesite.

class Application { 
    public function displayVar() { 
     echo 'hello world'; 
    } 
    public function getVar() { 
     $db = Database::getInstance(); 
     $sql = foo; 
     $db->query($sql); 
    } 
} 

Esto es todo bien para un comienzo y un gran paso más allá de la utilización de variables globales, pero se puede hacer mejor con Dependency Injection. La Inyección de Dependencia es un concepto simple de que si una clase tiene dependencias externas, como la conexión de la base de datos en su ejemplo, las pasa explícitamente a la clase necesitada en su constructor o en un método. Entonces, el nuevo código se parecería a la solución de Jonathan. Una gran ventaja de usar la inyección de dependencia es en pruebas unitarias, donde puede reemplazar fácilmente este objeto de base de datos real con un objeto simulado y pasarlo a quien lo necesite.

class Application { 
    private $db; 

    public function __construct(Database $db) { 
     $this->db = $db; 
    } 

    public function displayVar() { 
     echo 'hello world'; 
    } 

    public function getVar() { 
     $sql = foo; 
     $this->db->query($sql); 
    } 
} 

Para proyectos más pequeños, puede hacerlo usted mismo fácilmente. Para proyectos grandes, hay varios DI frameworks available for PHP

+0

¡Muchas gracias! – Citizen

+0

Es posible que desee poner un poco más énfasis en su segunda solución, ya que el enfoque singleton realmente es propenso a una gran cantidad de problemas. En general se considera como algo malo (pero lamentablemente todavía se usa ampliamente). – ToBe

2

$db podría ser una propiedad de su clase Application. Cualquier referencia a él desde dentro de una instancia de Application se llevaría a cabo a través de $this - $this->db

class Application { 

    private $db = null; 

    public function setDB($name) { 
    $this->db = new Database($name); 
    } 

} 
+0

Sí, lo tengo, pero ¿qué hay de otras clases? Me gusta si tuviera un user.class.php o un admin.class.php, aún tendría que globalizar la clase para usarla. – Citizen

+0

Tendrás que dar más información sobre tu proyecto. – Sampson

1

Incluya el archivo de clase (o configure autoinclude) en cada archivo PHP que necesite la clase en cuestión. Luego ejecútalo según sea necesario.

Si es necesario tener una instancia de "común" de un objeto, se puede ver en los patrones Singleton y fábrica:

Singleton Pattern Factory Pattern