Foros del Web

Foros del Web (http://www.forosdelweb.com/)
-   Frameworks y PHP orientado a objetos (http://www.forosdelweb.com/f68/)
-   -   Conocer si se ha instanciado una clase (http://www.forosdelweb.com/f68/conocer-si-ha-instanciado-clase-262039/)

jpinedo 14/01/2005 17:54

Conocer si se ha instanciado una clase
 
Hola:
Quiero saber si es posible conocer si una clase ha sido instanciada y si es posible, obtener referencias a esas instancias.

Todo esto sabiendo sólo el nombre de la clase.

Saludos:adios:

jpinedo 15/01/2005 23:15

En realidad lo que quiero es:
Tengo una clase "Ejemplo".
Necesito que cada una de las instancias de "Ejemplo" conozca (posea una referencia) a todas las otras instancias que pueda tener esa clase.

Saludos:adios:

jpinedo 15/01/2005 23:29

Lo que no quiero es hacer una clase adicional que maneje las instancias de mi clase "Ejemplo"

Ahora no tengo PHP5 y por lo tanto no puedo hacer pruebas...
¿Podría hacer algo así?
Código PHP:

class Ejemplo{
   static 
$instancias = array();// esta sería la solución (¿?)
   
public $atributo;

   function 
__construct($var){
       
self::$instancias[] = $this;
       
$this->atributo $var;
   }

   public function 
imprimir_instancias(){
      foreach(
self::$instancias as $inst){
          echo 
"<pre>\n";
          
var_dump($inst);
          echo 
"</pre>\n<hr />";
      }
   }
}

// Esto funcionará??
$ejem1 = new Ejemplo("uno");
$ejem2 = new Ejemplo("dos");

$ejem1->imprimir_instancias(); 

Saludos:adios:

sism82 16/01/2005 01:02

tu codigo debe funcionar correctamente. saludos

jpinedo 16/01/2005 01:28

Supongo que no está bien mezclar accesos a atributos estáticos y métodos no estáticos....
Tal vez sea una mejor idea tener una variable global que sea un array que guarda las referencias y que ese array se actualice desde el constructor de la clase.

Saludos:adios:

Herminio Heredia San 17/01/2005 15:50

Si te entiendo bien, lo que quieres hacer es tener un lugar comun de donde hacer referencia de una clase ya instanciada para no tener que volver a crearla. Si es asi, puedes usar el patron singleton que se asegura de devolverte una istancia nueva solo si no hay ya una existente.
Ahora que si tu problema es tener una relacion de todas las istancias de clase que hay durante la ejecucion de tu script posiblemente almacenar la referencia del objeto en un arreglo sea la solucion o implementar la interface Iterator de php5 o crear una para php4.
Para el primer caso una implementacion del Singleton en php5 podria ser la siguiente;
Código PHP:

class Ejemplo{
   static private 
$instancia null;     
   public 
$atributo;

   private function 
__construct($var){
       
$this->atributo $var;
   }
   
   public static function 
instSingleton($var){
       if( 
self::$instancia == null ){
       
self::$instancia = new Ejemplo($var);
       }else{
       return 
self::$instancia
       }
   }
   
   public function 
obtAtributo(){
       return 
$this->atributo;
   }


$x Ejemplo::instSingleton('unica instancia');
echo 
$x->obtAtributo();
$y Ejemplo::instSingleton('devuelve la misma instancia');
echo 
$x->obtAtributo(); 

Para el segundo caso puedes usar el iterador para alamcenar las instancias y pasarlo como parametro a los objetos que lo necesiten.

Si esto no es lo que estabas preguntando pues una disculapa por el choro mareador que escribi jejeje.

jpinedo 17/01/2005 21:52

Hola Herminio... gracias por responder.

Justamente buscando respuesta a mi pregunta dí con la explicación del Singleton que hay en el manual de PHP ( y aproveché para \'lanzar\' una taducción y postearla aquí, en la traducción que inició Calisco ).... como siempre, has hecho una explicación impecable... pero mi pregunta iba más bien por el segundo caso que enuncias.

Lo que quería era, en la medida de lo posible, que el usuario no tenga que instanciar más que mi clase "Ejemplo" (las veces que necesite) y que cada instancia pueda "ver" a todas sus "hermanas" automáticamente...

No sé si el iterador se pueda instanciar desde dentro de la clase "Ejemplo"... Para hacerlo, tal vez en ese iterador pueda utilizar un Singleton para que sea creado sólo cuando se instancie "Ejemplo" por primera vez y las otras instancias de "Ejemplo" no creen un iterador nuevo sino que utilicen el que creo la primera.

En realidad lo que sé del iterador es casi nulo... por eso antes de seguir hablando estupideces (¿?) voy a estudiarlo un poco...

Ya regreso. (opinen con confianza)

Saludos:adios:

Herminio Heredia San 18/01/2005 16:05

Si puedes. La ventaja es que en php5 ya tienes iteradores los cuales puedes implementar o extender dependiendo de lo que necesites. Por ejemplo para el caso que estas pidiendo puse la inicializacion de la clase ArrayIterator que ya esta predefinida en php5 como parte de la Standard Php Library ( es recomendable darse una vuelta por ese manual ). Asi que a partir del ejemplo que ya habia puesto en el mensaje anterior podemos hacer algo como lo siguiente (tomalo como ejemplo didactico )
Código PHP:

class Ejemplo{
    
   static private 
$instIterator null;
   private 
$atributo;

   public function 
__construct($var){
       
$this->atributo $var;
       
self::instSingleton();
       
self::$instIterator->append($this);
   }
   
   private function 
instSingleton(){
       if( 
self::$instIterator == null ){
       
self::$instIterator = new ArrayIterator($arreglo = array());
       }
   }
   
   public function 
obtAtributo(){
       return 
$this->atributo;
   }
   
   public function 
obtArrayIterator(){
       return 
self::$instIterator;
   }
}

$x =  new Ejemplo('unica instancia');
$y = new Ejemplo('devuelve la misma instancia');
$it $y->obtArrayIterator();
while(
$it->valid()){
    
$obj $it->current();
    echo 
$obj->obtAtributo()."<br>\n";
    
$it->next();


Como puedes apreciar la clase se instancia y si ya existe un ArrayIterator no vuelve a crear uno nuevo, el unico problema de esta implementacion es el caso en que quieras acceder a una instancia especifica de la clase Ejemplo, ya que tendrias que validar de alguna forma cual es la que quieres acceder para agregar o cambiar el estado del objeto mediante sus atributos. Para esa tarea lo que puedes hacer es una implementacion de la interface Iterator para que maneje arreglos asociativos, ya todo es cuestion de que veas las opciones.

jpinedo 18/01/2005 17:01

Gracias Herminio... es justamente eso a lo que me refería
Cita:

Iniciado por jpinedo
No sé si el iterador se pueda instanciar desde dentro de la clase "Ejemplo"... Para hacerlo, tal vez en ese iterador pueda utilizar un Singleton para que sea creado sólo cuando se instancie "Ejemplo" por primera vez y las otras instancias de "Ejemplo" no creen un iterador nuevo sino que utilicen el que creo la primera.

Claro que yo no tengo esa facilidad para explicar las cosas (bueno, debe ser también porque aún no las tengo tan claras)...
Muchas gracias por el ejemplo tan ilustrativo.
Bueno... nada más que decir... a seguir estudiando y empecemos por el enlace a la Standard Php Library que dejaste.

Gracias otra vez.

Saludos:adios:

jpinedo 22/02/2005 22:14

Bueno... ha pasado algún tiempo y debido a otro post regresé a este.
Después de leer el ejemplo de Herminio una vez más y tener todo claro.... simplemente cambiaría una cosita que no afectaría el funcionamiento pero sí puede confundir un poco al resto de usuarios que lo lean.
Código PHP:

$x =  new Ejemplo('una instancia');// Esta no sería la única instancia
$y = new Ejemplo('otra instancia');// Por lo tanto esta no sería la misma
$it $y->obtArrayIterator();
while(
$it->valid()){
    
$obj $it->current();
    echo 
$obj->obtAtributo()."<br>\n";
    
$it->next();


Era una cuestión mínima... pero así queda más claro, ya que $x e $y son objetos diferentes... lo que comparten es el mismo iterador.

Un saludo:adios:


La zona horaria es GMT -6. Ahora son las 10:05.

Desarrollado por vBulletin® Versión 3.8.7
Derechos de Autor ©2000 - 2026, Jelsoft Enterprises Ltd.