2015-10-16 52 views
3

我有以下数据库类。我的想法是,这将检查该类的现有实例并返回该实例,而不是创建新的数据库连接。通过PHP的MySQL数据库连接的单个实例类

当我运行代码时,它创建了一个连接。当我刷新页面时,会创建另一个连接(检查MySQL连接)。

我的想法不对吗?相当新的使用面向对象的新手问题!

任何帮助或指针在正确的方向将不胜感激。

非常感谢。

<?php 
class Db 
{ 
    private $_connection; 
    private static $_instance; 
    private $_host = 'localhost'; 
    private $_username = 'root'; 
    private $_password = 'password'; 
    private $_database = 'test'; 

    public static function getInstance() 
    { 
     if (!self::$_instance) { 
      self::$_instance = new self(); 
     } 
     return self::$_instance; 
    } 

    private function __construct() 
    { 
     try { 
      $this->_connection = new PDO("mysql:host=$this->_host;dbname=$this->_database", $this->_username, $this->_password); 
      echo 'Connected to database'; 
     } catch (PDOException $e) { 
      echo $e->getMessage(); 
     } 
    } 

    private function __clone() 
    { 
    } 

    public function getConnection() 
    { 
    return $this->_connection; 
    } 
} 

$db = Db::getInstance(); 

回答

3

PHP是“shared nothing”环境。根据所使用的server api (SAPI),由PHP应用程序处理的每个请求都与所有其他请求隔离,可以作为单独的线程或单独的进程。您设计的课程是singleton,但它被隔离到一个请求 - 响应周期。这意味着如果您在单个请求期间拨打Db::getInstance() 10次,您将获得10次对同一对象的引用,但是单独请求中的单个调用将创建并返回一个不同的对象。

您可以在服务器或应用程序端使用某种类型的连接池,以减少对后端数据库服务器发出的并发连接数。 PHP的PDO抽象通过PDO::ATTR_PERSISTENT连接驱动程序选项启用应用程序端连接池。这些池连接缓存在PHP父进程中,而不是处理请求并随后重用的工作线程/进程。根据您的SAPI和底层数据库类型,将要打开的连接的确切数量以及它们如何共享。

0

当您的服务器端语言使用PHP时,了解在后台发生的事情可能是一件好事。

PHP在您运行该代码时为您启动连接。它不会持续通过页面加载的连接。

在每个页面加载新连接将打开,以便您可以继续提出请求并执行您的任务。

想想看会发生什么。关闭页面并进入休眠状态,服务器永远与数据库保持开放连接。你会得到一些访客,然后你达到你的连接限制,并得到一个too many connections错误。

可能有一些引用引用,但我真的找不到很多,因为这是一个更合理的问题,然后编码问题。

0

每次刷新页面时,都会实例化一个全新的Db对象,并将其分配给一个名为$ db的全新变量,这样您每次都可以获得连接。我也认为你可能会让你的Db班过于复杂。

当我reate db class来包装PDO或mysqli时,我们的想法是创建一个db对象,在实例化时将包含一个数据库连接作为它的一个属性。为了达到这个目标,我会重写你的班级。像这样的东西将是你需要创建一个专用连接,你可以使用任何其他方法你想添加到类的范围内的Db对象...说,发出查询的方法,

class Db 
{ 
    private $_connection; 
    private $_host = 'localhost'; 
    private $_username = 'root'; 
    private $_password = 'flindersbeast'; 
    private $_database = 'flinders'; 

    public function __construct() 
    { 
     try { 
      $this->_connection = new PDO("mysql:host=$this->_host;dbname=$this->_database", $this->_username, $this->_password); 
      echo 'Connected to database'; 
     } catch (PDOException $e) { 
      echo $e->getMessage(); 
     } 
    } 

    // Other methods here will use $this->_connection to do a variety of things. 
    public function example() 
    { 
    // Do stuff - as needed you can pass $this->_connection to PDO 
    } 
} 

$db = new Db; 

祝你好运!