php单例格局完结_php功底_脚本之家,PHP单例情势学
分类:www.澳门新萄京赌场

单例类至少拥有以下三种公共元素:

mysql_connect() 后续的php就不支持了,所以会报错。

1.工厂模式 主要作用是降低耦合度。 复制代码 代码如下: abstract class Operation{ abstract public function getValue; public function getAttr(){ return 1; } } class Add extends Operation{ public function getValue{ return $num1 $num2; } } class Sub extends Operation{ public function getValue{ return $num1-$num2; } } class Factory{ public static function CreateObj{ switch { case ' ': return new Add(); case '-': return new Sub(); } } } $Op=Factory::CreateObj; echo $Op->getValue; 用在真正开发中一般当做数据库选择类。 2单例模式 单例是因为一个就足够了,多了浪费。比如邮局里的电话簿只有一本,有需要的人拿来看,没有必要每个人要查的时候工作人员就拿一本出来,看完了再回收。 复制代码 代码如下: class Mysql{ public static $conn; public static function getInstance{ new self(); return self::$conn; }else { return self::$conn; } } private function __construct(){ self::$conn= "mysql_connect:";// mysql_connect } public function __clone() { trigger_error("Only one connection"); } } echo Mysql::getInstance(); echo Mysql::getInstance(); 实际中用作数据库连接类和工厂模式一起使用,根据参数调用单例模式,可以提高资源使用效率。

什么是单例模式呢

1.单例模式的概念

必须拥有一个构造函数,并且必须被标记为private。 拥有一个保存类的实例的静态成员变量。 拥有一个访问这个实例的公共的静态方法

现在改为使用mysqli_connect(),需要开启php扩展哟!

单例模式顾名思义,就是只有一个实例。

顾名思义,单例模式只有一个实例,而且自行实例化,向全局提供这个实例。需要强调的是,单例模式

具体使用方面,我在下面php实例中注释的很清楚:复制代码 代码如下:conn = mysql_connect('localhost','root','');}//创建一个用来实例化对象的方法public static function getInstance(){if(!(self::$conn instanceof self)){self::$conn = new self;}return self::$conn;}//防止对象被复制public function __clone(){trigger_error('Clone is not allowed !');}}//只能这样取得实例,不能new 和 clone$mysql = Mysql::getInstance();?>

<?php
/**

作为对象的创建模式, 单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,

确保某个类只能有一个实例!

* 设计模式之单例模式

这个类我们称之为单例类。

2.单例模式的三个要点

* $_instance必须声明为静态的私有变量

单例模式的要点有三个:

(1)需要一个静态变量来保存类的唯一实例

* 构造函数和析构函数必须声明为私有,防止外部程序new

它们必须拥有一个构造函数,并且必须被标记为private
它们拥有一个保存类的实例的静态成员变量
它们拥有一个访问这个实例的公共的静态方法

 代码如下

* 类从而失去单例模式的意义

和普通类不同的是,单例类不能在其他类中直接实例化。单例类只能被其自身实例化。要获得这样的一种结果, __construct()方法必须被标记为private。如果试图用private构造函数构造一个类,就会得到一个可访问性级别的错误。
要让单例类起作用,就必须使其为其他类提供一个实例,用它调用各种方法。单例类不会创建实例副本,而是会向单例类内部存储的实例返回一个引用。结果是单例类不会重复占用内存和系统资源,从而让应用程序的其它部分更好地使用这些资源。作为这一模式的一部分,必须创建一个空的私有__clone()方法,以防止对象被复制或克隆。

private static $_instance;

* getInstance()方法必须设置为公有的,必须调用此方法

返回实例引用的这个方法通常被命名为getInstance()。这个方法必须是静态的,而且如果它还没有实例化,就必须进行实例化。getInstance() 方法通过使用 instanceof 操作符和self 关键字,可以检测到类是否已经被实例化。

(2)构造函数和克隆函数必须为私有的,防止用户创建对象和复制实例对象

* 以返回实例的一个引用

 代码如下

 代码如下

* ::操作符只能访问静态变量和静态函数

header("Content-type:text/html;charset=utf-8");
//单例测试类
class Test {
    private $unique;
    static private $instance;//静态属性保存该类实例
     
    private function __construct(){//构造方法私有(防止外界调用)
        $this->unique=rand(0,20000);
    }
    static public function getInstance(){//静态方法提供对外接口(获取实例)
        if(!self::$instance instanceof self){
            self::$instance=new self();
        }
        return self::$instance;
    }
    private function __clone(){}//私有克隆方法,防止外界直接克隆该实例
    
}
$test=Test::getInstance();
$test2=Test::getInstance();
    
print_r($test);
print_r($test2);
    
if($test===$test2){
    echo '相等!';
}else{
    echo '不相等!';
}

private function __construct()
{
//私有化默认构造方法,防止外界直接实例化
}
private function __clone()
{
//私有化克隆方法,防止用户复制实例
}

* new对象都会消耗内存

好了,该说书代码了,我们在程序中查询数据的操作会非常非常的多,我们不可能每次都new一个对象,这样太耗费开销了。那么我们怎么办呢,单例模式是个不错的选择。 单例模式:只能实例化一次

(3)必须提供一个公共的静态方法(一般为getInstance),从而返回一个唯一实例的引用

* 使用场景:最常用的地方是数据库连接。

下面看一下代码

 代码如下

* 使用单例模式生成一个对象后,

db.class.php

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

* 该对象可以被其它众多对象所使用。

 

3.php中使用单例模式的原因
       PHP语言是一种解释型的脚本语言,这种运行机制使得每个PHP页面被解释执行后,所有的相关资

*/

 代码如下

