1

I have a little problem. I have a class named BaseModel. There is a pdo connection. Now i have a other class named TestModel and i extended the BaseModel class. But when i make a var_dump() on the pdo variable it returns null. I know the problem its because the constructer, but how do i make it? i need that constructer in the TestModel. But whitout constcuter the variable returns null. I Already tried whit parent::__construct() but than the page loads infinite.

Here are my classes

BaseModel

<?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;
  }
}

?>

TestModel

<?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;
  }
}

?>

Please help me. Thanks

Sorry for bad english.

Synergy
  • 13
  • 5
  • parent controllers are not called by default... you will have to pass your parameters into the constructor of the child class and manually call `parent::__construct($config, $connection)` – Orangepill Aug 13 '15 at 17:42
  • I already tried that, but then the page loads infinite – Synergy Aug 13 '15 at 17:43

2 Answers2

2

You're never passing in the required variables to the child class instance, so there's no way you'd get any other result. For starters, call the super-constructor with the right arguments:

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
}

Now you can use your model like this:

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

But you have to pass the $config and $connection every time you use a model, and that's a pain as you can surely tell. In cases like this, you may want to have some sort of factory. The simplest one you can make would look like this:

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

This will let you only specify the parameters once, and then you can create as many model instances as you want very easily:

$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

This should make things a bit easier. Just keep in mind that usually the models don't have connections, they only have (meta)data, and then another object takes care of doing the queries. Take a look at the repository and data access object patterns.

Anonymous
  • 11,740
  • 3
  • 40
  • 50
  • Is there a way to no pass the config and connection for every model? i want to use the variables from the basemodel class – Synergy Aug 13 '15 at 17:59
  • You could have [static properties](https://stackoverflow.com/questions/14930046/php-static-property) in the `BaseModel` class that you set at the beginning of your script: `BaseModel::$connection= ???;`. Then reference them with `self::$connection->query(...);` inside the models. I would still recommend DAO or repository patterns though. – Anonymous Aug 13 '15 at 18:14
0

Parent constructors are not automatically called when you instantiate a child class, plus in your case there is no way to supply the parent constructor with it's dependencies as they are not being supplied to the child constructor.

Your Classes should probably be reimplemented like this:

<?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;
  }
  */
}

?>
Orangepill
  • 24,500
  • 3
  • 42
  • 63