Как зайти в Даркнет?!
25th January, 01:11
6
0
Как в tkinter из поля ввода Entry получить значение в одну переменную и обновить строку кнопкой, затем получить ещё одно введённое значение и затем сложить их. Ниже пример кода
21st July, 19:00
894
0
Программа, которая создает фейковые сервера в поиске игровых серверов CS 1.6 Steam
21st March, 17:43
948
0
Очень долго работает Update запрос Oracle
27th January, 09:58
914
0
не могу запустить сервер на tomcat HTTP Status 404 – Not Found
21st January, 18:02
905
0
Где можно найти фрилансера для выполнения поступающих задач, на постоянной основе?
2nd December, 09:48
938
0
Разработка мобильной кроссплатформенной военной игры
16th July, 17:57
1724
0
период по дням
25th October, 10:44
3955
0
Пишу скрипты для BAS только на запросах
16th September, 02:42
3720
0
Некорректный скрипт для закрытия блока
14th April, 18:33
4613
0
прокидывать exception в блоках try-catch JAVA
11th March, 21:11
4381
0
Помогите пожалуйста решить задачи
24th November, 23:53
6086
0
Не понимаю почему не открывается детальное описание продукта
11th November, 11:51
4350
0
Нужно решить задачу по программированию на массивы
27th October, 18:01
4396
0
Метода Крамера С++
23rd October, 11:55
4309
0
помогите решить задачу на C++
22nd October, 17:31
4002
0
Помогите решить задачу на python с codeforces
22nd October, 11:11
4492
0
Python с нуля: полное руководство для начинающих
18th June, 13:58
2599
0
Когда в классе PHP5 вызывается частный конструктор?
Допустим, я пишу класс PHP (>= 5.0), который должен быть singleton. Все документы, которые я читал, говорят о том, чтобы сделать конструктор класса закрытым, чтобы класс не мог быть непосредственно создан.
Так что если у меня есть что-то вроде этого:
class SillyDB
{
private function __construct()
{
}
public static function getConnection()
{
}
}
Есть ли случаи, когда __construct() вызывается иначе, чем если я делаю a
new SillyDB()
позвонить внутрь самого класса?
И почему мне вообще позволено создавать экземпляр SillyDB изнутри самого себя?
__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();
Причина, по которой вы можете/хотели бы создать экземпляр класса из самого себя, заключается в том, что вы можете проверить, существует ли только один экземпляр в любой момент времени. В конце концов, в этом и заключается весь смысл a Singleton. Использование Singleton для подключения к базе данных гарантирует, что ваше приложение не создает тонны соединений DB одновременно.
Edit: добавлено $, как предложено @emanuele-del-grande
Вот очень простой singleton, который просто генерирует строку даты / времени:
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()
{
}
}
Ладно, я сам провел несколько тестов.
- Если вы не объявите свой собственный конструктор в подклассе, попытка создать его экземпляр приведет к фатальной ошибке, потому что он пытается вызвать конструктор суперкласса.
- В случае соединения DB, когда вы предположительно возвращаете (во всяком случае, в PHP) экземпляр mysqli или ресурс, возвращаемый функцией
mysql_connect()(или какой-то другой ссылкой на какой-то другой RDBMS), пока вы отмечаете экземпляр private, нет никакой угрозы того, что кто-то подклассирует его и подделает ссылку. - Как я уже упоминал ранее, если кто-то действительно хочет переопределить ваше поведение и создать несколько соединений, он может также сделать это, написав новый класс.
Проверьте код, Марк, и дайте мне знать, что вы узнаете.
EDIT: кроме того, в этой конкретной ситуации я не уверен, почему вам нужно было бы беспокоиться о том, чтобы не допустить человека к подклассу. Если у кого-то есть доступ к вашему коду PHP, чтобы подклассировать его, то у них также есть доступ к вашему коду, чтобы скопировать его и изменить модификаторы доступа на то, что они (по какой-либо причине) считают подходящим.
Практическая польза Singleton в этом случае заключается в том, что с его помощью вы можете гарантировать, что всегда используете одно и то же подключение к базе данных для данного запроса HTTP. Оно это и делает. Другие вещи (использование final и частных конструкторов) полезно знать с точки зрения теории, и еще более полезно знать, если вы хотите распространять код API-качества другим программистам, но в данном конкретном примере все ключевые слова делают это добавление байтов к размеру файла вашего класса.
Немного придирчивости: для полноты вы, вероятно, объявите класс как окончательный , так как вы не хотите, чтобы кто-то подклассовал этот класс и реализовал его собственный открытый конструктор.
(Простите меня, если компилятор поймает переопределение частного конструктора, но я не думаю, что это так)