【问题标题】:PHP - mySQL DB classPHP - mySQL 数据库类
【发布时间】:2011-02-20 19:50:44
【问题描述】:

我已经看到 C++ 中的 OOP 有多么强大,所以我开始阅读 PHP 的 OOP。这让我想改造我的一个网站,以便它使用 OOP PHP 来清理它现在所处的皇家混乱。我已经知道 OOP 的基本概念,但是我在应用它时有点吃力。

到目前为止,我看到的所有使用 OOP PHP 的网站都有某种 mySQL DB 类。我绝对可以看到它的好处(当您想访问数据库中的某些内容时,代码更简洁),但我不完全确定如何设置我的。这就是我想知道的:

  • 我应该做的第一件事是什么 从
    构建此类时 接地? (这门课应该如何 设置?这背后的想法是什么 结构体?它是什么样子的 什么时候设置成这样?)
  • 我的方法应该有哪些 数据库类? (什么样的功能 我的 DB 课程应该提供吗? SQL 插入? SQL 更新?普通的 ole' SQL 查询?这些应该是什么数据 方法返回?)
  • 如何确定何时需要添加 类的新方法?
  • 我应该如何在我的其他代码中使用这些方法?

谢谢。

【问题讨论】:

    标签: php mysql oop class


    【解决方案1】:

    如果您的意思是连接到数据库、准备和运行查询的类,请使用PDO(请尝试使用“Writing MySQL Scripts with PHP and PDO”获取教程)。如果您的意思是 Data Access Object (DAO),它是一个或多个类,用作 bridge between the database records 和您的应用程序对象,请尝试 data mapperactive record 模式。请注意,活动记录模式有点陈旧,有些人不喜欢,所以关于 PHP 中活动记录的文章往往比较老,而且有点过时了。

    无论你应用什么模式,你的类应该提供的四个基本操作是create, read, update and delete (CRUD)。创建和读取返回应用程序对象,更新和删除可以返回指示成功或失败的值。

    使用类相当简单:当您需要一个对象时,使用 create 或 read 而不是对象构造函数。何时使用更新或删除取决于您的业务逻辑。例如,您可能需要在完成对象时(即对象被销毁时)进行更新。更棘手的是对象或函数如何获得对 DAO 的引用。阅读 Martin Fowler 在dependency injection 上的文章,了解几种不同的方法。

    进一步阅读:

    【讨论】:

      【解决方案2】:

      有几种方法可以解决这个问题,首先您可以将系统“集成”到本地系统中,例如 mysqli,或者您可以使用驱动程序从头开始创建自己的系统/结构。

      第一种方法有点局限,因为你必须遵守原生 API 的内部结构。

      我个人的方法通常是第二种,因为我可以创建一个基于驱动程序的系统,并根据主机操作系统和其他几个因素决定使用什么本机系统。

      在为您的应用程序创建数据库 API 以运行您不希望它专门用于该应用程序时,您应该能够获取库并将它们放入一个新项目中,并且一切都应该按预期工作,所以让它摘要是我们必须解决的第一个问题。

      下一个障碍是使代码可扩展,编程世界发生了翻天覆地的变化,所以我们应该为变化做好准备,虽然代码只能用几年,但如果我们考虑这么多年并做好准备,那将是有益的.

      想象一下,如果下周创建了一个比当前集成到 PHP 中的 mysql(i) 层快 50 倍的新数据库层,您会想尽快切换到该 api,考虑这些因素总是一个好主意在开发阶段。

      首先我们应该决定结构,对于传统的抽象层,代码通常都内置在一个大的类文件中,这可能是一种糟糕的编程,因为它应该被分解成它的用途。

      我们应该分离类/对象,以便它们执行专门设计的任务。

      我们应该有 1 个全局“控制器”,它是主数据库类,它将控制发送到子类和从子类发送的所有操作。

      我们将至少为 PHP 5.3 进行设计,所以让我们开始吧:

      我倾向于创建一些最终结果的伪代码,这样我就可以了解应该实现什么。

      $Connection = new DatabaseConnectionDetails(array(
          "hostname" => "localhost",
          "username" => "root",
          "password" => "n/a",
          "charset" => "UTF-8",
          "database" => "my_database",
          "driver" => "MySQL",
      ));
      
      $Database = Database::getInstnace($Connection);
      
      $Query = $Database->Query("SELECT * FROM {?:table} WHERE id = {?:id}",array(
          "table" => "posts",
          "id"    => 22
      ));
      
      if($Query->Execute())
      {
          $Results = $Query->GetResults();
      
          foreach($Results as $Result)
          {
               echo $Result->data; //trims, converts to int, returns;
          }
      }
      

      这就是我想要连接到我的数据库的方式,所以这就是我开始使用基类的方式

      class Database
      {
          private static $_DBInstance;
      
          public static function getInstance(IDatabaseConnectionDetails $ConnectionDetails)
          {
              if(self::$_DBInstance === null)
              {
                  self::$_DBInstance = new Database($ConnectionDetails);
              }
              return self::$_DBInstance;
          }
      
          public function __construct(IDatabaseConnectionDetails $ConnectionDetails)
          {
              //We will come back to this.
          }
      }
      

      查看上面的类,您会看到首先它有一个创建实例(单例),这将有助于在任何应用程序中使用数据库,您还会注意到我专门定义了所需的参数。

      在整个抽象层中保持上述因素将使生活变得更加轻松。

      让我稍微解释一下目录结构,您必须单独列出以下类

      • 数据库
        • 查询类
      • 接口
      • 驱动程序
      • 帮手

      我会选择一个有点像这样的结构:

      • 包括
        • DBAL
          • Database.class.php
          • DatabaseConnectionDetails.class.php
          • 驱动程序
          • 接口
          • 结果

      如上所述,需要IDatabaseConnectionDetails 接口,这样做的目的是使凭据和主数据库分离,因此IDatabaseConnectionDetails 的主要作用是管理用户凭据。

      class DatabaseConnectionDetails implements IDatabaseConnectionDetails
      {
          public $hostname = "localhost";
          public $username = "";
          public $password = "";
          public $charset = "UTF-8";
          public $driver = "mysqli";
      
          public function __construct($params)
          {
              //Set Params here
          }
      }
      

      现在上面已经提到了为你的配置创建一个类的好处,类的可扩展性,例如:

      class MyCustomConfig extends DatabaseConnectionDetails
      {
              public $hostname = "host.domain.tld";
              public $username = "my_other_user";
              public $password = "IJH87b&OTIT8fh";
              public $driver   = "mssql";
      }
      

      当类被接口时,您可以将任何类发送到主数据库对象中,无论是否自定义,因为接口允许您进行扩展。

      现在是所需的驱动程序,您应该注意每个驱动程序都应该是驱动程序接口的一部分,这会强制一组方法位于驱动程序本身内。

      interface IDatabaseDriver
      {
          public function setConnectionDetails(IDatabaseConnectionDetails $ConnectionDetails);
          public function connect();
          public function escape($string);
          public function query($string);
          /*
             all the methods here that will allow the main class can access, such as:
             - next()
             - prev()
             - reset()
             ect ect
          */
      }
      

      然后,主数据库类将能够根据 $Config->driver 加载正确的驱动程序。

      您将在主数据库类中创建模仿典型数据库系统的通用函数,例如fetchObjectfetchArray() 等,然后这些方法将使用驱动程序对象来选择、准备、清理数据,然后返回使用另一个对象/类(例如 QueryResult)的结果将具有一组专用方法,这些方法仅用于遍历结果集。

      希望您喜欢这篇长篇文章,但应该让您从头脑中的一个想法开始。

      问候: 罗伯特

      【讨论】:

        猜你喜欢
        • 2017-02-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多