单例模式也就是一个类只能创建出一个对象
首先你要知道它的基本思想为:三私一公!
何为三私一公?
1(私)、防止用户通过构造方法创建对象,因此私有化构造方法。
2(公)、创建一个公共静态函数用来进入类内部;思考:为什么要是静态的?为什么要公开?答:因为目前没有任何对象,只能由类来调用;因为需要类外调用
3(私)、增加一个静态私有属性:该静态属性用于保存已经实例化好了的对象,判断是否存在这个对象,如果存在,后续调用的时候直接返回它就行了!思考:为什么要是静态的?为什么要私有?答:因为还没有对象,只能用类去访问;因为要保证类外不能操作该属性。
4(私)、将克隆方法私有化,防止用户通过克隆来创建新的对象。
以下通过一个数据库连接的例子来讲解:
<?php class MySQLDB{ //定义数据可连接和要用到的属性 private $host;//主机地址 private $port;//端口号 private $user;//用户名 private $pass;//密码 private $charset;//默认字符集 private $dbname;//默认数据库 private $link;//保存连接资源 private static $instance;//定义一个私有化静态变量用来判断是否为新对象 //私有化构造函数 private function __construct($config){ $this->init($config);//调用初始化属性的值函数 $this->my_connect();//调用连接数据库函数 $this->my_charset();//调用设置字符集函数 $this->my_dbname();//设置数据库 } //初始化私有属性的值 private function init($config){ $this->host=$config['host']?? "localhost";//判断用户是否传入了host这个属性,有的话就使用用户传入的否则就使用默认属性。??这个是简化版的三目运算符。 $this->port=$config['port']?? 3306;//下面这些都是和上面一样 $this->user=$config['user']?? 'root'; $this->pass=$config['pass']?? 'admain'; $this->charset=$config['charset']?? 'utf8'; $this->dbname=$config['dbname']?? 'php'; } //获得实例化对象 public static function instance($config){ if(!self::$instance instanceof self){ //判断是否这个私有化静态变量是一个对象,不是就创建一个对象。 self::$instance=new self($config); } return self::$instance; //返回这个私有化静态变量 } //定义私有化克隆防止克隆出一个新的对象 private function __clone(){ } //连接数据库 private function my_connect(){ $link=mysqli_connect("$this->host:$this->port",$this->user,$this->pass);//连接数据库并把值赋给$link.注意这个$link和最开始定义的那个私有化属性$link不一样,只是恰好名字一样而已 if($link){ //判断是否存在这个$link.因为$link是个资源集所以可以直接判断 $this->link=$link;//存在则把这个$link资源集赋值给私有化属性$link }else{ echo "对不起连接数据库失败"; return false; } } //封装判断函数 private function my_query($sql){ $res=mysqli_query($this->link,$sql); if(!$res){ echo "对不起语句执行失败"; return false; }else{ return $res; } } //选择字符集 private function my_charset(){ $sql="set names $this->charset"; $this->my_query($sql); } //选择数据库 private function my_dbname(){ $sql="use $this->dbname"; $this->my_query($sql); } //释放资源 private function __destruct(){ @mysqli_close($this->link); } } $config=array("user"=>"root","pass"=>"admain");//定义要传入的数组参数 $obj= MySQLDB::instance($config);//调用公共静态函数来创建一个对象 $obj1= MySQLDB::instance($config);//这里再次调用用来验证是否只能出创建一个对象。 var_dump($obj); var_dump($obj1);
结果我这里就不放出来了图片有点大。你会发现var_dump()出来的这两个对象一模一样。