2

假设我正在编写一个旨在成为单例的 PHP (>= 5.0) 类。我读过的所有文档都说要使类构造函数私有,因此不能直接实例化该类。

所以,如果我有这样的事情:

class SillyDB
{
  private function __construct()
  {

  }

  public static function getConnection()
  {

  }
}

除了我在做一个

new SillyDB() 

在类本身内部调用?

为什么我完全可以从内部实例化 SillyDB?

4

5 回答 5

3

私有构造函数确保您不能在其自身之外实例化此类。
所以打电话

$obj = new SillyDB();

会导致错误。

这种技术通常在创建单例类时使用。

手册中的这条古老的评论很好地描述了它:http ://www.php.net/manual/de/language.oop5.decon.php#80314

您在类中有一个静态方法,该方法管理可以通过该方法检索的类的单个实例。

于 2013-10-22T13:35:19.393 回答
2

在该类中调用静态函数可以从该类中运行构造。

class SillyDB
{
  private function __construct()
  {
    $db->connect();
  }

  public static function getConnection()
  {
    self::__construct();
  }
}

跑步

SillyDB::getConnection()

将运行 __construct() 方法并将您连接到数据库

于 2013-10-22T13:34:54.727 回答
1

__construct()除了我在new SillyDB()类本身内部进行调用之外,是否还有其他调用的情况?

不。

为什么我完全可以SillyDB从内部实例化?

为什么不允许你这样做?

更好的问题是它对于只能从自己的类内部调用的构造函数有什么用?. 当您想要确保完全控制实例的创建方式时,这很有用,例如当您实现单例时。

于 2013-10-22T13:35:02.140 回答
0

__construct()仅当您从包含私有构造函数的类的静态方法中调用它时才会调用它。所以对于你的单身人士,你可能有这样的方法:

class DBConnection
{
   private static $Connection = null;

   public static function getConnection()
   {
      if(!isset(DBConnection::$Connection))
      {
         DBConnection::$Connection = new DBConnection();
      }
      return DBConnection::$Connection;
   }

   private function __construct()
   {

   }
}

$dbConnection = DBConnection::getConnection();

您能够/想要从内部实例化类的原因是您可以检查以确保在任何给定时间仅存在一个实例。毕竟,这就是 Singleton 的全部意义所在。使用 Singleton 进行数据库连接可确保您的应用程序一次不会进行大量数据库连接。

于 2013-10-22T13:35:04.603 回答
0

您可以调用它,因为范围是基于类而不是实例检查的(即对象能够毫无问题地访问同一类的另一个实例的私有和受保护方法/属性)

于 2013-10-22T13:37:23.927 回答