【问题标题】:PHP OOP database connectPHP OOP 数据库连接
【发布时间】:2014-01-11 01:03:03
【问题描述】:

我刚刚开始学习面向对象编程的概念,并且我已经用函数编写了这个类。

它工作正常,但我很想知道我是否正确地做到了这一点......

这是我的代码:

class Database{
    const DB_HOSTNAME = 'localhost';
    const DB_USERNAME = 'root';
    const DB_PASSWORD = 'password';
    const DB_NAME = 'shop';
    protected $_db_connect;
    protected $_sql;
    protected $_result;
    protected $_row;

    function db_connect(){
        $this->_db_connect = mysql_connect(self::DB_HOSTNAME,self::DB_USERNAME,self::DB_PASSWORD) or die(mysql_error());
    }

    function slect_db(){
        mysql_select_db(self::DB_NAME) or die(mysql_error());
    }

    function sql(){
        $this->_sql = 'SELECT * FROM users';
    }

    function query(){
        $this->_result = mysql_query($this->_sql);
    }

    function fetch_array(){
        while($this->_row = mysql_fetch_array($this->_result)){
            $username = $this->_row['user_USERNAME'];

            echo "<ul>";
                echo "<li>".$username."</li>";
            echo "</ul>";
        }
    }

    function db_close(){
        mysql_close($this->_db_connect);
    }
}

$database = new Database();
$database->db_connect();
$database->slect_db();
$database->sql();
$database->query();
$database->fetch_array();
$database->db_close();

【问题讨论】:

标签: php mysql database class oop


【解决方案1】:

请使用 PDO 或 MySQLi,因为它更安全,并且如上所述不推荐使用 mysql_* 函数,我提供了一些使用 PDO 的通用代码来帮助您进行新的冒险。如 cmets 中所述,如果您正在寻找面向对象的设计,您真的不应该回显数据,您应该做的是在执行查询之后,返回您获取的行并从那里使用一些东西例如 foreach 循环然后显示您的数据。这样做你的数据库类也将确保多个数据库连接不会一次打开!请注意,此代码仅供您参考,在生产或任何现场使用之前应进行测试。

config.php:

<?php
    //Enter your database connection details here.
    $host = 'localhost'; //HOST NAME.
    $db_name = 'databasename'; //Database Name
    $db_username = 'root'; //Database Username
    $db_password = ''; //Database Password

    try
    {
        $pdo = new PDO('mysql:host='. $host .';dbname='.$db_name, $db_username, $db_password);
    }
    catch (PDOException $e)
    {
        exit('Error Connecting To DataBase');
    }
?>

数据库.class.php:

<?php
    class database
    {
        function __construct($pdo)
        {
            $this->pdo = $pdo;
        }

        function getData()
        {
            $query = $this->pdo->prepare('SELECT * FROM database');
            $query->execute();
            return $query->fetchAll();
        }
    }
?>

index.php:

<?php
    require_once 'config.php';
    require_once 'database.class.php';
    $db = new database($pdo);
    $rows = $db->getData();
?>

