通过PHP单例模式与长连接减少MySql连接数
此单例代码有问题,请参考下面的
在Mysql驱动的PHP网站中,MySql连接的一般都是利用脚本的结束来进行释放,在一些分层写的php网站中,若一个页面含有多个数据访问类,由于每个数据访问类都会有数据库的连接,导致这一个页面在脚本结束前会有多个数据库连接,在一些大型的页面连接可能多至数十上百,为此需要进行必要的控制,对于解释性的PHP语言,脚本是顺序执行的,也就是说数据库连接的利用同时只有一个,根据这个特点,可以用单例模式来进行改造。
<?php
class ConnecToDB
{
private static $instance;
private function _constuct()
{
} //私有构造函数,防止外界构造新对象,
public static function GetConnec()
{
if (!self::$instance instanceof self) {
self::$instance =new self;//若当前对象实例不存在
}
$temp=self::$instance; //获取当前单例
return $temp::Con() ; //调用对象私有方法连接 数据库
}
//连接到数据库
private static function Con()
{
try {
$connec=mysqli_connect("127.0.0.1", "root", "root"); //数据库地址和密码等
mysqli_select_db($connec, "dbname");//选择数据库
} catch (Exception $e) {
echo $e->getMessage().'<br/>';
}
return $connec;
}
}
$db=new ConnecToDB();
$db->GetConnec();
这是正确的单例代码
<?php
class Config1 {}
class Config
{
/*
* 必须先声明一个静态私有属性:用来保存当前类的实例
* 1. 为什么必须是静态的?因为静态成员属于类,并被类所有实例所共享
* 2. 为什么必须是私有的?不允许外部直接访问,仅允许通过类方法控制方法
* 3. 为什么要有初始值null,因为类内部访问接口需要检测实例的状态,判断是否需要实例化
*/
private static $instance = null;
//保存用户的自定义配置参数
private $setting = [];
//构造器私有化:禁止从类外部实例化
private function __construct(){}
//克隆方法私有化:禁止从外部克隆对象
private function __clone(){}
//因为用静态属性返回类实例,而只能在静态方法使用静态属性
//所以必须创建一个静态方法来生成当前类的唯一实例
public static function getInstance()
{
//检测当前类属性$instance是否已经保存了当前类的实例
if (self::$instance == null) {
//如果没有,则创建当前类的实例
//self::$instance = new self();
self::$instance= new mysqli(DB_SERVER, DB_USERNAME, DB_PASSWORD, DB_NAME);
self::$instance->set_charset('utf8');
}
//如果已经有了当前类实例,就直接返回,不要重复创建类实例
return self::$instance;
}
//设置配置项
public function set($index, $value)
{
$this->setting[$index] = $value;
}
//读取配置项
public function get($index)
{
return $this->setting[$index];
}
}
//实例化Config类
$obj1 = Config::getInstance();
$obj2 = Config::getInstance();
var_dump($obj1,$obj2);
$obj1->set('host','localhost');
echo $obj1->get('host');
当然这个代码中,数据库的账号、密码等连接信息都是硬编码,可以通过改造GetConnec()函数注入相应的信息。
通过这段脚本,就可以控制一个页面只有一次数据库连接。这就会减少mysql的连接数。但是虽然减少了单次请求的连接数,但是如果这个页面进行多次刷新的话,还是会生产大量mysql连接,降低性能,如图,页面进行多次刷新后,mysql连接数,出现很多:
如何解决多次刷新情况下的大量连接呢,答案是用mysql长连接;
我们把上面的代码的
$connec=mysqli_connect("127.0.0.1", "root", "root"); //数据库地址和密码等
改为
$connec=mysqli_connect("p:127.0.0.1", "root", "root"); //数据库地址和密码等
注意:上面的代码在IP地址前加了一个“p:”前缀,代表使用的是mysql长连接,修改完成后,我们再来多次刷新页面。
如上图,只有2个连接了。解决成功。
当然,除了用mysql的长连接外,还可以修改linux 内核参数的连接重用参数,也可以达到目的。
用mysql长连接能大大提升性能,所以请务必使用mysql长连接。
评论 (0)