Domanda

Ho 2 classi, principale ed esteso. Ho bisogno di utilizzare Vars principali nella classe estesa.

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

$main = new Main;

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

class Extended extends Main { }

$other = new Extended;

var_dump($other->vars);

?>

A chi posso farlo?

Non valida per esempio:

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

Ho bisogno di qualche soluzione più trasparente ed efficiente:)

È stato utile?

Soluzione

Modifica : Questo può essere risolto molto meglio con Inversion of Control (IOC) e Dependency Injection (DI). Se si utilizza il proprio quadro o uno senza Dependency Injection Container League / contenitore

Risposta in basso a sinistra come la storia di risposte sciocche.


Il modo corretto immagino.

<?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";

Altri suggerimenti

Sarebbe facilmente possibile con un costruttore semplice

<?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

?>

Mi rendo conto che è super-vecchio, ma nel caso qualcuno altro ha bisogno un indizio ...

Hai pensato di usare le variabili statiche?

Il modello di progettazione OOP di PHP è tale che ha dichiarato staticamente variabili in un genitori di classe rimangono gli stessi nel bambino di classe, anche.

Per esempio ...

<?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();
?>

L'esecuzione di questo codice (su PHP 5.3- Sono sicuro che sia lo stesso per le altre versioni, anche) vi darà il seguente risultato:

Test è: un

Da quello che ho potuto raccogliere nel vostro OP, siete alla ricerca di un modo per variabili di classe genitore per rimanere - anche nelle classi estese. Questo risolve questo problema.

Per chiamare le variabili pubblicamente al di fuori del campo di applicazione della classe (cioè dove che normalmente si scrive $ obj-> vars ), avresti bisogno di creare una funzione nella classe padre che fa riferimento self::$variable_name in modo che possa gettare quella variabile torna al codice che utilizza sia quella classe, o di qualsiasi altra classe che la estende.

Per esempio, qualcosa come:

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

Si potrebbe anche creare un metodo magica che avrebbe dinamicamente gettare di nuovo la variabile self :: $ in base a quello che si chiede l'istanza per - vale a dire un metodo o una variabile. Si potrebbe collegare il codice di gettare di nuovo il self :: $ variabile pari in ogni caso.

http://php.net/manual/en/language. oop5.magic.php per ulteriori informazioni sui vari metodi di magia che ti permettono di fare questo genere di cose.

Il PO è stato un po 'criptico, quindi non era sicuro se questo è esattamente quello che volevi, ma non ho visto nessuno altro qui riferimento a variabili statiche così ho pensato di carillon - speriamo vi sia utile

Credo che bisogna essere più chiari su ciò che si desidera. Immaginate che avete dovuto diverse istanze di sia principale che estesa. Dovrebbero tutte riferimento agli stessi dati, in modo che se si modificano i dati in uno qualsiasi di loro, sono tutti colpiti?

Se è così, allora un approccio è quello di utilizzare una variabile statica, che è legato alla classe anziché l'istanza individuale. Un altro è quello di creare un oggetto separato (di una classe diversa) per memorizzare i dati, e passarlo al principale e le classi estese quando vengono creati. Potevano ogni memorizzare un riferimento ad esso, per esempio:.

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);

Se no, allora si desidera copie dei dati, piuttosto che i riferimenti agli stessi dati. In tal caso, il secondo esempio è più vicino, anche se non mi basta copiare ciecamente tutti i membri.

oooooooooooooooooooooooooooooooooooooooooooooooooooooh

si desidera che questo:

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:

Inoltre, si può fare questo:

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");
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top