【问题标题】:When is called private constructor in PHP5 class?什么时候在 PHP5 类中调用私有构造函数?
【发布时间】:2013-10-31 09:50:52
【问题描述】:

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

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

class SillyDB
{
  private function __construct()
  {

  }

  public static function getConnection()
  {

  }
}

除了我在做一个

new SillyDB() 

在类本身内部调用?

为什么允许我从内部实例化 SillyDB?

【问题讨论】:

标签: php oop


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    __construct() 只有在您从包含私有构造函数的类的静态方法中调用它时才会被调用。所以对于你的 Singleton,你可能有这样的方法:

    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 进行数据库连接可确保您的应用程序一次不会建立大量数据库连接。

    【讨论】:

      【解决方案3】:

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

      $obj = new SillyDB();
      

      会导致错误。

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

      手册中的这条石头旧评论描述得很好:http://www.php.net/manual/de/language.oop5.decon.php#80314

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

      【讨论】:

        【解决方案4】:

        是否有任何情况下会调用 __construct() 在类本身内部调用new SillyDB()

        没有。

        为什么允许我从内部实例化SillyDB

        为什么不允许你这样做?

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

        【讨论】:

          【解决方案5】:

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

          class SillyDB
          {
            private function __construct()
            {
              $db->connect();
            }
          
            public static function getConnection()
            {
              self::__construct();
            }
          }
          

          跑步

          SillyDB::getConnection()
          

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

          【讨论】:

            猜你喜欢
            • 2010-09-06
            • 2019-10-16
            • 1970-01-01
            • 2013-01-20
            • 2013-06-21
            相关资源
            最近更新 更多