防止类数据继承

时间:2009-09-03 16:30:41

标签: php oop class class-design

我有一个数据库抽象层,它以一个基类开头,如下所示:

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
}

现在我希望子类继承数据库句柄而不是凭据。我试过(在DBI课上):

    function DBI (){ 
        $this->host ='';
        $this->db ='';
        $this->user ='';
        $this->pass ='';
    }

但这会杀死手柄;不知道为什么。还尝试过:

class DBI extends DB {
    var $host ='';
    var $db ='';
    var $user ='';
    var $pass ='';
}

无效。

所以我想知道我应该做的只是将数据库连接移出类altoghether?只需使用连接启动类文件并将其保留在那个?

评论

4 个答案:

答案 0 :(得分:3)

然后不要将它们作为成员变量

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

或切换到PHP5并将其设为私有

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

我不应该记住你将连接句柄传递给像mysql_select_db()这样的函数来保持多连接安全。

EDIT!

  

但这会杀死手柄;不知道为什么。

因为PHP不会级联构造函数(不会隐式调用父类的构造函数)。这意味着当您创建DB::DB()的实例时,不会自动调用DBI。所以你必须明确地这样做。所以我想这是另一种选择,但我真的不喜欢它

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 = '';
  }
}

答案 1 :(得分:2)

为什么不通过构造函数传递数据库设置:

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

然后你可以做

function DBI() {
    parent::DB('xxx', 'xxx', 'xxx', 'xxx');
}

(在PHP4和PHP5中,父构造函数都不会被隐式调用。这就是你的DBI子类中的句柄被“杀死”的原因;它永远不会被初始化。你的真正需要切换到PHP5,但是:)

答案 2 :(得分:1)

如果您不希望子类继承属性,则可以将其声明为私有。这仅适用于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
  }
}

但是,我不推荐这种方法。数据库设置最好存储在配置文件中。通过这种方式,可以更轻松地在应用程序之间重用代码。

将配置变量设置为名为config.php的文件中的数组仍然很常见,然后将该数组用作需要它的函数中的全局数组。但是,在可能的情况下远离全局变量也是一个好主意。有一些关于如何管理配置类的好设计,例如Zend_Config。你可以从他们如何做到这一点得到一些好的想法。

答案 3 :(得分:0)

最后,最简单的方法就是将连接移出类。如果我使用连接启动类文件,则句柄可用于所有类,而不会使$ dbh成为类属性。