php 单例模式(三私一公)

私有的静态属性 (保存类的实例)  一私

私有的构造方法 (防止类外实例化)  二私

私有的克隆方法 (防止通过克隆生成对象)  三私

公有的静态方法 (调取这个类相当一个接口 )  一公

<?php 
//单例
class Single{
    //参数
    private $config;

    //创建静态私有的变量保存该类对象 -- 一私
    static private $instance;

    //防止直接创建对象 -- 二私
    private function __construct($config){
        $this -> config = $config;
                echo "我被实例化了";
    }

    //防止克隆对象 -- 三私
    private function __clone(){

    }
    //公有的静态方法 (调取这个类相当一个接口 ) -- 一公
    static public function getInstance($config){
        //判断$instance是否是Uni的对象
        //没有则创建
        if (!self::$instance instanceof self) {
            self::$instance = new self($config);
        }
        return self::$instance;
        
    }
    public function getName(){
        echo $this -> config;
    }
    public function setName($value){
        $this -> config = $value;
    }
}
$db1 = Single::getInstance(1);
$db1 -> getName();//1
echo "<br>";
$db2 = Single::getInstance(4);
$db2 -> getName();//1,还是1
echo "<br>";
$db3 = Single::getInstance(5);
$db3 -> setName(5);
$db3 -> getName();//5,被设置过变为5
$db4 = Single::getInstance(6);
$db4 -> getName();//5,还是5
?>

总结:

1、为什么使用单例模式呢

使用单例模式可以避免大量的new操作。因为每一次new操作都会消耗系统和内存的资源。

2、用到哪里呢

数据库连接;查询多次的情况下都可以用到单例模式;

每次数据库连接都要new这个类,然后调用mysqlconnect方法,返回连接,然后close掉连接,频繁的new和数据库连接关闭操作非常的消耗资源!数据库软件系统中使用数据库连接池,主要是节省打开或者关闭数据库连接所引起的效率损耗,这种效率上的损耗还是非常昂贵的,因为何用单例模式来维护,就可以大大降低这种损耗。

先看一段代码:(这是一个数据库连接类)

<?php  
class Mysql  
{  
    // MYSQL数据库连接信息  
    const HOSTNAME = "127.0.0.1";  
    const USERNAME = "root";  
    const PASSWORD = "***";  
    const DBNAME = "test";  
    const CHARSET = "utf8";  
 
    public function MysqlConnect()  
    {  
        $db = new mysqli(self::HOSTNAME, self::USERNAEM, self::PASSWORD, self::DBNAME); // 连接数据库  
        $db->query("set names ".self::CHARSET);  
        if (mysqli_connect_errno())  
        {  
            throw new MysqlException("服务器系统故障", 1001);  
        }  
        else  
        {  
            return $db;  
        }  
    }  
}  
?>

因此,为了避免资源消耗,我们有了下面的改进:

<?php
    class Mysql{
        //该属性用来保存实例
        private static $conn;
        //构造函数为private,防止创建对象
        private function __construct(){
            $this->conn = mysql_connect('localhost','root','');
        }
        //创建一个用来实例化对象的方法
        public static function getInstance(){
            if(!(self::$conn instanceof self)){
                self::$conn = new self;
            }
            return self::$conn;
        }
        //防止对象被复制
        private function __clone(){
            trigger_error('Clone is not allowed !');
        }
        
    }
    //只能这样取得实例,不能new 和 clone
    $mysql = Mysql::getInstance();
?>

这样就不用每次都来new这个类了,方便了很多。下面给一个详细的:

<?php
class  Mysql
{
    private $DB;
    static private $_instance;
    // 连接数据库
    private function __construct($host, $username, $password)
    {
        $this->DB = mysql_connect($host, $username, $password);
        $this->query("SET NAMES 'utf8'", $this->link);
        return $this->DB;
    }
    
    private function __clone(){}
    
    public static function getInstance($host, $username, $password)
    {    
        if( !(self::$_instance instanceof self) )
        {
            self::$_instance = new self($host, $username, $password);
        }
        return self::$_instance;
    }
    
    // 连接数据表
    public function select_db($database)
    {
        $this->result = mysql_select_db($database);
        return $this->result;
    }
    
    // 执行SQL语句
    public function query($query)
    {
        return $this->result = mysql_query($query, $this->link);
    }
    
    // 将结果集保存为数组
    public function fetch_array($fetch_array)
    {
        return $this->result = mysql_fetch_array($fetch_array, MYSQL_ASSOC);
    }
    
    // 获得记录数目
    public function num_rows($query)
    {
        return $this->result = mysql_num_rows($query);
    }
    
    // 关闭数据库连接
    public function close()
    {
        return $this->result = mysql_close($this->link);
    }
    
}
?>

使用的时候:

$con = Mysql::getInstance($host, $username, $password);
$con -> select_db($database);

当然,单例模式不仅仅只是应用在数据库的操作类上面。还可以应用在这些方面:

1. 网站的计数器,一般也是采用单例模式实现,否则难以同步。

2. 应用程序的日志应用,一般都何用单例模式实现,这一般是由于共享的日志文件一直处于打开状态,因为只能有一个实例去操作,否则内容不好追加。

3. Web应用的配置对象的读取,一般也应用单例模式,这个是由于配置文件是共享的资源。

本文部分转载:感谢原创!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值