Jump to content

How to access method object in base class from derived class? Error in my solut


fsarcani-marco

Recommended Posts

I have mysqli object in Database class base:

 

 

class Database {
  private $dbLink = null;
  
  public function __construct() {
    if (is_null($this->dbLink)) {
      // load db information  to connect
      $init_array = parse_ini_file("../init.ini.inc", true);
      $this->dbLink = new mysqli($init_array['database']['host'],
                           $init_array['database']['usr'],
                           $init_array['database']['pwd'],
                           $init_array['database']['db']);
  
      if (mysqli_connect_errno()) {
        $this->dbLink = null;
      }
    }
  }

  public function __destruct() {
    $this->dbLink->close();
  }
}

 

Class derived is Articles where I use object dBLink in base (or parent) class and I can't access to mysqli methods (dbLink member of base class):

 

Articles class:

 

require_once ('./includes/db.inc');

class Articles extends Database{
  private $id,
              ....
              ....
             $visible = null;
  
  public function __construct() {
    // Set date as 2009-07-08 07:35:00
    $this->lastUpdDate = date('Y-m-d H:i:s');
    $this->creationDate = date('Y-m-d H:i:s');
  }
  
  // Setter
  ....
  ....

  // Getter
  ....
  ....

  public function getArticlesByPosition($numArticles) {
    if ($result = $this->dbLink->query('SELECT * FROM articles ORDER BY position LIMIT '.$numArticles)) {
      $i = 0;
      while ($ret = $result->fetch_array(MYSQLI_ASSOC)) {
        $arts[$i] = $ret;
      }
      $result->close();
      return $arts;
    }
  }
}

 

In my front page php I use article class:

 

include_once('./includes/articles.inc');
$articlesObj = new articles();
$articles = $articlesObj->getArticlesByPosition(1);
var_dump($articles);

 

:'(

Notice: Undefined property: Articles::$dbLink in articles.inc  on line 89

 

Fatal error: Call to a member function query() on a non-object in articles.inc on line 89

 

If I remove constructor on derived class Articles result don't change  :'(

Please help me

Link to comment
Share on other sites

Technically the problem is that the parent constructor is not being set:

 

class a {

    public function __construct() {

        echo 'a';

    }

}

 

class b extends a {

    public function __construct() {

        echo 'b';

    }

}

 

new b();

 

will echo out 'b'.

 

You need to call parent::__construct(); to actually call the parent constructor.

 

 

 

On a design note though, you're going about it the wrong way.  You're coupling the database and the article objects quite tightly.  The article object might should have a Database object inside of it, but it should not be a database object if that makes sense.  Or, you could go a different route with it and have a mapper or some other intermediary between the Database object and the Article object (which is what I personally prefer, but it can be a bit painful to do by hand if not using a package of some kind).

 

 

 

Also wrong with your design right now is that every Article object created will have it's own Database object and this Database connection inside of it which is pointless.

 

 

Also, this is just me being picky, but it makes me cringe when I see a declaration for "Articles" and a creation of "articles".  I just wish PHP was case sensitive with everything though, so I'm picky :).

Link to comment
Share on other sites

I thinked that the constructor is always called for base class because if I'm creating a derived object I will create base object and calling construct method after call derived object and call construct of derived object without explict specification of call costructor base object in costructor of derived object. :-\ :(

 

It's very strange how to work php for object oriented programming. Why constructor is called construct if it isn't automatically called in creation derived object constructor ? I do not understand what's the advantage. :confused:

 

For example that I submit I will not use but it was to know how to work php in oo. Don't worry I know pattern to remove tightly coupled object. It was only to test how to work php. ;)

 

I'm using free web hosting in awardspace. I can't use permanent link for free space account.

 

In my first idea was create a session environment connection pooling but it's impossible in awardspace web hosting free because this company for free account don't offer permanent link to mysql or mysqli.

The second idea was create a connection for every session, but this can create an overflow of resource depending of the users number.

The third idea was create a user session connection for every user but is a waste.

The final idea was create a connection link and open and close for every query.

 

If you have some advices to solve the limit of permanent link with an elegant solution, please explain me . :'(

 

Thank you for your reply.

 

Link to comment
Share on other sites

To answer two of your questions:

 

First, the parent constructor is not called because it gives you the ability to override the parent constructor.  This is a big advantage and it would be a disadvantage to always have the parent constructor called.

 

Second, you could use the singleton pattern for the DB object so you only ever have one instance.

Link to comment
Share on other sites

I suggest not having the Database class implement the singleton pattern.  What if you want two database objects to live simultaneously?  Instead, in this case, I would use a registry.

 

Also, I would pass a Database object into an Article object.

 

like $a = new Article($db);

 

Or, a better design (in my opinion) would be to have an middle-man of sorts between the Article and Database class.

 

$am = new ArticleMapper($db);

 

$articles = $am->recentArticles(10); //could return the most recent 10 Article objects

 

That way the database stuff is a bit more abstracted away.

 

You could even have ArticleMapper extend a DbMapper class or something and have the ability to set a default Database object.

 

$db = new Database(...);

 

DbMapper::setDefaultDb($db);

 

$am = new ArticleMapper;

$newArticles = $am->getRecent(10);

 

 

 

 

Then again, it probably would be better to just pass a DB object to Article objects.  Otherwise, you might end up essentially creating a ORM package.  (A mix of Doctrine/Zend_Db_Table is essentially what I was describing in that post after all ;p.)

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.