【问题标题】:PHP Class - How to connect to the database only oncePHP 类 - 如何只连接一次数据库
【发布时间】:2016-01-02 10:42:23
【问题描述】:

我尝试做一个简单的 SQL 类。 只有一个问题:

function __classDBREAD($table, $where, $value, $back)
{
    $link = mysql_connect('127.0.0.1','XXXX','XXXXXX');
    mysql_select_db('XXXX', $link);
    mysql_set_charset('utf8');

    $sql = "SELECT * FROM $table WHERE $where = '$value' LIMIT 1";
    $result = mysql_query($sql, $link) or die(mysql_error());
    $row = mysql_fetch_assoc($result);
    return $row[$back];
    mysql_close($link);
}

现在,我怎样才能只连接一次 SQL 并添加“dbUpdate”、“dbInsert”和“dbRead”等函数,而无需每次都连接到数据库?

teampeak 连接也是如此。

这里是一个例子:

require_once                      ("lib/TeamSpeak3/TeamSpeak3.php");
    $ts3_VirtualServer              = TeamSpeak3::factory("serverquery://XXXXX:XXXX@127.0.0.1:10011/?server_port=XXXX");
    $__varTeamspeakClients          = $ts3_VirtualServer->clientList();
    $__intTeamspeakClientsOnline    = $ts3_VirtualServer["virtualserver_clientsonline"] - 1;
    $ts3_VirtualServer->request('clientupdate client_nickname='.$this->__classRndString(8));

同样的问题。当我在页面中包含 Class 时,如何只定义一次连接?

【问题讨论】:

  • 一方面,您不能将 mysqli_ 作为 mysqli_close($link); 与您的 mysql_ 函数混合使用。
  • 不要mysqli_close($link);,这样您就不必再次打开它
  • @Fred-ii-,我修好了。
  • 如果您熟悉 OOP,请查看 singleton 模式。看看你是否对它感兴趣(如果实施,不要过度使用......)
  • 好吧,我想保留这个。那么,有什么方法可以在函数之外连接到数据库并调用更新/选择/插入到函数中?

标签: php class load


【解决方案1】:

由于每个人都在将他们的 OOP 扔进环中(注意:我要做 PDO,因为我更了解它,但原理是一样的,只是替换连接)

<?php
class DatabaseConnection
    {
        # Create a singleton to store the connection for reuse
        private static $singleton,
                       $con;
        # save connection to singleton and return itself (the full object)
        public function __construct()
           {
                # If your singleton is not set
                if(!isset(self::$singleton))
                    # assign it this class
                    self::$singleton = $this;
                # return this class
                return self::$singleton;
           }
        # This is a connection method because your __construct
        # is not able to return the $pdo connection
        public function connection($host='hostname',$username='username',$password='password',$database='database')
            {
                # In the connection, you can assign the PDO to a static
                # variable to send it back if it's already set
                if(self::$con instanceof \PDO)
                    return self::$con;
                # If not already a PDO connection, try and make one
                try {
                        # PDO settings you can apply at connection time
                        $opts = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,PDO::ATTR_EMULATE_PREPARES => false);
                        # Assign your PDO Conneciton here.
                        self::$con =  new PDO("mysql:host={$host};dbname={$database}",$username,$password,$opts);
                        # Return the connection
                        return self::$con;
                    }
                catch (PDOException $e){
                        exit('Database error');
                    }   
            }
    }

你可以在任何地方使用它,在你的函数、类内外,你可以命名它。每次都会返回相同的连接。如果您将spl_autoload_register() 与自动加载功能一起使用,您将一切就绪,甚至不必每次都显式使用require_once()

<?php
require_once('class.DatabaseConnection.php');
// Instantiate connection class
$pdo = new DatabaseConnection();
// Assign the connection to $con (or whatever variable you like)
$con = $pdo->connection();

请注意,singleton 模式通常最少使用。通常最好使用new Objects() 而不指定singleton。不过,我个人喜欢 singleton 用于此用途。



简单演示 - 考虑这种情况:

