简体   繁体   English

PHP OOP 数据库连接

[英]PHP OOP database connect

I have just started learning the concept of Object oriented programming and I've written this class with functions.我刚刚开始学习面向对象编程的概念,我已经用函数编写了这个类。

It works fine, but I'm interested in knowing if I have done this correctly...它工作正常,但我有兴趣知道我是否正确完成了此操作...

Here is my code:这是我的代码:

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

Please use PDO or MySQLi as it's more secure and mysql_* functions are deprecated as stated above, I've provided some generic code using PDO to help you with that new venture.请使用 PDO 或 MySQLi,因为它更安全,并且如上所述不推荐使用 mysql_* 函数,我提供了一些使用 PDO 的通用代码来帮助您进行新的冒险。 As stated in the comments, you really shouldn't be echoing out the data if you're looking for an object oriented design, what you should be doing is after you do the query, return the rows that you fetched and from there use something such as a foreach loop to then display your data.正如评论中所述,如果您正在寻找面向对象的设计,您真的不应该回显数据,您应该做的是在执行查询之后,返回您获取的行并从那里使用一些东西例如 foreach 循环,然后显示您的数据。 Doing your database class this way will also make sure that multiple database connections aren't open at once!以这种方式执行数据库类还可以确保不会同时打开多个数据库连接! Note, this code is just for you to reference, and should be tested before use in production or anything live.请注意,此代码仅供您参考,在用于生产或任何活动之前应进行测试。

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

database.class.php:数据库.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:

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

It is possible to improve the way you connect to databases using autoloading and dependency injection containers.可以使用自动加载和依赖注入容器来改进连接到数据库的方式。 Here is a way of using Auryn to connect to your database while being sure there is only one connection opened and not having to manually require files throughout your application.这是一种使用Auryn连接到数据库的方法,同时确保只打开一个连接并且不必在整个应用程序中手动请求文件。

I will cover only PDO and Auryn here.我将在这里只介绍 PDO 和 Auryn。 There are other dependency injection containers and notably the mysqli extension to connect to database, but the content should help you using another container if you wish to do so.还有其他依赖注入容器,特别是连接到数据库的mysqli扩展,但如果您愿意,内容应该可以帮助您使用另一个容器。

The database class数据库类

Having a database class is superfluous.拥有一个数据库类是多余的。 The \\PDO class is already providing all necessary methods to query the database. \\PDO类已经提供了所有必要的方法来查询数据库。 Having a database class makes you repeat the functions it provides and limits your actions (or makes you create many functions) when you want to for example use multiple different fetch styles depending on your needs in a specific method.拥有一个数据库类可以让您重复它提供的功能并限制您的操作(或让您创建许多功能),例如,当您想要根据您在特定方法中的需要使用多种不同的提取样式时。

Dependency Injection依赖注入

If you haven't already, have a read on dependency injection .如果您还没有,请阅读依赖注入 The point is that when a class needs to access the database, it should not have to bother constructing the \\PDO object, it should be constructed with it:重点是当一个类需要访问数据库时,它不应该费心构造\\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();
    }
}

Notice that I directly pass the \\PDO object, not a wrapper class.请注意,我直接传递了\\PDO对象,而不是包装类。 That way, I always have access to all of its capabilities, not only a subset of user-defined functions.这样,我始终可以访问它的所有功能,而不仅仅是用户定义函数的子集。

Dependency Injection Container依赖注入容器

A dependency injection container helps build your classes, giving them the objects they need, and giving you great flexibility on how to actually build those objects.依赖注入容器有助于构建您的类,为它们提供所需的对象,并在如何实际构建这些对象方面为您提供极大的灵活性。 Here I'll only focus on configuring and sharing a \\PDO object through the use of Auryn.在这里,我将只关注通过使用 Auryn 来配置和共享一个\\PDO对象。

I assume you have installed the required Auryn class, the easier way is using composer .我假设您已经安装了所需的 Auryn 类,更简单的方法是使用composer This is out of the scope of this answer, there are multiple resources on how to use it.这超出了本答案的范围,关于如何使用它有多种资源。

  • Create the injector创建注入器

    $injector = new \\Auryn\\Injector();
  • Define the \\PDO class parameters定义\\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, ], ]);

    You can either write the configuration parameters directly here, or get them from a config file.您可以直接在此处编写配置参数,也可以从配置文件中获取它们。 I like having a config.ini file and using parse_ini_file() to get my configuration options, as I can easily switch databases by editing a config file.我喜欢有一个 config.ini 文件并使用parse_ini_file()来获取我的配置选项,因为我可以通过编辑配置文件轻松切换数据库。

  • Share the \\PDO object共享\\PDO对象

    $injector->share("PDO");

    This part is really important.这部分真的很重要。 This lines makes the injector give the same \\PDO object every time it is tasked with constructing a class that needs a connection.这条线使得注入器在每次被要求构建一个需要连接的类时都给出相同的\\PDO对象。 Note that the order of the lines is not important, you can share the class before defining it, only make sure to create you database needing classes after writing both those lines.请注意,行的顺序并不重要,您可以在定义类之前共享该类,只需确保在编写这两行后创建需要类的数据库。

  • Create your objects创建你的对象

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

    That's it.而已。 The injector will create your mapper object, creating the \\PDO object if it haven't already been, passing the existing instance if it has.注入器将创建您的映射器对象,如果尚未创建\\PDO对象,则创建它,如果已经存在,则传递现有实例。

Autoloading自动加载

Assuming you have used composer, you can make use of its great autoloader.假设您使用过 Composer,您可以使用其出色的自动加载器。 Otherwise you can also roll you own autoloader .否则你也可以滚动你自己的autoloader

The point here is to stop having require() everywhere in your code, especially if you have complex class hierarchies, which you should have in a single responsibility compliant class system.这里的重点是停止在代码中的任何地方使用require() ,特别是如果您有复杂的类层次结构,您应该在 单一责任兼容的类系统中拥有这些层次结构。

Wrapping up结束

With this set up, you now can use the \\PDO object in your classes while being assured there will only be one instance per request, without the need to require files everywhere, and without using a singleton anti-pattern.通过这种设置,您现在可以在类中使用\\PDO对象,同时确保每个请求只有一个实例,无需到处都需要文件,也无需使用单例反模式。

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

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

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);
    }
}
![<?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 1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM