PHP OOP数据库连接

Pir*_*aTa 8 php mysql database oop class

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

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

这是我的代码:

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();
Run Code Online (Sandbox Code Playgroud)

ZZP*_*LKF 14

请使用PDO或MySQLi,因为它更安全,并且如上所述不推荐使用mysql_*函数,我已经提供了一些使用PDO的通用代码来帮助您进行新的冒险.正如评论中所述,如果你正在寻找一个面向对象的设计,你真的不应该回应数据,你应该做的是在你做查询后,返回你提取的行,然后从那里使用一些东西比如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');
    }
?>
Run Code Online (Sandbox Code Playgroud)

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();
        }
    }
?>
Run Code Online (Sandbox Code Playgroud)

index.php文件:

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


Fél*_*ier 5

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

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

数据库类

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

依赖注入

如果您还没有读过,请阅读依赖注入。要点是,当一个类需要访问数据库时,它不应该费心构造对象\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();
    }
}
Run Code Online (Sandbox Code Playgroud)

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

依赖注入容器

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

我假设您已经安装了所需的 Auryn 类,更简单的方法是使用Composer。这超出了本答案的范围,有多种资源介绍如何使用它。

  • 创建注入器

    $injector = new \Auryn\Injector();
    
    Run Code Online (Sandbox Code Playgroud)
  • 定义\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,
        ],
    ]);
    
    Run Code Online (Sandbox Code Playgroud)

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

  • 共享\PDO对象

    $injector->share("PDO");
    
    Run Code Online (Sandbox Code Playgroud)

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

  • 创建你的对象

    $mapper = $injector->make("Mapper");
    
    Run Code Online (Sandbox Code Playgroud)

    就是这样。注入器将创建您的映射器对象,\PDO如果还没有创建该对象,则创建该对象,如果已经存在,则传递现有实例。

自动加载

假设您使用过 Composer,您可以利用它出色的自动加载器。否则,您也可以使用自己的自动加载器

这里的要点是停止require()在代码中到处使用,特别是如果您有复杂的类层次结构,而您应该在单一职责兼容的类系统中拥有这些层次结构。

包起来

通过此设置,您现在可以\PDO在类中使用该对象,同时确保每个请求只有一个实例,而不需要到处都需要文件,也不需要使用单例反模式。