В классе PHP5, когда вызывает вызов частного конструктора? - программирование
Подтвердить что ты не робот

В классе PHP5, когда вызывает вызов частного конструктора?

Скажем, я пишу класс PHP ( >= 5.0), который должен быть синглом. Все прочитанные документы, чтобы сделать конструктор класса закрытым, чтобы класс не мог быть непосредственно создан.

Итак, если у меня есть что-то вроде этого:

class SillyDB
{
  private function __construct()
  {

  }

  public static function getConnection()
  {

  }
}

Существуют ли случаи, когда __construct() вызывается иначе, чем если я делаю

new SillyDB() 

вызов внутри самого класса?

И почему мне разрешено создавать экземпляр SillyDB внутри себя?

4b9b3361

Ответ 1

__construct() будет вызываться только если вы вызвали его из метода для класса, содержащего частный конструктор. Итак, для вашего Singleton у вас может быть такой способ:

class DBConnection
{
   private static $Connection = null;

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

   private function __construct()
   {

   }
}

$dbConnection = DBConnection::getConnection();

Причина, по которой вы/хотите создать экземпляр класса внутри себя, заключается в том, что вы можете проверить, чтобы в любой момент времени существовал только один экземпляр. В конце концов, это цель Синглтона. Использование Singleton для подключения к базе данных гарантирует, что ваше приложение не делает тонны соединений DB за раз.

Ответ 2

Здесь очень простой синглтон, который просто генерирует строку даты/времени:

class TheDate
{
    private static $DateInstance = null;
    private $dateVal;

    public static function getDateInstance()
    {
        if(!isset(self::$DateInstance))
        {
            self::$DateInstance = new TheDate();
        }

        return self::$DateInstance;
    }

    public static function getDateVal()
    {
        return self::$DateInstance->dateVal;
    }

    private function __construct()
    {
        $this->dateVal = strftime("%Y-%m-%d %H:%M:%S");
    }
}

Выполнение чего-то подобного, очевидно, дает мне одну и ту же дату снова и снова:

$date1 = TheDate::getDateInstance();
echo $date1->getDateVal() . "<br />";

$date2 = TheDate::getDateInstance();
echo $date2->getDateVal() . "<br />";

И это не вызывает ошибок:

class NewDate extends TheDate
{
    public function __construct()
    {

    }
}

Ответ 3

Хорошо, я провел несколько тестов самостоятельно.

  • Если вы не объявляете свой собственный конструктор в подклассе, попытка его создания вызовет фатальную ошибку, потому что он пытается вызвать конструктор суперкласса.
  • В случае соединения с БД, когда вы предположительно возвращаете (в PHP, так или иначе) экземпляр mysqli или ресурс, возвращаемый функцией mysql_connect() (или некоторая другая ссылка на некоторые другие СУБД), до тех пор, пока вы помещаете экземпляр private, нет угрозы кому-то подклассифицировать его и подделывать ссылку.
  • Как я уже упоминал ранее, если кто-то действительно хочет переопределить ваше поведение и сделать несколько подключений, они могли бы также сделать это, написав новый класс.

Ответ 4

Проверьте код, Марк, и дайте мне знать, что вы узнали.

EDIT: Кроме того, в этой конкретной ситуации я не уверен, почему вам нужно будет беспокоиться о том, чтобы предотвратить подкласс людей. Если у кого-то есть доступ к вашему PHP-коду для подкласса, то у них также есть доступ к вашему коду, чтобы скопировать его и изменить модификаторы доступа на то, что они (по какой-либо причине) находят подходящим.

Практическая полезность Singleton в этом случае заключается в том, что, используя это, вы можете гарантировать, что вы всегда используете одно и то же соединение с базой данных для данного HTTP-запроса. Он это выполняет. Другой материал (используя final и частные конструкторы) полезен для понимания с точки зрения теории и еще более полезно знать, хотите ли вы распространять код качества API другим программистам, но в случае этого конкретного примера все ключевые слова делают добавление байтов в размер вашего класса.

Ответ 5

Небольшая выборка: для полноты вы, вероятно, объявите класс окончательным, так как вы не хотите, чтобы кто-то подклассифицировал этот класс и реализовал свой собственный публичный конструктор.

(Простите меня, если компилятор ловит переопределение частного конструктора, но я не думаю, что это делает)