Q: Preventing class data inheritance I have a database abstraction layer that starts with a base class like so:
class DB {
  function DB() {
    $this->host = "xxx";
    $this->db = "xxx";
    $this->user = "xx";
    $this->pass = "xx";
    $this->dbh = mysql_connect($this->host, $this->user, $this->pass);
    mysql_select_db($this->db);
    // etc
  }
}

class DBI extends DB {
  // etc
}

Now I would like for the child classes to inherit the database handle but not the credentials. I tried (in the DBI class):
    function DBI (){ 
        $this->host ='';
        $this->db ='';
        $this->user ='';
        $this->pass ='';
    }

But that kills the handle; not sure why.  Also tried:
class DBI extends DB {
    var $host ='';
    var $db ='';
    var $user ='';
    var $pass ='';
}

to no effect.
So I am wondering if what I ought to do is just move the database connection out of the class altoghether?  Just start the class file with a connection and leave it at that?
Opinions?

A: Then don't make them member variables
<?php
class DB
{
  var $dbh;

  function DB()
  {
    $this->dbh = mysql_connect( "xxx", "xxx", "xx" );
    mysql_select_db( "xx", $this->dbh );
    // etc
  }
}

class DBI extends DB {
  // etc
}

or switch to PHP5 and make them private
<?php
class DB
{
  private
      $host = "xxx"
    , $db   = "xxx"
    , $user = "xx"
    , $pass = "xx"
  ;

  protected $dbh;

  public function __construct()
  {
    $this->dbh = mysql_connect($this->host, $this->user, $this->pass);
    mysql_select_db( $this->db, $this->dbh );
    // etc
  }
}

class DBI extends DB {
  // etc
}

and I should not that you need to remember you pass your connection handle to functions like mysql_select_db() to stay multi-connection safe.
EDIT!

But that kills the handle; not sure why.

Because PHP doesn't cascade constructors (the parent class' constructor isn't implicitly called).  That means DB::DB() isn't automatically called when you create an instance of DBI. So you have to do that explicitly.  So I guess this is another option but I don't really like it
class DBI extends DB
{
  function DBI()
  {
    // Call the parent constructor
    parent::DB();

    // Now empty these member variables
    $this->host = '';
    $this->db   = '';
    $this->user = '';
    $this->pass = '';
  }
}


A: Why not pass the database settings in via the constructor:
function DB($host, $db, $user, $pass) {
    $this->host = $host;
    $this->db = $db;
    $this->user = $user;
    $this->pass = $pass;
    $this->dbh = mysql_connect($this->host, $this->user, $this->pass);
    mysql_select_db($this->db);
}

Then you can do
function DBI() {
    parent::DB('xxx', 'xxx', 'xxx', 'xxx');
}

(In both PHP4 and PHP5, the parent constructor will not be called implicitly. This is why your handle is "killed" in your DBI subclass; it never gets initialized. What you really need is to switch to PHP5, though :)

A: If you don't want a child class to inherit a property, you can declare it as private.  This only works for PHP 5:
class DB {

  private $host = "xxx";
  private $db = "xxx";
  private $user = "xx";
  private $pass = "xx";

  function DB() {
    $this->dbh = mysql_connect($this->host, $this->user, $this->pass);
    mysql_select_db($this->db);
    // etc
  }
}

However, I wouldn't recommend this approach.  Database settings are better off stored in a configuration file.  In this way, it's easier to re-use your code between applications.
It's still very common to make a configuration variable be an array inside a file named config.php, and then use that array as a global in functions that require it.  However, it's also a good idea to stay away from globals when possible.  There are some good designs of how to manage a configuration class out there, for instance Zend_Config.  You can get some good ideas from how they've done it.

A: In the end the simplest approach is just to move the connection out of the classes. If I start off the class file with the connection then the handle is available to all the classes without making $dbh a class attribute.