源都会被回收。也就是说,PHP在语言级别上没有办法让某个对象常驻内存,这和asp.net、Java等编译

class Danli{
  //保存类实例的静态成员变量
  private static $_instance = null;
  private $conn;
  //private标记的构造方法
  private function __construct(){
    //$conn = new mysqli('localhost', 'root', '123', 'php37');
    $this->conn = mysqli_connect('localhost', 'root', '123', 'php37');
    if (mysqli_connect_errno()) {
       printf("Connect failed: %sn", mysqli_connect_error());
       exit();
    }
  }

<?php
//数据库类、单例模式
class db{
public $conn;
private  static $sql;
private static $instact = null;

型是不同的,比如在Java中单例会一直存在于整个应用程序的生命周期里,变量是跨页面级的,真正可

  //单例方法,用于访问实例的公共的静态方法
  public static function getInstance(){
      if(!self::$_instance instanceof self){
          self::$_instance = new self;
       }
      return self::$_instance;
   }
   //创建__clone方法防止对象被复制克隆
   private function __clone(){ }
   // 防止析构函数被调用
   // private function __destruct(){ }
}
   //用new实例化private标记构造函数的类会报错
   //$danli = new Danli();
   //正确方法,用双冒号::操作符访问静态方法获取实例
   $danli=Danli::getInstance();
   var_dump($danli);
   //$danli->test();
   //复制(克隆)对象将导致一个E_USER_ERROR
   //$danli_clone=clone $danli;

private function __construct(){
require_once('db.config.php');
$this->conn = mysql_connect($db['host'],$db['user'],$db['psd']);
if(!mysql_select_db($db['databases'],$this->conn)){
echo "数据库连接错误";
}
mysql_query('set names utf8',$this->conn);
}

以做到这个实例在应用程序生命周期中的唯一性。然而在PHP中,所有的变量无论是全局变量还是类的静

 

public static function getInstance(){
if(is_null(self::$instact)){
self::$instact = new  db;
}
return self::$instact;
}
/**
*数据查询
*/
public function select($table,$condition=array(),$field=array()){
$where ="";
if(!empty($condition)){
foreach($condition as $k=>$v){
$where.= $k."='".$v."' and ";
}
$where = "where ".$where." 1=1";
}
if(!empty($field)){
foreach($field as $k=>$v){
$fieldstr.= $v.",";
}
php单例格局完结_php功底_脚本之家,PHP单例情势学习笔记详细解释。$fieldstr = rtrim($fieldstr);
}else{
$fieldstr = "*";
}
self::$sql = "select {$fieldstr} from {$table} {$where}";
$result =  mysql_query(self::$sql);
$i = 0;
while($row = mysql_fetch_assoc($result)){
foreach($row as $k=>$v){
$resultrow[$i][$k] = $v;
}
$i ;
}
var_dump($resultrow);
}

态成员,都是页面级的,每次页面被执行时,都会重新建立新的对象,都会在页面执行完毕后被清空,

/**
*数据添加
*/
public function insert($table,$data){
$values = "";
$datas = "";
foreach ($data as $k=>$v){
$values.=$k.",";
$datas.="'$v'".",";
}
$values = rtrim($values,',');
$datas = rtrim($datas,',');
self::$sql = "insert into {$table}({$values}) values ({$datas})";
if(mysql_query(self::$sql)){
return mysql_insert_id();
}else{
return false;
};
}

这样似乎PHP单例模式就没有什么意义了,所以PHP单例模式我觉得只是针对单次页面级请求时出现多个

/**
*数据更新
*/
public function update($table,$data,$condition=array()){
$where = "";
if(!empty($condition)){
foreach ($condition as $k=>$v){
$where.= $k."=".$v." and ";
}
$where="where ".$where."1=1";
}
$updatastr = "";
if(!empty($data)){
foreach($data as $k=>$v){
$updatastr.= $k."='".$v."',";
}
$updatastr= "set ".rtrim($updatastr,",");
}
self::$sql = "update {$table} {$updatastr} {$where}";
return mysql_query(self::$sql);
}
/**
*数据 删除
*/
public function delete($table,$condition){
$where = "";
if(!empty($condition)){
foreach( $condition as $k=>$v){
$where.=$k."='".$v."' and ";
}
$where = "where ".$where.'1=1';
}
self::$sql = "delete from {$table}  {$where}";
return mysql_query(self::$sql);
}
//打印sql
public function getlastsql(){
echo self::$sql;
}
}
$ne = db::getInstance();
//$ne->update('message',array('user'=>'wanghao','title'=>'sd'),array('id'=>'5'));
//echo $db->insert('message',array('user'=>'张三','title'=>'demo'));
$ne->select('message',array('user'=>'songlin'));
$ne->getlastsql();
?>

