【问题标题】:How to pass multiple variables from parent class to child class functions automatically using extract();?如何使用 extract(); 自动将多个变量从父类传递给子类函数?
【发布时间】:2017-01-10 17:18:43
【问题描述】:

我不确定如何准确编码,但我肯定可以说得比我的代码显示的更好。

我想 extract(); 父类中的 vars 并让这些 vars 自动可用于子类中的函数。

目前,我必须调用 extract();每个子类函数中的函数以使变量可用。这就是我想要减少的,extract();每次只在子班内调用一次。

我还是 __construct(); 的新手。方法,因为我刚开始只是静态调用函数。但是我试图研究并理解这一点,但我只在网上找到了展示如何将 SINGLE vars 从 __construct(); 传递给其他函数的文章。我没有找到任何关于如何一次传递多个变量的文章。具体使用 extract();。

这个可以吗?

我的最终目标只是减少子类中每个 var 的“parent::”的编写。因此,当需要时,我可以提取变量并简单地编写 $var 而不是 parent::$var

// ----------------------------------------------------------------------------------------------------
// Concept One
// ----------------------------------------------------------------------------------------------------

class Parent_Vars {

    public static function get_vars() {

        $vars = array(
            'var_1' => 'var_1',
            'var_2' => 'var_2',
            'var_3' => 'var_3',
        );
        return $vars;

    }

}

class Parent_Vars extends class Child_Vars {

    public static $instance;

    static function getInstance() {
        if (!self::$instance) {
            self::$instance = new self;
        }
        return self::$instance;
    }

    public function __construct() {
        parent::get_vars();
    }

    // This method DOES NOT work

    public static function echo_var_method_1() {

        //extract(parent::get_vars()); If I uncomment this, my vars below will work
        // But I don't want to call extract(parent::get_vars()); for every function I need. 
        //  I would like the vars to already be available from the __construct();
        echo $var_1; // returns error = undefined var
        echo $var_2; // returns error = undefined var
        echo $var_3; // returns error = undefined var
        echo parent::$var_1; // Works, but I'm trying to reduce writing parent:: everytime
        echo parent::$var_2; // Works, but I'm trying to reduce writing parent:: everytime
        echo parent::$var_3; // Works, but I'm trying to reduce writing parent:: everytime

    }

    // This method DOES work

    public static function echo_var_method_2() {

        extract(parent::get_vars()); // I'm trying NOT to call the var extract for each function, but for the whole class at once
        echo $var_1; // echoes "var_1" !! No need to write parent:: everytime for the vars
        echo $var_2; // echoes "var_2" !! No need to write parent:: everytime for the vars
        echo $var_3; // echoes "var_3" !! No need to write parent:: everytime for the vars

    }

}

$object = new Child_Vars();
Child_Vars::echo_var_method_1();
Child_Vars::echo_var_method_2();

// ----------------------------------------------------------------------------------------------------
// Concept Two - just slightly different with the parent class having its own __construct(); and the child __construct(); calling the parent __construct();
// ----------------------------------------------------------------------------------------------------

class Parent_Vars {

    public function __construct() {
        extract(self::get_vars());
    }

    public static function get_vars() {

        $vars = array(
            'var_1' => 'var_1',
            'var_2' => 'var_2',
            'var_3' => 'var_3',
        );
        return $vars;

    }

}

class Parent_Vars extends class Child_Vars {

    public static $instance;

    static function getInstance() {
        if (!self::$instance) {
            self::$instance = new self;
        }
        return self::$instance;
    }

    public function __construct() {
        parent::__construct();
    }

    // This method DOES NOT work

    public static function echo_var_method_1() {

        //extract(parent::get_vars()); If I uncomment this, my vars below will work
        // But I don't want to call extract(parent::get_vars()); for every function I need. 
        //  I would like the vars to already be available from the __construct();
        echo $var_1; // returns error = undefined var
        echo $var_2; // returns error = undefined var
        echo $var_3; // returns error = undefined var
        echo parent::$var_1; // Works, but I'm trying to reduce writing parent:: everytime
        echo parent::$var_2; // Works, but I'm trying to reduce writing parent:: everytime
        echo parent::$var_3; // Works, but I'm trying to reduce writing parent:: everytime

    }

    // This method DOES work

    public static function echo_var_method_2() {

        extract(parent::get_vars()); // I'm trying NOT to call the var extract for each function, but for the whole class at once
        echo $var_1; // echoes "var_1" !! No need to write parent:: everytime for the vars
        echo $var_2; // echoes "var_2" !! No need to write parent:: everytime for the vars
        echo $var_3; // echoes "var_3" !! No need to write parent:: everytime for the vars

    }

}

$object = new Child_Vars();
Child_Vars::echo_var_method_1();
Child_Vars::echo_var_method_2();

