在 PHP 扩展类中使用父变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/393204/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 22:35:57  来源:igfitidea点击:

Using parent variables in a extended class in PHP

phpclassobjectextends

提问by Lito

I have 2 classes, main and extended. I need to use main vars in extended class.

我有两个类,主要和扩展。我需要在扩展类中使用主变量。

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

$main = new Main;

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

class Extended extends Main { }

$other = new Extended;

var_dump($other->vars);

?>

Who I can do it?

我谁能做到?

No valid for example:

无效例如:

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

I need some solution more transparent and efficient :)

我需要一些更透明、更高效的解决方案:)

采纳答案by OIS

EDIT: This can be solved much better with Inversion of Control(IoC) and Dependency Injection(DI). If you use your own framework or one without Dependency Injection Containertry League/Container

编辑:这可以通过控制反转(IoC)和依赖注入(DI)更好地解决。如果您使用自己的框架或没有依赖注入容器的框架,请尝试League/Container

Answer below left as history of foolish answers.

下面的答案左为愚蠢答案的历史。



The correct way I 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";

回答by Chris

It would be easily possible with a 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

?>

回答by Lee Benson

I realize this is super-old, but in case anyone else needs a clue...

我意识到这太旧了,但万一其他人需要线索......

Have you considered using static variables?

您是否考虑过使用静态变量?

The PHP OOP design pattern is such that statically declared variables in a parentclass remain the same in the childclass, too.

PHP的面向对象的设计模式是这样的:在一个静态声明的变量类保持在相同的类,太。

For example...

例如...

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

Running this code (on PHP 5.3- I'm sure it's the same for other versions, too) will give you the following result:

运行此代码(在 PHP 5.3 上 - 我相信其他版本也是如此)将为您提供以下结果:

Test is: a

测试是:

From what I could gather in your OP, you are looking for a way for the parent class variablesto remain - even in extended classes. This solves that problem.

根据我在您的 OP 中收集到的信息,您正在寻找一种保留父类变量的方法 - 即使在扩展类中也是如此。这解决了这个问题。

To call the variables publicly outside of the class scope (i.e. where you'd normally write $obj->vars), you'd need to create a function in the parent class that references self::$variable_nameso that it can throw that variable back to the code that utilizes either that class, or any other class that extends it.

要在类范围之外公开调用变量(即您通常编写$obj->vars 的地方),您需要在父类中创建一个引用的函数,self::$variable_name以便它可以将该变量扔回代码使用该类或扩展它的任何其他类。

For example, something like:

例如,类似于:

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

You could also create a magic method that would dynamically throw back the self::$variable based on what you ask the instance for - i.e. a method or a variable. You could wire the code to throw back the self::$variable equivalent in any case.

您还可以创建一个魔术方法,该方法会根据您要求实例的内容动态返回 self::$ 变量 - 即方法或变量。在任何情况下,您都可以连接代码以返回 self::$variable 等效项。

Read http://php.net/manual/en/language.oop5.magic.phpfor more info on the various magic methods that allow you to do this kind of stuff.

阅读http://php.net/manual/en/language.oop5.magic.php以获取有关允许您执行此类操作的各种魔术方法的更多信息。

The OP was a bit cryptic so I wasn't sure if that's exactly what you wanted, but I didn't see anyone else here reference static variables so thought I'd chime in - hope it helps!

OP 有点神秘,所以我不确定这是否正是你想要的,但我没有看到这里的其他人引用静态变量,所以我想我会插话 - 希望它有所帮助!

回答by JW.

I think you need to be more clear about what you want. Imagine that you had several instances of both Main and Extended. Should they all refer to the same data, so that if you change the data in any one of them, they're all affected?

我认为你需要更清楚你想要什么。假设您有几个 Main 和 Extended 实例。它们是否应该都引用相同的数据,以便如果您更改其中任何一个中的数据,它们都会受到影响?

If so, then one approach is to use a static variable, which is tied to the class rather than the individual instance. Another is to create a separate object (of a different class) to store your data, and pass it to the Main and Extended classes when they're created. They could each store a reference to it, e.g.:

如果是这样,那么一种方法是使用静态变量,该变量与类而非单个实例相关联。另一种方法是创建一个单独的对象(属于不同的类)来存储您的数据,并在创建它们时将其传递给 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);

If not, then you want copies of the data, rather than references to the same data. In that case, your second example is closer, although I wouldn't just blindly copy all members.

如果不是,那么您需要数据的副本,而不是对相同数据的引用。在那种情况下,您的第二个示例更接近,尽管我不会盲目地复制所有成员。

回答by JW.

oooooooooooooooooooooooooooooooooooooooooooooooooooooh

oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo

you want this:

你要这个:

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:

编辑:

also, you can do this:

此外,你可以这样做:

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