【问题标题】:variable returns null after extending class扩展类后变量返回null
【发布时间】:2015-11-06 19:29:44
【问题描述】:

我有一个小问题。我有一个名为 BaseModel 的类。有一个 pdo 连接。现在我有另一个名为 TestModel 的类,并且我扩展了 BaseModel 类。但是当我在 pdo 变量上创建一个 var_dump() 时,它返回 null。我知道问题是因为构造函数,但我该怎么做呢?我需要 TestModel 中的构造函数。但是没有 constcuter 变量返回 null。我已经尝试过parent::__construct(),但页面加载无限。

这是我的课程

基础模型

<?php

namespace App\System\MVC\Models;

class BaseModel
{
  protected $config;
  protected $connection;

  public function __construct($config, $connection)
  {
    $this->config     = $config;
    $this->connection = $connection;
  }

  public function __destruct()
  {
    $this->config     = null;
    $this->connection = null;
  }
}

?>

测试模型

<?php

namespace App\System\MVC\Models;

use App\System\MVC\Models\BaseModel;

class TestModel extends BaseModel
{
  protected $config;
  protected $connection;

  public function __construct()
  {
    var_dump($this->connection);
  }

  public function __destruct()
  {
    $this->config     = null;
    $this->connection = null;
  }
}

?>

请帮助我。 谢谢

抱歉英语不好。

【问题讨论】:

  • 默认情况下不调用父控制器...您必须将参数传递给子类的构造函数并手动调用parent::__construct($config, $connection)
  • 我已经尝试过了,但是页面加载无限

标签: php class oop pdo extends


【解决方案1】:

您永远不会将所需的变量传递给子类实例,因此您无法获得任何其他结果。首先,使用正确的参数调用超级构造函数:

class TestModel extends BaseModel
{
    // no need to redeclare the properties

    public function __construct($config, $connection)
    {
        // pass the variables to __construct() in BaseModel
        parent::__construct($config, $connection);
        // some other initialization
    }

    // no need for destructor since the parent one is called
}

现在你可以像这样使用你的模型了:

$obj = new TestModel($config, $connection);
var_dump($obj->getAllChildren()); // whatever operations that you want

但是每次使用模型时都必须通过$config$connection,这很痛苦,你可以肯定地说。在这种情况下,您可能想要某种factory。你可以做的最简单的应该是这样的:

class ModelFactory
{
    const NS = 'App\System\MVC\Models';
    private $config;
    private $connection;

    public function __construct($config, $connection)
    {
        $this->config = $config;
        $this->connection = $connection;
    }

    public function create($class_name)
    {
        $reflection = new ReflectionClass(self::NS . '\\' . $class_name);
        return $reflection->newInstance($this->config, $this->connection);
    }
}

这将让您只指定一次参数,然后您可以非常轻松地创建任意数量的模型实例:

$factory = new ModelFactory($config, $connection);
$obj1 = $factory->create('UserModel'); // creates new App\System\MVC\Models\UserModel
$obj2 = $factory->create('GroupModel'); // creates new App\System\MVC\Models\GroupModel

这应该会让事情变得更容易一些。请记住,通常模型没有连接,它们只有(元)数据,然后另一个对象负责执行查询。看看repository and data access object patterns

【讨论】:

  • 有没有办法不通过每个模型的配置和连接?我想使用 basemodel 类中的变量
  • 您可以在脚本开头设置的BaseModel 类中包含static propertiesBaseModel::$connection= ???;。然后在模型中使用self::$connection-&gt;query(...); 引用它们。不过,我仍然会推荐 DAO 或存储库模式。
【解决方案2】:

当您实例化子类时,不会自动调用父构造函数,此外,在您的情况下,无法向父构造函数提供其依赖项,因为它们没有提供给子构造函数。

您的类可能应该像这样重新实现:

<?php

namespace App\System\MVC\Models;

class BaseModel
{
  protected $config;
  protected $connection;

  public function __construct($config, $connection)
  {
    $this->config     = $config;
    $this->connection = $connection;
  }

  public function __destruct()
  {
    $this->config     = null;
    $this->connection = null;
  }
}

?>

<?php

namespace App\System\MVC\Models;

use App\System\MVC\Models\BaseModel;

class TestModel extends BaseModel
{
  /* You don't need to redefine them as they are inherited from the parent  
  protected $config;
  protected $connection;
  */

  public function __construct($config, $connection)
  {

    parent::__construct($config, $connection);
    var_dump($this->connection);
  }
  /* This is also inherited from the parent 
  public function __destruct()
  {
    $this->config     = null;
    $this->connection = null;
  }
  */
}

?>

【讨论】:

  • 当我使用 parent::__construct() 页面加载无限
猜你喜欢
  • 1970-01-01
  • 2016-07-14
  • 1970-01-01
  • 2013-10-18
  • 2017-02-24
  • 2015-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多