2009-07-18 21 views
6

Actualmente estoy creando un sistema de blog, que espero convertir en un CMS completo en el futuro.¿Cómo evitar el uso de objetos globales PHP?

Hay dos clases/objetos a los que sería útil tener acceso global (la conexión de base de datos mysqli y una clase personalizada que verifica si un usuario ha iniciado sesión).

Estoy buscando una forma de hacer esto sin usar objetos globales, y si es posible, no pasar los objetos a cada función cada vez que son llamados.

Respuesta

13

Podrías hacer que los objetos Estáticos, entonces tienes acceso a ellos en cualquier lugar. Ejemplo:

myClass::myFunction(); 

Eso funcionará en cualquier parte del script. Sin embargo, es posible que desee leer en clases estáticas y, posiblemente, utilizar una clase Singleton para crear una clase regular dentro de un objeto estático que pueda usarse en cualquier lugar.

Ampliado

Creo que lo que estamos tratando de hacer es muy similar a lo que hago con mi clase DB.

class myClass 
{ 
    static $class = false; 
    static function get_connection() 
    { 
     if(self::$class == false) 
     { 
      self::$class = new myClass; 
     } 
     return self::$class; 
    } 
    // Then create regular class functions. 
} 

Lo que sucede es después de obtener la conexión, utilizando $ objeto = myClass :: get_connection(), usted será capaz de hacer cualquier cosa función con regularidad.

$object = myClass::get_connection(); 
$object->runClass(); 

Expanded

Una vez que hacer que las declaraciones estáticas, sólo hay que llamar get_connection y asignar el valor devuelto a una variable. Luego, el resto de las funciones pueden tener el mismo comportamiento que una clase a la que llamó con $ class = new myClass (porque eso es lo que hicimos). Todo lo que está haciendo es almacenar la variable de clase dentro de una clase estática.

class myClass 
{ 
    static $class = false; 
    static function get_connection() 
    { 
     if(self::$class == false) 
     { 
      self::$class = new myClass; 
     } 
     return self::$class; 
    } 
    // Then create regular class functions. 
    public function is_logged_in() 
    { 
     // This will work 
     $this->test = "Hi"; 
     echo $this->test; 
    } 
} 

$object = myClass::get_connection(); 
$object->is_logged_in(); 
+0

Hola, gracias por su respuesta, es posible guardar variables en clases estáticas. es decir, llamar a la función para verificar si el usuario está conectado, y luego acceder a esta variable varias veces más adelante en la página? –

+2

Sí, para una clase estática hago lo mismo que hice para declarar la variable $ class. Lo único es que 'tienes' que declarar cada variable que usas. –

+1

Pero, el código que te di te permite usar cualquier clase regular, bueno, regularmente. La parte estática simplemente le da la clase, en lugar de globalizarla. Voy a editar para mostrar un poco más. –

1

Bueno, si ya tiene algún objeto por el cual se refiere al sistema de blog, puede componer estos objetos en que, para que sean $blog->db() y $blog->auth() o lo que sea.

+0

Podría, pero también será necesario acceder a los objetos fuera de la clase de blog. –

8

Puede pasar los objetos actualmente globales en el constructor.

<?php 
    class Foo { 
    protected $m_db; 
    function __construct($a_db) { 
     $this->m_db = $a_db; 
    } 
    } 
?> 
3

Recientemente renové mi estructura en preparación para la segunda versión del CMS de nuestra compañía. I undid una gran cantidad de cosas que hice estáticas para reemplazarlas con objetos normales. Al hacerlo, creé una gran cantidad de flexibilidad que solía depender de que yo revisara y pirateara los archivos centrales. Ahora solo uso construcciones estáticas cuando la única alternativa son las funciones globales, que solo está relacionada con la funcionalidad básica de bajo nivel.

Voy a mostrar algunas líneas de mi archivo bootstrap.php (todas mis solicitudes se envían a través de ese archivo, pero puede lograr el mismo resultado al incluirlo en la parte superior de cada archivo) para mostrarle lo que quiero decir. Esta es una versión bastante fuerte de lo que probablemente usarías en tu situación, pero espero que la idea sea útil. (Todo esto es ligeramente modificado.)

//bootstrap.php 

... 

// CONSTRUCT APPLICATION 

{  
    $Database = new Databases\Mysql(
     Constant::get('DATABASE_HOST'), 
     Constant::get('DATABASE_USER'), 
     Constant::get('DATABASE_PASSWORD'), 
     Constant::get('DATABASE_SCHEMA') 
    ); 

    $Registry  = new Collections\Registry; 
    $Loader  = new Loaders\Base; 
    $Debugger  = new Debuggers\Dummy; // Debuggers\Console to log debugging info to JavaScript console 

    $Application = new Applications\Base($Database, $Registry, $Loader, $Debugger); 
} 

... 

Como se puede ver, tengo todo tipo de opciones para la creación de mi objeto de aplicación, que puedo proporcionado como un argumento en el constructor a otros objetos para darles acceso a estas necesidades "globales".

El objeto de la base de datos se explica por sí mismo. El objeto de registro actúa como un contenedor para el objeto al que deseo acceder en otro lugar de la aplicación. El cargador actúa como una utilidad para cargar otros recursos como archivos de plantilla. Y el depurador está ahí para manejar la salida de depuración.

Puedo, por ejemplo, cambiar la clase de base de datos que instancia y, si tengo una conexión a una base de datos SQLite. Puedo cambiar la clase del depurador (como se indicó) y ahora toda mi información de depuración se registrará en mi consola de JavaScript.

Bien, volviendo al problema. ¿Cómo le da acceso a otros objetos a todo esto? Simplemente pásalo en una discusión al constructor.

// still bootstrap.php 

... 

// DISPATCH APPLICATION 

{ 
    $Router = new Routers\Http($Application); 
    $Router->routeUri($_SERVER['REQUEST_URI']); 
} 

... 

No solo eso, sino que mi enrutador (o cualquier objeto que construya con él) también es más flexible. Ahora puedo crear una instancia de mi aplicación de forma diferente, y mi router se comportará de manera diferente.

Cuestiones relacionadas