Jump to content

Passing a DB object to other objects


MelodyMaker

Recommended Posts

Hi, I've just got into PHP Object-Oriented programming, and I wold like to ask to you the following question (I think, to many of you this is maybe a very stupid one):

 

I have two classes:

 

A Database class and a SessionManager class. So the question is quite simple: what is the best way to pass to SessionManager a DB instance?

 

-passing it to the SessionManager constructor?

$session = new SessionManager(Database::getInstance());

 

 

-passing it to a SessionManager method?

$session = new SessionManager();

$DB = Database::getInstance() (suppose I use Singleton pattern)

$session->loadDB($DB)

 

or putting it directly INSIDE the SessionManager Object, maybe in its constructor:

 

Class SessionManager{

private $DB;

function __construct(){

$this->DB = Database::getInstance();

}

} ...

 

The questions comes from the fact that there will be many objects in my project and lots of them will use the DB object. I really don't know if there's a "best" solution. Maybe you can help.

 

Thanks in advance.

 

Davide

Link to comment
Share on other sites

Thank you very much. Could you tell me please if the following one could be a correct solution:

 

 

abstract class Database{ 
abstract protected function DBQuery($query,$line="",$file=""); 
abstract protected function DBfetchArray($mode=""); 
abstract static protected function DBgetInstance(); 
... 

} 

class mysqliDB extends Database{ 
private function __construct()... //this should be a singleton 
static public DBgetInstance()  ... //this returns only an Instance of this object 
public function DBQuery ... 
public function DBFetchArray ... 

} 

class SessionManager{ //or any other object that neeeds a DB connection 
public function loadDB (Database $db){ //type hint 
.... 
} 
} 

$session = new SessionManager(); 
$session->loadDB(mysqliDB::getInstance()); 
//and so on for any other objects that need a DB 

 

Could this be a correct solution?

Link to comment
Share on other sites

Sure and no :)

 

First off, __construct() can't return any values so it can't be a singleton. Second, I suggest programming to an interface instead of using a base class.

 

My reasoning is here: http://www.javaworld.com/javaworld/jw-08-2003/jw-0801-toolbox.html

 

Following the rules in that guide you end up with something like this:

 

<?php

interface Database {
    public function connect($host, $username, $password, $database); //establishes and selects database
    public function query($query); //queries the database, returns array
    public static function getInstance();
    .
    .
    . etc
}

class mySQLi implements Database {
      private $instance = null; //for singleton
      public function __construct() {}
      public static function getInstance() {
            if ($instance == null) //bla bla
      }

      public function connect($...) {
            mysqli_connect($host, $username, $password) or throw new SQLException("Could not connect to database");
            mysqli_select_db($db, $con);
      }
}


//now, finally, a DAO.

class AlbumDao {
      private $dbconnection;

      public function getImageByName($dir) {
          //find an image in a certain directory;
      }

      public function getImageById($id) {
             //select * from images where id = id
      }
      
      public function initialize($albumName) {
            // select * from album a 
            // inner join images i on i.album = a.id
            // inner join videos v on v.album = a.id
            // where album.short_tile = '$albumName'
      }
      public function setDbConnection(Database $dbconnection) {$this->dbconnection = $dbconnection;}
}

class Album {
    private $name;
    private $title;
    private $dir;

    private $dao;

    public function __construct($name) { 
          $this->name = $name; 
          $this->init();
    }


    private init() {
          $this->dao->initialize($this->name);
    }

    public function getImageList() {
        // some helper functions which return a list of Image objects
    }

    public function getVideoList() {
       // some other helper functions
    }

    public function setDao(AlbumDao $dao) {$this->dao = $dao}

}


//client

$db = new mySQLi::getInstance();
$db->connect(...);

$album = new Album("Family Photos"); 
$a->setDao($db); // make sure it's using our database
$a->init();

foreach($a->getImageList() as $image) // loop through and get some images..


?>

Link to comment
Share on other sites

Yes, you're right. I'm sorry for that, what I was trying to explain is that the constructor is private because I use a singleton pattern to instantiate the object. Sorry, I put a wrong comment there...

 

Anyway, at this point I wonder what are abstract classes useful for. After reading that article about Java and derived classes it seems that abstract classes (and, in general, base classes) should be replaced by interfaces. I'm a bit confused about that...

Link to comment
Share on other sites

Thank to all of you. Let's suppose that it is NOT a Database object that you want to pass across the pages of,say, a website and use in objects, but anything else (for example a Log or Error object).

Is there a way to change only the class (base class) and, of course, his name without changing every instantiation across the script ($newObject = new newObject()...) something like this, I mean:

 

 

interface BaseObject

|

Obj1 OBj2 OBj3 .... (all implement the interface and this objects are interchangeable, I could use Obj1 or Obj2, or Obj3...)

|

Then, a CurrentObject that someway (which?) stores or get the Object I need (Obj1 or Obj2, or Obj3,...)

 

 

 

This way, I can keep the scripts untouched because I instantiate the CurrentObject:

 

$newObject = new CurrentObject() // does not matter if this uses Obj1 or Obj2 or Obj3...

 

I don't know if the question is clear, I hope so.

 

Thanks in advance.

 

Davide

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • 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.