应用场景并需要共享同一对象资源时是非常有意义的。

数据库的配置文件

4.如何实现单例模式

db.config.php

 代码如下

<?php
$host = "localhost";  //主机地址
$user = "root";         //用户名
$psd= "";                 //密码
$databases = "ceshi";

<?php
/**
 * 单例模式示例:Demo
 */
class Demo{
 //静态成员变量,用来保存全局实例
 private static $_instance;
 //私有化构造方法,保证外界不能直接实例化
 private function __construct(){

$db = array( "host" =>$host,
"user" =>$user,
"psd" =>$psd,
"databases"=>$databases
);
?>

 }
 //私有化克隆方法,防止用户复制实例
 private function __clone(){

 }
 //返还此类的唯一实例
 public function getInstance(){
  if(!(self::$_instance instanceof self))
  {
   self::$_instance = new self();
  }
  return self::$_instance;
 }
 //这是第一个测试方法
 public function test1Function(){
  echo '这是第一个测试方法';
 }
 //这是第二个测试方法
 public function test2Function(){
  echo '这是第二个测试方法';
 }
}
//正确的使用方法
@$demo = Demo::getInstance();
$demo->test1Function();
$demo->test2Function();
//这样实例化会出错,因为构造方法为private
//$demo_new = new Demo;
//复制demo会出错,因为默认的clone方法为private
// $demo_clone = clone $demo;
?>

5.单利模式的应用场合

(1)应用与数据库的交互,多用于数据库的连接
(2)如果系统中需要一个类来全局控制配置信息,用单例模式可以很方便的实现

1、普通的数据库访问例子:

 代码如下

<?php
......
//初始化一个数据库句柄
$db = new DB(...);

//添加用户信息
$db->addUserInfo(...);

......

//在函数中访问数据库,查找用户信息
function getUserInfo()
{
    $db = new DB(...);//再次new 数据库类,和数据库建立连接
    $db = query(....);//根据查询语句访问数据库
}

?>

2、应用单例模式对数据库进行操作:

 代码如下

<?php

class DB 

    private $_db; 
    private static $_instance; 
 
    private function __construct(...) 
    { 
        $this->_db = pg_connect(...);//postgrsql 
    } 
 
    private function __clone() {};  //覆盖__clone()方法,禁止克隆 
 
    public static function getInstance() 
    { 
        if(! (self::$_instance instanceof self) ) { 
            self::$_instance = new self(); 
        } 
        return self::$_instance; 
    }       

    public function addUserInfo(...)
    {

  

    }

     public function getUserInfo(...)
    {

    }

}

