2008-12-25 12 views
6

Tengo 2 clases, principal y extendida. Necesito usar vars principales en clase extendida.Usar variables padre en una clase extendida en PHP

<?php 
class Main { 
    public $vars = array(); 
} 

$main = new Main; 

$main->vars['key'] = 'value'; 

class Extended extends Main { } 

$other = new Extended; 

var_dump($other->vars); 

?> 

¿Quién puedo hacerlo?

No válido por ejemplo:

<?php 
class Extended extends Main { 
    function __construct ($main) { 
    foreach ($main as $k => $v) { 
     $this->$k = $v; 
    } 
    } 
} 
?> 

Necesito un poco de solución más transparente y eficiente :)

+0

Yo no lo entiendo. Estaría más que feliz de responder a su pregunta, pero no es lo suficientemente claro. ¿Desea construir "extendido" como ($ obj = new Extended ($ main)) o está buscando vars estáticos? – nlaq

Respuesta

4

EDITAR: Esto se puede resolver mucho mejor con Inversión de Control (COI) y Dependency Injection (DI). Si utiliza su propio marco o uno sin Dependency Injection Container intente League/Container

Responda a continuación a la izquierda como el historial de respuestas tontas.


La forma correcta que imagino.

<?php 
class Config { 
    protected $_vars = array(); 

    protected static $_instance; 

    private function __construct() {} 

    public static function getInstance() 
    { 
     if (!isset(self::$_instance)) { 
      self::$_instance = new self(); 
     } 
     return self::$_instance; 
    } 

    public function &__get($name) { 
     return $this->_vars[$name]; 
    } 

    public function __set ($name, $value) { 
     $this->_vars[$name] = $value; 
    } 
} 

$config = Config::getInstance(); 
$config->db = array('localhost', 'root', ''); 
$config->templates = array(
    'main' => 'main', 
    'news' => 'news_list' 
); 

class DB { 
    public $db; 

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

    public function connect() 
    { 
     mysql_connect($this->db[0], $this->db[1], $this->db[2]); 
    } 
} 

$config = Config::getInstance(); 
$db = new DB($config->db); 
$db->connect(); 

class Templates { 
    public $templates; 

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

    public function load ($where) { 
     return $this->templates[$where]; 
    } 
} 

$config = Config::getInstance(); 
$templates = new Templates($config->templates); 
echo $templates->load('main') . "\n"; 
+0

Me gustaría que el hombre que no conoce PHP y me modificó explique por qué. – OIS

+0

No voy a downmod pero realmente me falta el área de diseño de OOP. NUNCA debe extender las clases de configuración. Los objetos de configuración deben estar contenidos en los objetos que los consumen, y no deben extenderse a otras clases. Lo siento, pero esto es tonto. – nlaq

+0

Yo no hago eso, pero eso es lo que el chico quiere. No comenzó como una clase de configuración, pero eso es lo que resultó ser ... – OIS

1

Creo que necesita tener más claro lo que quiere. Imagine que tiene varias instancias de Main y Extended. ¿Deberían todos referirse a los mismos datos, de modo que si cambia los datos en alguno de ellos, todos se vean afectados?

Si es así, entonces un enfoque es usar una variable estática, que está vinculada a la clase en lugar de la instancia individual. Otra es crear un objeto separado (de una clase diferente) para almacenar sus datos y pasarlos a las clases principal y extendida cuando se crean. Cada uno de ellos se podrían almacenar una referencia a él, por ejemplo .:

class Main { 
    public $data; 
    function __construct(Data $data) { 
    $this->data = $data; 
    } 
} 
class Extended extends Main {} 

$ourData = new Data(); 
$ourData->vars = array(1,2,3); 

$main = new Main($ourData); 
$other = new Extended($ourData); 

Si no es así, entonces usted quiere copias de los datos, en lugar de referencias a los mismos datos. En ese caso, su segundo ejemplo es más cercano, aunque no solo copiaría ciegamente a todos los miembros.

0

oooooooooooooooooooooooooooooooooooooooooooooooooooooh

desea que esta:

class Config 
{ 
    private $m_vars = array(); 

    function __get($name) 
    { 
     return $this->m_vars[$name]; 
    } 

    function & __set($name, $value) // << the & is important! 
    { 
     $this->m_vars[$name] = $value; 
    } 
} 

class Db 
{ 
    funciton __construct(Config $config) 
    { 
     $this->Connect($config->host, $config->user, $config->pass, $config->db); 
    } 
} 

$config = new Config(); 
$config->host = "localhost"; 
... 
$db = new Db($config); 

:)

EDIT:

También, usted puede hacer esto:

class Templator 
{ 
    private $m_config = null; 
    function __construct($config) 
    { 
     $this->m_config = $config; 
    } 

    function PrintTemplate($name) 
    { 
     echo file_get_contents($this->m_config->template_path . $name); 
    } 

} 

$config->template_path = "./templates/"; 
$temp = new Templator($config); 
$temp->PrintTemplate("index.html"); 
2

Me doy cuenta de que esto es súper antiguo, pero en caso de que alguien más necesite una pista ...

¿Ha considerado usar variables estáticas?

El patrón de diseño PHP programación orientada a objetos es tal que estáticamente por variables en un padre clase permanecer en la misma clase que el niño, también.

Por ejemplo ...

<?php 
class A { 
    public static $test = 'a'; 

    public function test() { 
     echo 'Test is: '.self::$test; 
    } 

} 
class B extends A { 
    public static $test = 'b'; 
} 
$obj = new B; 
$obj->test(); 
?> 

La ejecución de este código (en PHP 5.3- Estoy seguro de que es el mismo para las otras versiones, también) le dará el siguiente resultado:

prueba es: a

Por lo que pude deducir en su OP, está buscando una forma para que variables de clase primaria permanezcan, incluso en clases ampliadas. Esto resuelve ese problema.

Para llamar a las variables públicamente fuera del ámbito de la clase (es decir, el lugar donde quiere escribe normalmente $ obj-> vars), que había necesidad de crear una función en la clase padre que hace referencia a self::$variable_name de modo que pueda arroje esa variable nuevamente al código que utiliza esa clase o cualquier otra clase que la amplíe.

Por ejemplo, algo como:

public function get_variable() { 
    return self::$variable; 
} 

También podría crear un método mágico que echar hacia atrás de forma dinámica la variable self :: $ basado en lo que pide la instancia de - es decir, un método o una variable . Puede cablear el código para devolver el equivalente a self :: $ variable en cualquier caso.

Lea http://php.net/manual/en/language.oop5.magic.php para obtener más información sobre los diversos métodos mágicos que le permiten hacer este tipo de cosas.

El OP era un poco críptico, así que no estaba seguro de si eso era exactamente lo que querías, pero no vi a nadie más referenciando variables estáticas, así que pensé que sonaría - ¡espero que ayude!

+0

Interesante. pero, ¿qué sucede si declaraste y asignaste $ test dentro del método __construct()? Pregunto esto porque no se puede hacer público static $ this-> test; – sqram

6

Sería posible fácilmente con un simple constructor

<?php 

class One { 

    public static $string = "HELLO"; 

} 

class Two extends One { 

    function __construct() 
    { 
     parent::$string = "WORLD"; 
     $this->string = parent::$string; 
    } 

} 

$class = new Two; 
echo $class->string; // WORLD 

?> 
Cuestiones relacionadas