2011-02-14 39 views
0

我想创建我自己的一种轻量级的OOP方式来跟踪加载的文件及其相应版本(尚未实现)在我的PHP框架中,以便能够轻松测试将来的依赖性问题。创建单身 - 这真的是对的吗?

这里是我当前的代码,但作为一个总的初来乍到OOP和模式,我不能确定我是否已经完成了正确的单身与否:

class loadRegistry { 

    private static $registry = null; 

    private function __construct(){ 

     if (is_null(self::$registry)); 
     self::$registry = array(); 

    } 

    public static function get() { 
     return self::$registry; 
    } 

    public static function set($filename){ 

     if (isSet(self::$registry[$filename]) AND !empty($filename)) { 
      throw new Exception("File already loaded"); 
     } 
     else self::$registry[$filename] = ''; 
    } 

} 

loadRegistry::set('filename'); 
loadRegistry::set('filename2'); 

$reg = loadRegistry::get(); 
+0

这不是一个单身人士。我不确定它试图成为什么......它几乎看起来像一个抽象工厂,但我看不到对象在哪里处理。更何况你可以只做'private static $ registry = array()`并保存is_null检查...并且你没有办法实例化它,所以没有任何注册表...... – ircmaxell 2011-02-14 22:23:56

+4

你可能想要读取[静态方法vs单例:不选择](http://www.phparch.com/2010/03/static-methods-vs-singletons-choose-neither/)。 – 2011-02-14 22:26:28

+1

*(相关)* [为什么单身人士在PHP中没有用处](http://gooh.posterous.com/singletons-in-php)是我对[谁需要单身人士]的答案的更长版本(http:// stackoverflow.com/questions/4595964/who-needs-singletons/4596323#4596323) – Gordon 2011-02-14 22:38:10

回答

2

不,它不是单例。你实际上只是在玩静态属性。一个单身会更喜欢这样的:

class Registry { 

    private static $registry = null; 
    private $data; 

    private function __construct(){ 
     $this->data = array(); 
    } 

    public static function getInstance() { 
     if (is_null(self::$registry)) { 
      self::$registry = new Registry(); 
     } 
     return self::$registry; 
    } 

    public function set($filename){ 
     if (isset($this->data[$filename]) && !empty($filename)) { 
      throw new Exception("File already loaded"); 
     } 
     else { 
      $this->data[$filename] = ''; 
     } 
    } 

    // further **instance** methods 
} 

$reg = Registry::getInstance(); 
$reg->set('filename'); 
$reg->set('filename2'); 

我不知道你是否可以设置构造函数在PHP私人...我不这么认为。

静态类$和一个单间的差异。单例允许一次只有一个实例。对于静态类,你甚至不需要一个实例。另外,静态属性在类的所有实例之间共享(在你创建实例的情况下)。

如果您不需要实例来保存某些状态,通常会使用静态类。

$:没有真正的静态类。只有成员可以被定义为静态。我想说一个只有静态成员的类可以被称为静态类。

1

这段代码看起来很奇怪 - 首先,构造函数永远不会被任何内部函数调用,因为它是私有的,所以不能在外部调用。这不是一个单身人士,因为单身人士实际上是要作为一个物体来创造,而这个阶级从来就不是。

但是,您可以使用这样的代码来创建划分的全局存储,如果这是您想要做的。

下面是你单身:

class Singleton { 
    private static $me; 

    private function __construct 
    { 
     /* something */ 
    } 

    public static getInstance() 
    { 
     if(empty(self::$me)) self::$me = new self; 
     return self::$me; 
    } 

}

这里的改进5.3+单:

class Singleton { 
    private static $me; 

    private function __construct 
    { 
     /* something */ 
    } 

    public static getInstance() 
    { 
     if(empty(self::$me)) self::$me = new static; 
     return self::$me; 
    } 

}

2

你提出什么上面不继单身的模式。一个Singleton只允许一个类的单个实例同时存在(与定义一个Static对象不同,它不会阻止你从同一时间创建其他对象并将它们混合起来)。

您可以在官方手册中阅读PHP中的Singleton模式; http://php.net/manual/en/language.oop5.patterns.php

上面的手册示例给出了一个准系统示例,但从PHP5发布以来,我从来没有真正需要在PHP中使用Singleton。它们对iPhone等设备更有用,因为您只需要一个指定的硬件接口 - 比如屏幕。不过,我想你可能会用它在你的数据库连接中的一个PHP应用程序...

0

我看到这是有点旧..但是..

我以前只是为了单实例而使用单例,但是在注册表中你不再需要静态。 另一方面是如何实施和使用注册管理机构,以确定注册管理机构解决方案是否良好。

因为我使用MVC,只需要为基础控制器传递一次注册表,一次为基础模型传递注册表,这就是全部。另一方面,如果有一个设计需要经常传递注册表对象,它可能不是一个好主意。

的基本思路是:

  1. 有一个注册表

  2. 在非常begining仅创建数据库类的实例,这样一来我们不创建连接等烦。我使用了两个数据库,直到veri第一次我需要它时才创建连接。

    $ registry-> dbManager = new dbManager();

  3. 将注册表对象传递给路由器,控制器和模型基类注册表无处不在。
    $ registry = My_Registry :: singleton(); $ registry-> router = new router($ registry); $ registry-> dbManager = new dbManager(); 等..................

  4. DB类撑正常类,这仅仅是从DB类

    类dbManager {

    的一部分
    //DB Connections 
    private $Internal_db_con = null; 
    private $Business_db_con = null; 
    
    //DB Connection Parameters 
    private $host=null; 
    private $user=null; 
    private $pass=null; 
    
    //DB Names 
    private $internal_db_name=null; 
    private $business_db_name=null;  
    
    // 
    private $result = null; 
    
    
    
    // only one object created 
    public function __construct() 
    { 
         include_once __SITE_PATH . 'includes/db_config.inc'; 
    

    list($ this-> host,$ this-> user,$ this-> pass,$ this-> internal_db_name,$ this-> business_db_name)= $ db_conf;

    } 
    
    
    
    
    //set internal database connection 
    private function setInternalDBCon() 
    { debug('setInternalDBCon called'); 
          try{  
           # MySQL with PDO_MYSQL 
           $dbq="\""; 
           $this->Internal_db_con = new 
    

    PDO( “MySQL的:主机=”。$这个 - >主机 “; DBNAME =” $这 - > internal_db_name,$这 - >用户,$这 - >通, 阵列(PDO :: MYSQL_ATTR_INIT_COMMAND =>“SET NAMES utf8”));

    $this->Internal_db_con->setAttribute (PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
           } 
          catch(PDOException $e) 
          { 
          echo 'Error connecting to MySQL: ' .$e->getMessage(); 
          }  
    
    } 
    
    
    
    
    
    
    //set business database connection 
    public function setBusinessDBCon() 
    { 
          try{  
          # MySQL with PDO_MYSQL 
          $dbq="\""; 
          $this->Business_db_con = new 
    

    PDO( “MySQL的:主机=”。$这个 - >主机 “; DBNAME =” $这 - > internal_db_name,$这 - >用户,$这 - >通, 阵列(PDO :: MYSQL_ATTR_INIT_COMMAND =>“SET NAMES utf8”));

    $ this-> Business_db_con-> setAttribute(PDO :: ATTR_ERRMODE,PDO :: ERRMODE_EXCEPTION); }
    catch(PDOException $ e) {
    echo'连接到MySQL的错误:'。$ e-> getMessage();
    }

    } 
    
    
    
    
    
    
    /*check if a row exists in a safe way that avoids sql atack*/ 
    public function uniqueRowExists($dbcon, $table,$col_name, $data) 
    {  
         //check if connection is set 
         if($this->{$dbcon.'_db_con'}==null) //dynamic variable call 
        $this->callMyFunc('set'.$dbcon.'DBCon'); //dynamic function call 
    

    .......................等....

     //prepare 
         $stmt = $this->{$dbcon.'_db_con'}->prepare($sql); 
        $stmt->execute($data); 
    

    ..... ............等

  5. 这是我如何调用一个公共职能从DB类

    //查询数据库
    $结果= $这个 - >登记处送交> dbManager-> uniqueRowExists ( '内部',“ internal_user',Array('uname','pass'),$ input); //连接到来自表,coloumns,阵列数据选择搜索

这种方式只有一个实例的任何地方。