2008-12-25 10 views
6

Ich habe 2 Klassen, Haupt- und erweitert. Ich muss Hauptvars in der erweiterten Klasse verwenden.Verwenden Eltern Variablen in einer erweiterten Klasse in 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); 

?> 

Wer kann ich es tun?

Keine gültige zum Beispiel:

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

ich eine Lösung transparenter und effizienter brauchen :)

+0

ich nicht bekommen, ist es leicht möglich sein. Ich wäre mehr als glücklich, Ihre Frage zu beantworten, aber es ist nicht klar genug. Möchten Sie "erweitert" wie ($ obj = new Extended ($ main)) konstruieren oder suchen Sie statische Vars? – nlaq

Antwort

4

EDIT: Dieses viel besser mit Inversion of Control gelöst werden können (IOK) und Abhängigkeitsinjektion (DI). Wenn Sie Ihr eigenes Framework verwenden oder eines ohne Dependency Injection Container versuchen Sie League/Container

Antwort unten links als Geschichte der törichte Antworten.


Der richtige Weg, den ich sehe.

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

Ich wünschte, der Typ, der PHP nicht kennt und mich modifiziert, würde erklären, warum. – OIS

+0

Ich gehe nicht nach downmod, aber es fehlt Ihnen wirklich im OOP-Designbereich. Sie sollten NIE Config-Klassen erweitern - Config-Objekte sollten in den Objekten enthalten sein, die sie konsumieren - nicht in andere Klassen erweitert. Entschuldigung, aber das ist einfach dumm. – nlaq

+0

Ich mache das nicht, aber das ist was der Typ will. Es begann nicht als Config-Klasse, aber das ist, was es sich herausstellte ... – OIS

1

Ich denke, Sie müssen klarer sein, was Sie wollen. Stellen Sie sich vor, Sie hätten mehrere Instanzen von Main und Extended. Sollten sie alle auf dieselben Daten verweisen, so dass, wenn Sie die Daten in einem von ihnen ändern, sie alle betroffen sind?

Wenn dies der Fall ist, besteht ein Ansatz darin, eine statische Variable zu verwenden, die an die Klasse und nicht an die einzelne Instanz gebunden ist. Eine weitere Möglichkeit besteht darin, ein separates Objekt (einer anderen Klasse) zu erstellen, um Ihre Daten zu speichern und bei der Erstellung an die Klassen Main und Extended zu übergeben. Sie können jeweils speichern einen Verweis darauf, z.B .:

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

Wenn nicht, dann mögen Sie Kopien der Daten, sondern als Verweis auf die gleichen Daten. In diesem Fall ist Ihr zweites Beispiel näher, obwohl ich nicht blind alle Mitglieder kopieren würde.

0

oooooooooooooooooooooooooooooooooooooooooooooooooooooh

Sie wollen dies:

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:

auch, Sie können dies tun:

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

Ich weiß, das ist super-alt, aber falls irgendjemand sonst eine Ahnung braucht ...

Haben Sie überlegt, statische Variablen zu verwenden?

Das PHP-OOP-Entwurfsmuster ist so, dass statisch Variablen in einer Klasse Mutter erklärt bleiben gleich in der Kind Klasse auch.

Zum Beispiel ...

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

Ausführen dieses Code (auf PHP 5.3- Ich bin sicher, dass es auch für andere Versionen ist auch) geben Sie das folgende Ergebnis:

-Test ist: ein

Von was ich in Ihrem OP sammeln konnte, suchen Sie nach einer Möglichkeit für die Elternklasse Variablen bleiben - auch in erweiterten Klassen. Dies löst dieses Problem.

Um die Variablen öffentlich außerhalb des Klassenbereiches zu nennen (also dort, wo werden Sie normalerweise schreiben obj- $> Vars), müssen Sie eine Funktion in der übergeordneten Klasse erstellen, die self::$variable_name so dass es Referenzen kann Werfen Sie diese Variable zurück auf den Code, der entweder diese Klasse oder eine andere Klasse verwendet, die sie erweitert.

Zum Beispiel so etwas wie:

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

Sie könnten auch eine magische Methode erstellen, die self :: $ Variable dynamisch zurückwerfen würde auf, was Sie fragen die Instanz für - also ein Verfahren oder eine Variable . Sie könnten den Code verdrahten, um die self :: $ Variable in jedem Fall zurück zu werfen.

Lesen Sie http://php.net/manual/en/language.oop5.magic.php für weitere Informationen über die verschiedenen magischen Methoden, mit denen Sie diese Art von Sachen machen können.

Das OP war ein wenig kryptisch, also war ich mir nicht sicher, ob das genau das ist, was du wolltest, aber ich habe niemanden gesehen, der hier statische Variablen anspricht.

+0

Interessant. Was passiert aber, wenn Sie in der Methode __construct() $ test deklarieren und zuweisen? Ich frage das, weil Sie nicht öffentlich statisch $ this-> test machen können; – sqram

6

Es wäre mit einem einfachen Konstruktor

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

?> 
Verwandte Themen