【问题讨论】:

  • 我不太确定您要完成什么,但我的第一印象是,这确实是非常糟糕的 OO 实践(事实上,随着 static 关键字出现在任何地方,它可能根本不是 OO!静态方法是试图将非 OO 思维应用于 OO 模型的代码味道)。如果您在超类中声明一个变量,那么它在子类中自动可用(除非您将其声明为私有)。没有必要缺少提取物,绝对不推荐。
  • 我应该补充一点,我不想让这些全局变量随处可用,而只是在需要时可供子类及其函数使用。我希望这是有道理的。我不确定 PHP 是如何收集变量的,但根据我的理解,每次调用 extract(); php 将提取所有这些变量。当提取中只能使用几个变量时,我不想这样做。所以我想尽可能减少调用提取,这就是为什么我想在需要时为整个班级调用一次。希望这是有道理的。 - 哦好的。刚看到你的回复。 @戈登M
  • 对于 OO 静态关键字它是。我明白,正如我所说,我开始只静态调用函数,因为我还没有完全理解 obj 逻辑。但我知道构造可以在实例创建时自动使某些东西可用,所以这是我尝试构造的逻辑。但最终我只希望我提取的变量可用于我的子类函数。
  • 为什么不创建一个__get 方法来查找数组,而不是将它们提取到变量中?
  • @Barmar 很好,我可以打电话给parent::,这就是我已经在做的事情。我所有的变量都已经作为 public static $var;但我试图找到一种方法将所有这些变量拉到另一个类中,而不必编写 parent::$var。只是因为我注意到 parent::$var 变得非常重复。这可能不是什么大问题,但我有这个想法并想深入研究它,特别是因为我没有找到关于这个概念的文章,但也许​​这就是为什么,哈哈。

标签: php class oop variables global-variables


【解决方案1】:

extract 在与 OO 一起使用时非常狡猾。运行 foreach 并分配 $this->$key = $value 会更明智(并且执行时间更快)(因为无论如何它们都是动态的,您也可以使用魔术函数来创建 getter 和 setter)。如果您坚持使用 extract,您应该在 php 手册的同一 extract() 页面上看到“FredLawl”发表的评论。

更新:

class MyClass
{
    public function __construct($data)
    {
        foreach($data as $key => $value){
            $this->$key = $value
        }
    }
}

class MyClass2 extends MyClass
{
    public function __get($name) {
        return $this->$name;
    }
}

$instance = new MyClass2($variableArray);

$xtractedVar = $instance->variableKey;

您可以使用这个基本原则来尝试并制定出您需要的解决方案。

【讨论】:

  • 好的。好吧,如果这是不可取的,那么我不想这样做,也不想学习如何去做,那样。我还在学习,所以这只是我所拥有的知识的想法。你能给我一个你想要尝试的代码示例吗?更快的执行也是我想要的,并且试图减少我注意到的代码变得重复。现在我将每个 $var 称为 parent::$var,我试图只编写 $var,但也可以在需要时通过一次调用使所有这些 $var 对类可用。理论上调用 parent::$var 会更快吗?
【解决方案2】:

我认为您对 OO 的理解不是很好,并且正在尝试应用一种非 OO 的思维方式。 PHP(以及大多数其他基于类的 OO 语言)中的对象是数据的集合和操作该数据的相关方法的集合。当您创建给定类的子类时,您创建了一种新类型的对象,它扩展了变量集合和适用方法的集合。

您似乎也不太了解类变量(所有类共有)和实例变量(其值对于给定类的实例唯一的变量)之间的区别。

对于实例变量,任何非私有变量都可以通过 $this 自动提供给子类。

class SuperClass {
    protected $var = "";
    public function showVar ()
    {
        echo $this -> var . PHP_EOL;
    }

    public function setVal ($newVal)
    {
        $this -> var = $newVal;
    }
}

class SubClass extends SuperClass {
    public function showVarInString ()
    {
        echo "Hello, I'm a subclass with value " . $this -> var;
    }
}

$a = new SuperClass ();
$b = new SubClass ();
$a -> setVal (1);
$b -> setVal (4);
$a -> showVar (); // "1"
$b -> showVar (); // "4"
$b -> showVarInString (); // "Hello, I'm a subclass with value 4"

类变量,又名静态变量,对一个类的所有实例都是通用的,并且可以使用 static:: 而不是 $this 访问

class SuperClass
{
    protected static $var = 1234;
}

class SubClass extends SuperClass
{
    public function showVar ()
    {
        echo static::$var . PHP_EOL;
    }
}

【讨论】:

  • 好的。我提到了非 OO 技能集,因为我只使用类来保护函数并使用更通用的函数名称,并将某些类元素扩展到子类。我没有使用 __construct() 因为我还不明白。我已经看了好几遍了,但我还不明白,我也看不出它的目的。
  • 我不能按原样使用 $this,因为我总是收到错误...在不在对象上下文中使用 $this...我会坚持我当时正在做的事情稍后再次查看 OOP。我的变量也必须是公开的,否则它们会出错,所以我明白这一点。我正在尝试编写一些与我实际想要实现的目标更相关的代码。
猜你喜欢
  • 2013-07-08
  • 2020-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-16
  • 2015-07-23
  • 2017-04-15
相关资源
最近更新 更多