<?php
// Here is an example of the singlton with an echo
// which shows that the class is returning itself
// like a global
class DatabaseConnection
    {
        private static $singleton;
        public function __construct()
           {
                // If your singleton is not set
                if(!isset(self::$singleton)) {
                        echo 'NEW Object'.PHP_EOL;
                        // assign it this class
                        self::$singleton = $this;
                    }
                else
                    echo 'SAME Object'.PHP_EOL;
                // return this class
                return self::$singleton;
           }
    }

function ReturnConnection()
    {
        return new DatabaseConnection();
    }

class TestClass
    {
        public  function __construct()
            {
                new DatabaseConnection();
            }
    }

function query($sql=false)
    {
        return ReturnConnection();
    }

// The connection class wrapped in a function 
$a = ReturnConnection();
// The function nested inside a class
$b = new TestClass();
// The function nested inside another function
$c = query();

singleton 的上述用法会产生:

NEW Object
SAME Object
SAME Object

【讨论】:

    【解决方案2】:

    首先,您根本不应该使用 mysql_* 函数。它们已被弃用且使用起来很危险。但是,假设您可以使用全局变量。

    在函数之外(在全局范围内)定义您的连接,然后使用global 让您的函数访问它。现在您所要做的就是在所有需要它的函数中包含一个“全局”行。

    $link = mysql_connect('127.0.0.1','XXXX','XXXXXX');
    
    function __classDBREAD($table, $where, $value, $back)
    {
        global $link;
        mysql_select_db('XXXX', $link);
        mysql_set_charset('utf8');
    
        $sql = "SELECT * FROM $table WHERE $where = '$value' LIMIT 1";
        $result = mysql_query($sql, $link) or die(mysql_error());
        $row = mysql_fetch_assoc($result);
        return $row[$back];
        mysqli_close($link);
    }
    

    编辑...

    我没有仔细阅读这篇文章。我看到你正在上课,所以 globals 不是最好的选择。考虑一下..

    class mydbclassthing {
        private $conn;
        public function __construct(){
            $this->conn = mysql_connect('127.0.0.1','XXXX','XXXXXX');
        }
    
        function __classDBREAD($table, $where, $value, $back)
        {
            $link = $this->con;
            mysql_select_db('XXXX', $link);
            mysql_set_charset('utf8');
    
            $sql = "SELECT * FROM $table WHERE $where = '$value' LIMIT 1";
            $result = mysql_query($sql, $link) or die(mysql_error());
            $row = mysql_fetch_assoc($result);
            return $row[$back];
            mysql_close($link);
        }
    }
    

    【讨论】:

    • 嗯,是的,我想如果你想重写库的话。我不熟悉那个库,所以我不能告诉你处理它的最佳方法。
    • 我会在文件顶部使用它(在函数之外)并将其链接到它,它应该可以工作。这样,我可以在文件顶部使用 require_once 吗?
    • @ZackDaniPoladro require_once 可以,但请检查我的编辑。
    【解决方案3】:

    正如 PHP 文档所说的持久数据库连接 (http://php.net/manual/en/features.persistent-connections.php):

    每个 PHP 解释器的实例都会被创建和销毁 页面请求(对于 PHP 页面)到您的 Web 服务器。因为它是 每次请求后销毁,它获取的任何资源(例如 SQL 数据库服务器的链接)在销毁时关闭。在 在这种情况下,您不会从尝试使用持久性中获得任何收益 连接——它们根本不会持续存在。

    如果您想要更有效地重用代码,那么 OOP 方式是关键。

    我以后可能会考虑更好的解决方案,但我会使用类成员来存储 SQL 的链接,因此不必每次都创建它们:

    class MySQL {
    
        protected $mysql_link;
        protected $server = '127.0.0.1'; //and so on...
    
        public function __construct() {
           $this->link = mysql_connect($this->server,$this->user,$this->password);
           mysql_select_db($this->selected_db, $this->link);
           mysql_set_charset('utf8');
        }
    
        public function link() {
            return $this->link;
        }
    
        public function close() {
            return mysql_close($this->link);
        }
    
    }
    

    现在,在应用程序的其余部分使用 OOP(类似于依赖注入)会很棒,但如果不是,无论如何,您始终可以实例化您正在创建的类,甚至将该对象存储在 $_SESSION 变量中。

    使用 $object->link() 将始终返回该实例的链接,而不是每次需要执行任何查询时都创建新链接,

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多