2011-11-22 25 views
11

Estoy un poco confundido sobre cómo funcionan los constructores en PHP.Constructores PHP y funciones estáticas

Tengo una clase con un constructor al que se llama cuando instancia un nuevo objeto.

$foo = new Foo($args); 

__construct($params) se llama en la clase Foo y ejecuta el código de inicialización correcto.

Sin embargo, cuando uso la clase para llamar a una función estática, se llama al constructor de nuevo.

$bar = Foo::some_function(); //runs the constructor from Foo 

Esto hace que el constructor para ejecutar, ejecutar el código objeto de inicialización que tenía la intención sólo para cuando se crea un nuevo objeto Foo.

¿Me falta el sentido de cómo funcionan los constructores? ¿O hay alguna manera de evitar que se ejecute __construct() cuando uso la clase para hacer llamadas a funciones estáticas?

¿Debo usar una función "fábrica" ​​para hacer la inicialización del objeto? Si es así, ¿cuál es el punto del constructor entonces?

:: EDIT :: Tengo un formulario donde los usuarios pueden subir fotos a un álbum (create_photo.php) y un área donde pueden ver el álbum (view_photos.php). Al enviar el formulario:

$photo = new Photo($_FILES['photo'], $_POST['arg1'], ect..); 

El constructor de Foto crea y guarda la foto. Sin embargo, en view_photo.php, cuando llamo a:

$photo = Photo::find_by_id($_POST['id']) //user-defined function to query database 

¡Esto está provocando que el constructor de Photo se ejecute!

+8

Eso no puede estar bien. Proporcione el código completo donde el constructor recibe una llamada estática. – mAu

+0

Muestra tu código real. Lo que estás escribiendo no parece correcto. –

+0

¿Cómo se ve el constructor, desde qué comportamiento concluyes que se ejecuta? – markus

Respuesta

16

No veo nada que replique su pregunta.

Ver Demo: http://codepad.org/h2TMPYUV

Código:

class Foo { 
    function __construct(){ 
     echo 'hi!'; 
    } 
    static function bar(){ 
     return 'there'; 
    } 
} 

echo Foo::bar(); //output: "there" 
+2

¿No debería ser '__construct()'? El resultado es el mismo aunque ... – jeroen

+0

@jeroen arreglado^_^nice catch – Neal

6

Asunción PHP 5.x

diferentes objetivos, diferentes de ruta

  1. crear una nueva instancia de una clase (objeto)

    class myClassA 
    { 
        public $lv; 
    
        public function __construct($par) 
        { 
         echo "Inside the constructor\n"; 
         $this->lv = $par; 
        } 
    } 
    
    $a = new myClassA(11); 
    $b = new myClassA(63); 
    

    porque creamos un nuevo objeto PHP llamadas:

    __construct($par);

    del nuevo objeto, así que:

    $a->lv == 11 
    
    $b->lv == 63 
    
  2. utilizar una función de una clase

    class myClassB 
    { 
        public static $sv; 
    
        public static function psf($par) 
        { 
         self::$sv = $par; 
        } 
    } 
    
    myClassB::psf("Hello!"); 
    $rf = &myClassB::$sv; 
    myClassB::psf("Hi."); 
    

    ahora $rf == "Hi."

    función o variabiles obligada definido estática para ser visitada por ::, no se crea ningún objeto llamando a "psf", la "variable de clase" sv tiene onl y 1 instancia dentro de la clase.

  3. utilizar un producto único creado por una fábrica (myClassA está por encima)

    class myClassC 
    { 
    
        private static $singleton; 
    
        public static function getInstance($par){ 
    
         if(is_null(self::$singleton)){ 
    
          self::$singleton = new myClassA($par); 
    
         } 
    
         return self::$singleton; 
    
        } 
    
    } 
    
    $g = myClassC::getInstance("gino"); 
    echo "got G\n"; 
    
    $p = myClassC::getInstance("pino"); 
    echo "got P\n"; 
    

El uso de la fábrica (getInstance) la primera vez que se construye un nuevo objeto que tiene $ par conjunto de gino.

Usando la fábrica la segunda vez $ singleton ya tiene un valor que le devolvemos. No se crea ningún objeto nuevo (no se llama a __construct, se utiliza menos memoria & cpu).

El valor, por supuesto, es un objeto instanceOf myClassA y no se olvide: la atención

myClassC::$singleton->lv == "gino"

atención a embarazos únicos:

What is so bad about singletons?

http://www.youtube.com/watch?v=-FRm3VPhseI

Por mi ans wer no quiero promover/degradar singleton. Simplemente de las palabras en la pregunta, hice esto calc:

"static" + "__ construct" = "singleton"!

+0

deberías haber agregado un descargo de responsabilidad con respecto a las clases de singletons y táticas: http://stackoverflow.com/questions/137975/what-is-so-bad -about-singletons y http://www.youtube.com/watch?v=-FRm3VPhseI –

+0

solo para aclarar $ g = myClassC :: getInstance ("gino"); y luego $ p = myClassC :: getInstance ("pino"); , $ g-> lv y $ p-> lv son los mismos valores = "gino". ¡no gine y pino, porque el constructor solo se ejecuta una vez! – Miguel

1

Aquí es mi solución:

puse método construct() en la clase estática. Aviso, es diferente de __construct() que utilizo en clases regulares.

Cada clase está en un archivo propio, por lo que lazy cargar ese archivo en el primer uso de la clase.Esto me da el evento del primer uso de la clase.

spl_autoload_register(function($class) { 

    include_once './' . $class . '.php'; 

    if (method_exists($class, 'construct')) { 
     $class::construct(); 
    } 
}); 
Cuestiones relacionadas