fsarcani-marco Posted August 2, 2010 Share Posted August 2, 2010 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 Quote Link to comment https://forums.phpfreaks.com/topic/209539-how-to-access-method-object-in-base-class-from-derived-class-error-in-my-solut/ Share on other sites More sharing options...
corbin Posted August 2, 2010 Share Posted August 2, 2010 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 . Quote Link to comment https://forums.phpfreaks.com/topic/209539-how-to-access-method-object-in-base-class-from-derived-class-error-in-my-solut/#findComment-1093973 Share on other sites More sharing options...
fsarcani-marco Posted August 2, 2010 Author Share Posted August 2, 2010 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. 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. Quote Link to comment https://forums.phpfreaks.com/topic/209539-how-to-access-method-object-in-base-class-from-derived-class-error-in-my-solut/#findComment-1094053 Share on other sites More sharing options...
fsarcani-marco Posted August 2, 2010 Author Share Posted August 2, 2010 A possible solution can be to create a GLOBALS environmet as connection pool and for every access I verify if the connection is not closed? $GLOBALS[' but in my free web host I can't modify php.ini. Quote Link to comment https://forums.phpfreaks.com/topic/209539-how-to-access-method-object-in-base-class-from-derived-class-error-in-my-solut/#findComment-1094058 Share on other sites More sharing options...
AbraCadaver Posted August 2, 2010 Share Posted August 2, 2010 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. Quote Link to comment https://forums.phpfreaks.com/topic/209539-how-to-access-method-object-in-base-class-from-derived-class-error-in-my-solut/#findComment-1094178 Share on other sites More sharing options...
corbin Posted August 3, 2010 Share Posted August 3, 2010 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.) Quote Link to comment https://forums.phpfreaks.com/topic/209539-how-to-access-method-object-in-base-class-from-derived-class-error-in-my-solut/#findComment-1094445 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.