PHP中的数据库和OOP实践

PHP中的数据库和OOP实践,php,database,oop,Php,Database,Oop,很难解释这种情况,但请参见示例 我已经编写了一个网页加载,我初始化一个数据库类的网站。我将这个类作为函数参数发送给任何需要访问数据库的函数 我知道这是一个糟糕的方法,但目前我还不知道如何用其他方法做到这一点。你能帮帮我吗 范例 class sms { function log_sms($message, $db) { $sql = "INSERT INTO `smslog` SET `mesasge` = '$message'

很难解释这种情况,但请参见示例

我已经编写了一个网页加载,我初始化一个数据库类的网站。我将这个类作为函数参数发送给任何需要访问数据库的函数

我知道这是一个糟糕的方法,但目前我还不知道如何用其他方法做到这一点。你能帮帮我吗

范例

class sms {

    function log_sms($message, $db) {

        $sql = "INSERT INTO `smslog` SET
            `mesasge` = '$message'
            ";
        $db->query($sql);

        if ($db->result)
            return true;
        return false;
    }

}
然后在主页上

$db = new db(username,pass,localhost,dbname);

$sms = new sms;

$sms->log_sms($message, $db);

有比这更好的方法吗?

对于初学者,您可以在需要使用数据库的每个类中创建一个受保护的$db变量。然后可以将$db传递给类构造函数。以下是更新的代码:

$db = new db(username,pass,localhost,dbname);
$sms = new sms($db);
$sms->log_sms($message);

class sms {

    protected $db;

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

    public function log_sms($message) {
        $sql = "INSERT INTO `smslog` SET
                `mesasge` = '$message'
                ";
        $this->db->query($sql);

        if ($this->db->result)
                return true;
        return false;
    }
}

这个例子在PHP5中。

您可以有一个静态类,它有两个列表,一个是可用的连接,另一个是分发的连接,并且只有一个连接池


或者,如果您使用的是连接时间很快的东西,比如MySQL,那么只需在数据库类中创建连接,执行该功能所需的所有查询,然后关闭它。这是我的首选方法。

解决依赖关系问题有很多选择(对象A需要对象B):

构造函数注入

  class Sms { 
        function __construct($db) ....
  }

  $sms = new Sms (new MyDbClass);
  class Sms { 
        protected $db;
  }
  $sms = new Sms;
  $sms->db = new MyDbClass;
塞特注射

  class Sms { 
        function __construct($db) ....
  }

  $sms = new Sms (new MyDbClass);
  class Sms { 
        protected $db;
  }
  $sms = new Sms;
  $sms->db = new MyDbClass;
“注册表”模式

 class Registry {
     static function get_db() {
          return new MyDbClass;
 }}

 class Sms {
      function doSomething() {
          $db = Registry::get_db();
          $db->....
  }}
“服务定位器”模式

 class Loader {
     function get_db() {
          return new MyDbClass;
 }}

 class Sms {
      function __construct($loader) {
         $this->loader = $loader;

      function doSomething() {
          $db = $this->loader->get_db();
          $db->....
  }}

  $sms = new Sms(new Loader);
自动化的基于容器的依赖项注入,请参见示例

举几个例子;)


另外,我之前给您的Fowler文章确实值得一读

Singleton也是应用程序设计中的良好实践。它们对于避免在一次调用期间重复查询或计算非常有用。 将数据库对象传递给每个方法或构造函数不是一个好主意,请改用Singleton

扩展数据库,或在db类中插入静态方法。(我还将在db构造函数方法中调用config)

使您的方法保持静态

class sms {

    public static function log($message) {

        $sql = "INSERT INTO `smslog` SET `mesasge` = '$message'";

        database::instance()->query($sql);

        return (bool) database::instance()->result;
    }
}
下次你需要记录短信的时候,就这样做静态通话

sms::log($message);

这是最好的方式吗?我几乎有14个类,所以我应该为每个类添加一个构造函数吗?这是一个社交网站,没有最好的方法。cballou给出的方法当然是一个好方法。为了知道这对你的14门课来说是否是一个好方法,我们需要知道它们是什么。在任何情况下,如果您在这14个类上有方法,比如log($msg,$db),那么您需要传递$db对象的次数(可能甚至更多)与将其作为构造函数参数传递时的次数相同。是的,14个类意味着我还有14个类需要使用db类(如个人资料、用户设置、相册、视频、授权、消息、网络、推荐、更新等)是的,我在每个方法的参数中都提供了db。我使用$db作为参数,我相信大约有50个或更多这样的方法。如果有更好的方法,我不介意更改完整的代码,因为有更多的东西要添加到网站中。如果有任何改进的迹象,这将把$db作为参数传递从50减少到14对于那些理解正确的OOP和模式的人来说,stereo的解决方案是可行的。如果您必须返回并添加新的数据库抽象层(即缓存、另一个数据库等),它将是未来最可维护的.Im仅使用1个连接来保存资源,因为网站位于共享服务器上。那么,为什么不将查询排队,处理它们,并将结果传递到一个打包的回调中,否则当两个线程尝试使用相同的连接时,您将遇到问题。我不能,因为我为每个函数编写了一个类,例如一个class用于验证用户,一个用于获取用户详细信息,一个用于读取用户收件箱,等等,他们使用主$db类。该类在索引文件的顶部初始化,方法一个接一个地处理。每个方法都有查询,仅提取所需内容并返回数组。HTML在模板页面上呈现,如MVC。因此,第二个查询只在第一个查询之后执行。但是,我讨厌在每个函数上添加$db,我有一种感觉,如果它使事情变得缓慢,那么您应该将这些语句添加到您的问题中,这将有助于确保您获得最佳答案。您对每个查询的处理时间有什么线索?哪个更快,哪个更慢?或者如果有并没有太大的区别,那个么构造函数的东西看起来对我来说是最简单的:)哦,很好的概述。谢谢:)您和我对
注册表
服务定位器
模式的理解不同。对我来说,您的注册表看起来像一个ServiceLocator(一个知道如何实例化对象的注册表),而您的ServiceLocator看起来像。。。通过组合实现到另一个类中的ServiceLocator。这里什么都不像是注册处。