【问题标题】:PHP Keep parent class properties when using a child class constructorPHP在使用子类构造函数时保留父类属性
【发布时间】:2016-01-08 14:16:27
【问题描述】:

我有一个父类Database 如下

class Database{

    /** @var Object Filemaker object across the application*/
    protected $fm = null;
    public function __construct(){

        if($this->fm == null){
            $this->_openConnection();
        }
    }

    /**
     * Function to open connection to FileMaker
     * @return null
     */
    private function _openConnection(){
        $this->fm = new FileMaker();
    }
}

我的一个孩子班是

class Login extends Database{

    public function validate(){
        // $this->fm is accessed here with no constructors
        print_r($this->fm);
    }
}

我正在创建对象,

$login = new Login();
$login->validate();

请注意,在这个 Login 类中,我没有任何构造函数。所以在$login = new Login(); 行,它调用了Database 类的构造函数并调用了_openConnection()。这很好

这是我的另一个子类:

class PouleManipulation extends Database{
    private $year;
    public function __construct(){
        // $this->fm is only accessed if I call parent class constructor
        parent::__construct(); 
        $year = '2015';
    }

    public function processQueue(){
        $this->fm->perform();
    }
}

$pm = new PouleManipulation();
$pm->processQueue();

现在,当我调用$pm = new PouleManipulation(); 时,请注意我有一个此类的构造函数。如果我访问$this->fm,那么它会抛出一个未定义的错误。我google了一下,发现

在这个类构造函数中,我需要使用parent::__construct(); 来访问父类属性。如果我没有使用parent::__construct();,那么当您在子类中有构造函数时,父类对象将无法访问

现在,问题在于数据库类 $fm 为空,它再次调用 _openConnection()。我总共有 10 个扩展数据库类的类,以及具有它调用 _openConnection() 的构造函数的任何类。

我需要在所有子类中访问 $this->fm,第一次只调用一次 _openConnection(),并且在所有类中都需要 $this->fm。你是怎么做到的?

【问题讨论】:

  • 不会让 fm 静态帮助?
  • Login 不是 a Database。它没有业务extending它。了解依赖注入。实例化一个Database 一次,并将其传递给所有需要数据库连接的类。
  • @deceze 你能简单解释一下吗?并且这里的可见性没有问题。我在Login 类中还有更多方法
  • @deceze 那么我想我不明白这个问题。然而,告诉某人“学习依赖注入”并不能解决问题(我同意你的观点)。
  • @ash 我想了解这个问题并知道如何克服这个问题。 “学习依赖注入”并不能解决问题

标签: php class oop object


【解决方案1】:

让我们澄清一下。这些属性是在对象级别上设置的。这意味着每次您实例化一个创建对象的类时,该对象都是新的,并且具有与您实例化的其他对象不同的属性(它们可能具有相同的值,但它们存储在不同的位置并且它们是独立的)。

例子:

class Database {
    public $fm = "Value";
}

class Login extends Database {}

class PouleManipulation extends Database {}


$a = new Login();
$b = new PouleManipulation();
$b->fm = "New Value";
echo $a->fm; // prints "Value"
echo $b->fm; // prints "New Value"

您要查找的是在类级别设置的静态属性。如果您通过静态方法访问它会更好。这是一个快速而肮脏的示例,但您最好使用 getter 和 setter。

class Database {
    public static $fm = "Value";
}

class Login extends Database {}

class PouleManipulation extends Database {}

$a = new Login();
$b = new PouleManipulation();
$b::$fm = "New Value";
echo $a::$fm; // prints "New Value"
echo $b::$fm; // prints "New Value"

编辑: 我使用您提供的代码来解释如何实现您想要的,但我想强调 Ryan Vincent 在评论中写的内容:Login 类应该使用(而不是扩展)Database

【讨论】:

  • 阿盖$b::$fm = "New Value";。为什么?
  • 这是一个例子,说明如果你要在父类中使用静态属性,它在继承自同一个父类的类的所有对象中是唯一的。
猜你喜欢
  • 2019-05-21
  • 2021-11-16
  • 1970-01-01
  • 1970-01-01
  • 2018-02-28
  • 2014-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多