Question

J'ai 2 classes, principale et étendue. Je dois utiliser vars principales dans la classe étendue.

<?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 je peux le faire?

Non valide par exemple:

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

J'ai besoin d'une solution plus transparente et efficace:)

Était-ce utile?

La solution

EDIT : Ceci peut être résolu beaucoup mieux avec Inversion de contrôle (IoC) et Injection de dépendance (DI). Si vous utilisez votre propre cadre ou un sans injection de dépendances Conteneur League / Container

Réponse en bas à gauche l'histoire des réponses folles.


La manière correcte je figure.

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

Autres conseils

Il serait facilement possible avec un simple constructeur

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

?>

Je sais que c'est super vieux, mais au cas où quelqu'un d'autre a besoin d'un indice ...

Avez-vous envisagé d'utiliser des variables statiques?

Le modèle de conception PHP POO est telle que statiquement variables déclarées dans parent classe restent les mêmes dans le enfant classe aussi.

Par exemple ...

<?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'exécution de ce code (sur PHP 5.3- Je suis sûr que c'est la même pour les autres versions, aussi) vous donnera le résultat suivant:

Test est: un

D'après ce que je pouvais rassembler dans votre OP, vous êtes à la recherche d'un moyen pour les variables de classe parent pour rester - même dans les classes prolongées. Cela résout ce problème.

Pour appeler les variables publiquement en dehors de la portée de la classe (là où vous auriez normalement écrire $ obj-> vars ), vous aurez besoin de créer une fonction dans la classe parente qui fait référence self::$variable_name afin qu'il puisse lancer cette variable vers le code qui utilise soit cette classe, ou de toute autre classe qui la prolonge.

Par exemple, quelque chose comme:

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

Vous pouvez également créer une méthode magique qui dynamiquement rejettera l'auto :: $ variable en fonction de ce que vous demandez l'instance pour - à savoir une méthode ou une variable. Vous pouvez câbler le code pour rejeter l'auto :: variable $ équivalent dans tous les cas.

http://php.net/manual/en/language. oop5.magic.php pour plus d'informations sur les différentes méthodes magiques qui vous permettent de faire ce genre de choses.

L'OP était un peu cryptique donc je ne sais pas si c'est exactement ce que tu voulais, mais je ne vois personne d'autre référence ici variables statiques alors pensé que je carillon en - it helps

Je pense que vous devez être plus clair sur ce que vous voulez. Imaginez que vous avez eu plusieurs cas à la fois principal et étendu. Si tous se référer aux mêmes données, de sorte que si vous modifiez les données dans l'un d'eux, ils sont tous touchés?

Si oui, une approche consiste à utiliser une variable statique, qui est liée à la classe plutôt que l'instance individuelle. Une autre est de créer un objet distinct (d'une autre classe) pour stocker vos données, et le transmettre à la Main et des classes étendues lors de leur création. Ils pourraient stocker chacun une référence à elle, par exemple:.

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

Dans le cas contraire, vous souhaitez obtenir une copie des données, plutôt que des références aux mêmes données. Dans ce cas, votre deuxième exemple est plus proche, bien que je ne serais pas copier aveuglément tous simplement membres.

oooooooooooooooooooooooooooooooooooooooooooooooooooooh

vous voulez ceci:

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:

Vous pouvez également faire ceci:

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");
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top