如何使用extract()自动将多个变量从父类传递给子类函数?

时间:2017-01-10 17:18:43

标签: php class oop variables global-variables

我不确定如何准确编码,但我可以肯定地说,我相信它比我的代码所表明的更好。

我希望来自父类的extract();变量,并且这些变量可以自动用于子类中的函数。

目前,我必须调用extract();每个子类函数内的函数,以使变量可用。这就是我试图减少的,extract();每次只在儿童班内打电话一次。

我是__construct()的新手;因为我开始时只是静态调用函数。但我试着研究并理解这一点,但我只能在网上找到如何将单个变量传递给__construct();中的其他函数的文章。我找不到任何关于如何一次传递多个变量的文章。特别是使用extract();。

可以这样做吗?

我的最终目标只是减少" parent :: "对于子类中的每个var。因此,在需要时,我可以提取变量,只需编写$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();

2 个答案:

答案 0 :(得分:1)

与OO一起使用时,提取物非常狡猾。运行foreach并分配$ this-> $ key = $ value会更加明智(并且执行时间更快)(因为无论如何它们都是动态的,你也可以使用魔术函数来创建getter和setter)。如果你坚持使用提取,你应该在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;

您可以使用此基本原则来解决并找到所需的解决方案。

答案 1 :(得分:0)

我不认为你非常了解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;
    }
}