澳门新葡萄京官网首页控制 PHP 类的实例化次数!

控制 php
类的实例化次数!为了保证服务器资源的有效利用,而且一个类比方说模板啊,数据库什么的,在一个页面内只需要实例化一次!也就是在内存中只运行一个实例!那么为了避免重复实例化,那么控制
php
类的实例化次数,是很有必要的!方法其实很简单:就是给类一个外部接口,私有化(private)构造函数,抛弃可以在类外部使用new实例化该类的方法!以下,就是我给出的一个例子,相信大家一看就明白了!(
PHP5 以上版本! )

单例类:

1.单例模式(职责模式):

?phpclass test{ const name = ”test”; public static $havenew = false;
public $name = ”我被限制为只能实例化一次了!”; private function
__construct(){ } function __destruct(){ self::$havenew = false; }
public function inter(){ if(self::$havenew){ echo ”类 ”.self::name.”
已被实例化!”; return NULL; }else{ self::$havenew = true; return new
self; } }}$class1 = test::inter();var_dump($class1);echo ”br
/”;$class2 = test::inter();var_dump($class2);?

1.构造函数需要标记为private,单例类不能再其他类中实例化,只能被其自身实例化
    2.拥有一个保存类的实例静态成员变量
   
3.拥有一个访问这个实例的公共的静态方法。[常用getInstance()方法进行实例化单例类,通过instanceof操作符可以检测到此类是否已经被实例化]
    注:需要创建__clone()方法防治对象被复制

简单的说,一个对象(在学习设计模式之前,需要比较了解面向对象思想)只负责一个特定的任务;

这里都是实例通过test里inter()这个方法实例化对象的!因为构造本身不可以直接访问,所以也不存在可以使用new
来实例化!

作用:
   
1.php的应用主要用于数据库,所以一个应用中会存在大量的数据库操作,使用单例模式,则可以避免大量new操作消耗的资源
   
2.如果系统中需要一个类来全局控制某些配置信息,那么使用单例模式可以很方便的实现。参照ZF的FrontController部分
   
3.在一个页面请求汇总,便于进行调试,因为所有的代码都集中在一个类中,我们可以在类中设置钩子,输出日志,从而避免到处var_dump,echo。

单例类:

php单例模式的例子。

1、构造函数需要标记为private(访问控制:防止外部代码使用new操作符创建对象),单例类不能在其他类中实例化,只能被其自身实例化;

 代码如下

2、拥有一个保存类的实例的静态成员变量

 
<?php
/**
 * 单例模式

3、拥有一个访问这个实例的公共的静态方法(常用getInstance()方法进行实例化单例类,通过instanceof操作符可以检测到类是否已经被实例化)

*/
class DanLi{
    //静态成员变量
    private static $_instance;
    //私有的构造方法
    private function __construct(){
    }
    //防止对象被克隆
    public function __clone(){
        trigger_error(‘Clone is not allow!’,E_USER_ERROR);
    }
    public static function getInstance(){
        if(!(self::$_instance instanceof self)){
            self::$_instance = new self;
        }
        return self::$_instance;
    }
    public function test(){
        echo “ok”;
    }
}
 
//错误:$danli = new DanLi(); $danli_clone = clone $danli;
//正确:$danli = DanLi::getInstance(); $danli->test();
?>

另外,需要创建__clone()方法防止对象被复制(克隆)

 
下面我们讨论下为什么要使用PHP单例模式?

使用PHP单例模式的有点:

多数人都是从单例模式的字面上的意思来理解它的用途,
认为这是对系统资源的节省, 可以避免重复实例化, 是一种”计划生育”.  
而PHP每次执行完页面都是会从内存中清理掉所有的资源.
因而PHP中的单例实际每次运行都是需要重新实例化的,
这样就失去了单例重复实例化的意义了. 单单从这个方面来说,
PHP的单例的确有点让各位失望. 但是单例仅仅只有这个功能和应用吗?
答案是否定的,我们一起来看看。

1、php的应用主要在于数据库应用, 所以一个应用中会存在大量的数据库操作, 使用单例模式, 则可以避免大量的new 操作消耗的资源。

  1. php的应用主要在于数据库应用,
    所以一个应用中会存在大量的数据库操作, 在使用面向对象的方式开发时(废话),
    如果使用单例模式, 则可以避免大量的new 操作消耗的资源。

  2. 如果系统中需要有一个类来全局控制某些配置信息,
    那么使用单例模式可以很方便的实现. 这个可以参看zend
    Framework的FrontController部分。

  3. 在一次页面请求中, 便于进行调试,
    因为所有的代码(例如数据库操作类db)都集中在一个类中,
    我们可以在类中设置钩子, 输出日志,从而避免到处var_dump, echo。

2、如果系统中需要有一个类来全局控制某些配置信息, 那么使用单例模式可以很方便的实现. 这个可以参看ZF的FrontController部分。

 代码如下

3、在一次页面请求中, 便于进行调试, 因为所有的代码(例如数据库操作类db)都集中在一个类中, 我们可以在类中设置钩子, 输出日志,从而避免到处var_dump, echo。

<?php

代码展示部分:** **

/**
* 设计模式之单例模式
* $_instance必须声明为静态的私有变量
* 构造函数和析构函数必须声明为私有,防止外部程序new
* 类从而失去单例模式的意义
* getInstance()方法必须设置为公有的,必须调用此方法
* 以返回实例的一个引用
* ::操作符只能访问静态变量和静态函数
* new对象都会消耗内存
* 使用场景:最常用的地方是数据库连接。
* 使用单例模式生成一个对象后,
* 该对象可以被其它众多对象所使用。
*/
class Example
{
//保存例实例在此属性中
private static $_instance;

class Danli {

//构造函数声明为private,防止直接创建对象
private function __construct()
{
echo ‘I am Construceted’;
}

//保存类实例的静态成员变量

//单例方法
public static function singleton()
{
if(!isset(self::$_instance))
{
$c=__CLASS__;
self::$_instance=new $c;
}
return self::$_instance;
}

 private static $_instance;

//阻止用户复制对象实例
public function __clone()
{
trigger_error(‘Clone is not allow’ ,E_USER_ERROR);
}

//private标记的构造方法

function test()
{
echo(“test”);

private function __construct(){

}
}

 echo “test _construct”; 

// 这个写法会出错,因为构造方法被声明为private
$test = new Example;

}

// 下面将得到Example类的单例对象
$test = Example::singleton();
$test->test();

//创建__clone方法防止对象被复制克隆

// 复制对象将导致一个E_USER_ERROR.
$test_clone = clone $test;
?>

public function __clone(){}

//单例方法,用于访问实例的公共的静态方法

public static function getInstance(){

  if(!(self::$_instance instanceof self)){

    self::$_instance = new Danli ();

  }

  return self::$_instance;

}

 

public function test(){

  echo ‘调用方法成功’;

}

}

//用new实例化private标记构造函数的类会报错

$danli = new Danli();

$danli->test(); 

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注