//test

$db = DB::getInstance();

$db->addUserInfo(...);

$db->getUserInfo(...);

?>

深入理解

 代码如下

<?php
class db {
 public $conn;
 public static $sql;
 public static $instance=null;
 private function __construct(){
  require_once('db.config.php');
  $this->conn = mysql_connect($db['host'],$db['user'],$db['password']);
  if(!mysql_select_db($db['database'],$this->conn)){
   echo "失败";
  };
  mysql_query('set names utf8',$this->conn);  
 }
 public static function getInstance(){
  if(is_null(self::$instance)){
   self::$instance = new db;
  }
  return self::$instance;
 }
 /**
  * 查询数据库
  */
 public function select($table,$condition=array(),$field = array()){
  $where='';
  if(!empty($condition)){
   
   foreach($condition as $k=>$v){
    $where.=$k."='".$v."' and ";
   }
   $where='where '.$where .'1=1';
  }
  $fieldstr = '';
  if(!empty($field)){
   
   foreach($field as $k=>$v){
    $fieldstr.= $v.',';
   }
    $fieldstr = rtrim($fieldstr,',');
  }else{
   $fieldstr = '*';
  }
  self::$sql = "select {$fieldstr} from {$table} {$where}";
  $result=mysql_query(self::$sql,$this->conn);
  $resuleRow = array();
  $i = 0;
  while($row=mysql_fetch_assoc($result)){
   foreach($row as $k=>$v){
    $resuleRow[$i][$k] = $v;
   }
   $i ;
  }
  return $resuleRow;
 }
 /**
  * 添加一条记录
  */
  public function insert($table,$data){
   $values = '';
   $datas = '';
   foreach($data as $k=>$v){
    $values.=$k.',';
    $datas.="'$v'".',';
   }
   $values = rtrim($values,',');
澳门新萄京,   $datas   = rtrim($datas,',');
   self::$sql = "INSERT INTO  {$table} ({$values}) VALUES ({$datas})";
  if(mysql_query(self::$sql)){
   return mysql_insert_id();
  }else{
   return false;
  };
  }
  /**
   * 修改一条记录
   */
 public function update($table,$data,$condition=array()){
  $where='';
  if(!empty($condition)){
   
   foreach($condition as $k=>$v){
    $where.=$k."='".$v."' and ";
   }
   $where='where '.$where .'1=1';
  }
  $updatastr = '';
  if(!empty($data)){
   foreach($data as $k=>$v){
    $updatastr.= $k."='".$v."',";
   }
   $updatastr = 'set '.rtrim($updatastr,',');
  }
  self::$sql = "update {$table} {$updatastr} {$where}";
  return mysql_query(self::$sql);
 }
 /**
  * 删除记录
  */
  public function delete($table,$condition){
   $where='';
  if(!empty($condition)){
   
   foreach($condition as $k=>$v){
    $where.=$k."='".$v."' and ";
   }
   $where='where '.$where .'1=1';
  }
  self::$sql = "delete from {$table} {$where}";
  return mysql_query(self::$sql);
  
  }
 
 public static function getLastSql(){
  echo self::$sql;
 }
 
 
 
}

$db = db::getInstance();
//$list = $db->select('demo',array('name'=>'tom','password'=>'ds'),array

('name','password'));
//echo $db->insert('demo',array('name'=>'最近你啦','password'=>'123'));
//echo $db->update('demo',array("name"=>'xxx',"password"=>'123'),array('id'=>1));
echo $db->delete('demo',array('id'=>'2'));
db::getLastSql();
echo "<pre>";
?>

       php中有很多的设计模式,其中的单例模式是我们写代码的时候较为常用的一种模式,它不但能

够有效的减少new操作的资源消耗,而且能够很方便的对某些全局配置信息进行控制!希望大家在php学

习中深刻理解单例模式的应用。

本文由澳门新萄京发布于www.澳门新萄京赌场,转载请注明出处:php单例格局完结_php功底_脚本之家,PHP单例情势学

上一篇:澳门新萄京有关phpmailer的详细介绍及使用方法, 下一篇:没有了
猜你喜欢
热门排行
精彩图文