【讨论】:

    【解决方案2】:

    使用自动加载和依赖注入容器可以改进连接到数据库的方式。这是一种使用 Auryn 连接到数据库的方法,同时确保只打开一个连接,而不必在整个应用程序中手动请求文件。

    我将在这里只介绍 PDO 和 Auryn。还有其他依赖注入容器,尤其是用于连接数据库的 mysqli 扩展,但如果您愿意,这些内容应该可以帮助您使用另一个容器。

    数据库类

    拥有一个数据库类是多余的。 \PDO 类已经提供了所有必要的方法来查询数据库。拥有一个数据库类可以让您重复它提供的功能并限制您的操作(或让您创建许多功能),例如,当您想根据特定方法中的需要使用多种不同的获取样式时。

    依赖注入

    如果您还没有,请发送read on dependency injection。关键是当一个类需要访问数据库时,它不应该费心构造\PDO对象,应该用它来构造:

    class Mapper {
        private $pdo;
        public function __construct(\PDO $pdo) {
            $this->pdo = $pdo;
        }
        public function createFromId($id) {
            $stmt = $this->pdo->prepare("SELECT name FROM foo WHERE id=:id");
            $stmt->execute([
                ":id" => $id,
            ]);
            return $stmt->fetchObject();
        }
    }
    

    请注意,我直接传递了\PDO 对象,而不是包装类。这样,我始终可以访问它的所有功能,而不仅仅是用户定义函数的子集。

    依赖注入容器

    依赖注入容器有助于构建您的类,为它们提供所需的对象,并为您在如何实际构建这些对象方面提供极大的灵活性。在这里,我将只专注于通过使用 Auryn 来配置和共享 \PDO 对象。

    我假设您已经安装了所需的 Auryn 类,更简单的方法是使用 composer。这超出了此答案的范围,有多种资源可以说明如何使用它。

    • 创建注入器

      $injector = new \Auryn\Injector();
      
    • 定义\PDO类参数

      $injector->define("PDO", [
          ":dsn" => "mysql:host=localhost;charset=utf8;dbname=dbname",
          ":username" => "user",
          ":passwd" => "passwd",
          ":options" => [
              PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
              PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
              PDO::ATTR_EMULATE_PREPARES => false,
          ],
      ]);
      

      您可以直接在此处编写配置参数,也可以从配置文件中获取它们。我喜欢有一个 config.ini 文件并使用parse_ini_file() 来获取我的配置选项,因为我可以通过编辑配置文件轻松切换数据库。

    • 分享\PDO 对象

      $injector->share("PDO");
      

      这部分真的很重要。这行代码使注入器在每次负责构建需要连接的类时都给出相同的\PDO 对象。请注意,行的顺序并不重要,您可以在定义之前共享类,只需确保在编写完这两行之后创建需要类的数据库。

    • 创建你的对象

      $mapper = $injector->make("Mapper");
      

      就是这样。注入器将创建您的映射器对象,如果尚未创建 \PDO 对象,则传递现有实例。

    自动加载

    假设您使用过 composer,您可以使用其出色的自动加载器。否则你也可以滚动你自己的autoloader

    这里的重点是不要在代码中到处使用require(),尤其是当你有复杂的类层次结构时,你应该在符合single responsibility 的类系统中拥有它。

    总结

    通过此设置,您现在可以在您的类中使用 \PDO 对象,同时确保每个请求只有一个实例,无需在任何地方都需要文件,也无需使用单例反模式。

    【讨论】:

    • 漂亮又简单的解释
    【解决方案3】:
    $database = new Connection();
    class Connection
    {
     function __construct()
     {
        switch($_SERVER['DOCUMENT_ROOT'])
        {
            case 'path':
                $this->host = 'hostname';
                $this->user = 'username';
                $this->passwd = 'password';
                $this->database = 'dbname';
                break;
            default :
                $this->host = 'localhost';
                $this->user = 'root';
                $this->passwd = 'root';
                $this->database = 'dbname';
                break;
        }
        $this->clink = @mysql_connect($this->host,$this->user,$this->passwd);
        @mysql_select_db($this->database,$this->clink);         
     }
    }
    

    【讨论】:

      【解决方案4】:

      $objConn = new mysqlconnect(); $Conn = $objConn->setobjConnect("localhost","root","P@ssw0rd");

      【讨论】:

      • 您应该稍微扩展您的答案,只是粘贴原始代码而不说什么,这对提问者和社区没有帮助。如果您需要一些指导,可以参考帮助中心的“如何写出好的答案”。 stackoverflow.com/help/how-to-answer
      【解决方案5】:
      class Database{
          var $last_query; //Saved result of the last query made
          var $last_result; //Results of the last query made
          var $func_call; //A textual description of the last query/get_row/get_var call
          var $link; //database link
          var $lastquery; //last query
          var $result; //query result
      
          // Connect to MySQL database
          function database() {
              $this->link=mysql_connect(DB_HOST, DB_USER, DB_PASS) or die('Server connexion not possible.');
              //Set All Charsets to UTF8
              mysql_query("SET character_set_results=utf8 , character_set_client=utf8 , character_set_connection=utf8 , character_set_database=utf8 , character_set_server=utf8");
              mysql_select_db(DB_NAME) or die('Database connection not possible.');
          }
          /** Query the database.
            * @param $query The query.
            * @return The result of the query into $lastquery, to use with fetchNextObject().
            */
          function query( $query ){
              $this->lastquery=$query;
              $this->result=@mysql_query( $query, $this->link );
              return $this->result;
          }
          /** Do the same as query() but do not return nor store result.
            * Should be used for INSERT, UPDATE, DELETE...
            * @param $query The query.
            * @param $debug If true, it output the query and the resulting table.
            */
          function execute($query)
          {
            @mysql_query($query);
          }
          /** Convenient method for mysql_fetch_object().
            * @param $result The ressource returned by query().
            * @return An ARRAY representing a data row.
            */
          function fetchArray($result){
          if ($result == NULL)
              $result = $this->result;
          if ($result == NULL || mysql_num_rows($result) < 1)
              return NULL;
          else
              return mysql_fetch_assoc($result);
          }
      
          /** Close the connecion with the database server.
            * It's usually unneeded since PHP do it automatically at script end.
            */
          function close()
          {
            mysql_close($this->link);
          }
          /** Get the number of rows of a query.
            * @param $result The ressource returned by query(). If NULL, the last result returned by query() will be used.
            * @return The number of rows of the query (0 or more).
            */
          function numRows($result = NULL)
          {
            if ($result == NULL)
              return @mysql_num_rows($this->result);
            else
              return mysql_num_rows($result);
          }
      }
      

      【讨论】:

        【解决方案6】:
        ![<?php
        class mysqlconnect{
        private $server=null;private $user=null;private $password=null;private $objConnect=null;
        function setobjConnect($s,$u,$p){
        $this->server = $s;
        $this->user = $u;
        $this->password = $p;
        return $this->objConnect = mysql_connect($this->server,$this->user,$this->password);
        }
        }
        $objConn = new mysqlconnect();
        $Conn = $objConn->setobjConnect("localhost","root","P@ssw0rd");
        if($Conn)
            {
                echo "Database Connect";
            }
            else
            {
                echo "Database Connect Failed.";
            }
        mysql_close($Conn); 
        
        ?>]
        

        1

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-01-18
          • 2016-08-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-11-01
          相关资源
          最近更新 更多