我有2个课程,主要课程和扩展课程。我需要在扩展类中使用主变量。
<?php
class Main {
public $vars = array();
}
$main = new Main;
$main->vars['key'] = 'value';
class Extended extends Main { }
$other = new Extended;
var_dump($other->vars);
?>
我可以做谁?
无效例如:
<?php
class Extended extends Main {
function __construct ($main) {
foreach ($main as $k => $v) {
$this->$k = $v;
}
}
}
?>
我需要一些透明和高效的解决方案:)
答案 0 :(得分:6)
使用简单的构造函数
很容易实现<?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
?>
答案 1 :(得分:4)
编辑:使用控制反转(IoC)和依赖注入(DI)可以更好地解决这个问题。如果您使用自己的框架或没有依赖注入容器的框架,请尝试League/Container
下面的回答是愚蠢答案的历史。
我想的正确方法。
<?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";
答案 2 :(得分:2)
我意识到这是超级老,但万一其他人需要线索......
您是否考虑过使用静态变量?
PHP OOP设计模式是 parent 类中静态声明的变量在子类中保持不变。
例如......
<?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();
?>
运行此代码(在PHP 5.3上 - 我确信它对其他版本也是一样)会给你以下结果:
测试是:a
从我在OP中收集到的内容,您正在寻找一种方法来保留父类变量 - 即使在扩展类中也是如此。这解决了这个问题。
要在类范围之外公开调用变量(即通常编写 $ obj-&gt; vars 的位置),您需要在引用的父类中创建一个函数self::$variable_name
以便它可以将该变量抛回到使用该类的代码或任何其他扩展它的类。
例如:
public function get_variable() {
return self::$variable;
}
您还可以创建一个魔术方法,根据您要求实例的内容(即方法或变量)动态地返回self :: $变量。您可以连接代码以在任何情况下都返回self :: $ variable等效。
阅读http://php.net/manual/en/language.oop5.magic.php,了解有关允许您执行此类操作的各种魔术方法的详细信息。
OP有点神秘,所以我不确定这是不是你想要的,但是我没有看到其他人在这里引用静态变量,所以以为我会参与其中 - 希望它有所帮助!答案 3 :(得分:1)
我认为您需要更清楚自己想要什么。想象一下,你有几个主要和扩展的实例。它们是否应该引用相同的数据,那么如果你改变其中任何一个数据,它们都会受到影响吗?
如果是这样,那么一种方法是使用静态变量,该变量与类而不是单个实例相关联。另一种方法是创建一个单独的对象(不同的类)来存储数据,并在创建时将它传递给Main和Extended类。他们每个人都可以存储对它的引用,例如:
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);
如果没有,那么您需要数据的副本,而不是对相同数据的引用。在这种情况下,你的第二个例子更接近,尽管我不会盲目地复制所有成员。
答案 4 :(得分:0)
oooooooooooooooooooooooooooooooooooooooooooooooooooooh
你想要这个:
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);
:)
编辑:
另外,你可以这样做:
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");