Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
singleton (РНР)
|
|||
|---|---|---|---|
|
#18+
Добрый (день/вечер или что там у вас)! тут http://www.sql.ru/forum/actualutils.aspx?action=gotomsg&tid=683298&msg=7471609 рассказано было про синглтов в контексте сохранения коннекта к бд. Т.е. коннект, ежели верить доке, все равно с окончанием работы скрипта закроется... Собственно не понятен момент границ этого самого "окончания скрипта". объясню на примере: у меня , предположим, есть сингл тон с той же целью - подключение к БД. допустим мест , где я могу обратится к базе - три. 1) выбрать все данные с таблицы 2) выбрать данные по конкретному ид 3) обновить данные по конкретному ид. ну и на каждые из трех в своем месте есть определенное обращение к БД. то есть : 1) вызываю singlton::getinstance(); 2) закидываю текст запроса 3) забираю ответ 4) "отдаю" объект ? что мне не понятно: 1) состояние класса. например в одном месте я уже взял объект - в нем запрос(1) лежит. не может ли получится конкуренция за ресурс между потоками, ну если в другом месте я только пытаюсь взять объект. - т.е. не получу ли я вместо готового к запросу объекта что-то" наоборот "? т.е. нужно ли делать типа защиты , например флаг -"объект занят" - включать перед заходом выключать после - или пхп исключает подобное в рамках сессии? 2) если сингл тон у меня в отдельном файле. и я делаю include_once; теперь он - класс - подгружен. но если каждый из запросов у меня в разных файлах - как они расцениваются системой? это до окончания скрипта? или после? т.е. если я не юзаю mysql_pconnect() - все равно при КАЖДОМ обращении от клиента к серверу (включая аякс) идет создание нового подключения к БД? т.е. "спасет" меня только от ситуации типа : один файл: 1 коннект 2 запрос 3 обработка 4 закрыл 5 коннект 6 запрос 7 обработка 8 закрыл с использованием синглтона станет: один файл: 1 сингл тон - вызов 2 коннект приватный при создании метод в __construct() 3 запрос 4 обработка 5 сингл тон - вместо коннект - отдает созданное в п.2 подключение 6 запрос 7 обработка 8 закрыл (т.е. кончился скрипт, грохнулись объекты, привязанные к скрипту, и при высвобождении ресурсов убился коннект внутри сингл тона). Спасибо. п.с. если есть че почитать по этой теме заранее спасибо за ссылки. п.п.с. проясняю для себя туманные моменты - т.к. "один раз сработало" и "проблемное место, которое может выстрелить" - это две разные ситуации, которые нередко бывают одним и тем же участком кода пока сам на тестовом сервере "у нас все работает". ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.06.2014, 12:34 |
|
||
|
singleton (РНР)
|
|||
|---|---|---|---|
|
#18+
ScareCrowphp однопоточный. спасибо. в случае iis сервера - тоже? пока что из доки , что успел нарыть : от запроса юзера (вбил в браузере url) до вывода из буффера (т.е. типа "дорисовали" или встретили die) - и есть время работы скрипта. т.е. как вывод окончен - все объекты убиты. включая классы и т.д. что может пережить: сессии - т.к. их могут сериализовать в файл - и оттуда востановить при новом подключении/ хттп запросе ну и исключение - если есть параметр , который разрешает не рубить скрипт если соединение с браузером потеряно, и расширяет таймаут. правда как тогда будет организована работа - не совсем понимаю. ну например при коннекте с другой вкладки... у меня как-то была задача по парсу очень большого XML который закидывал юзер. т.е. вывод вроде как осуществлялся - там делал типа дебага и поэтапно плевался данными о прогрессе - но скрипт умирал по таймауту. ну вроде бы проясняется, спасибо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.06.2014, 15:44 |
|
||
|
singleton (РНР)
|
|||
|---|---|---|---|
|
#18+
Judeв случае iis сервера - тоже? да обычный способ существования - пул fastcgi ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.06.2014, 15:49 |
|
||
|
singleton (РНР)
|
|||
|---|---|---|---|
|
#18+
Jude, Мне кажется структура понята не совсем верно :) Что значит "взять объект" и "отдать объект"? Мы просто запоминаем указатель (ссылку) на объект, а он остаётся там же где и был... А сам объект - это по большому счёту некий ресурс, который является прослойкой между клиентом и сервером mysql. Какой-нить конфликт может возникнуть при одновременном обращении к ресурсу... Но для каждого экземпляра скрипта (учитывая что php однопоточный по сути), ресурс будет отдельный... Потому конфликты по сути невозможны (а в пределах сервера при одновременном обращении - это уже забота самого сервера и он в этом плане всё делает сам). Так что я например не вижу никаких видимых помех при работе с singleton-ами :) Кроме как неочевидность того, создался ли объект или вернулся просто его указатель... Не помню точно, но где-то я об этом читал, что иногда бывают трудности из-за такого непрозрачного поведения (хотя сам ниразу не сталкивался :) ) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.06.2014, 10:32 |
|
||
|
singleton (РНР)
|
|||
|---|---|---|---|
|
#18+
Jude, тото меня удивило - целая куча умных вопросов, и совсем не целая и не куча понимания работы пхп. зашол в профиль - а там 79% в ветке delphi. :) вообще есть среда иде для пхп. и там можно будет дебажить код, выполнять пошагово. а вообще пхп скрипт, это как экзе файл - запуск даже тогоже из соседней вкладки - это уже совсем отдельная история. ======== постоянные соединения - речь шла о том чтобы за время работы одного скрипта (включая подключённые файлы - это как если ихний код скопировать в место подключения) не создавались лишние подключения. и сдесь дело даже не в том что на подключение новое время надо, а в том что на базе лимит стоит всегда на число подключений, вот чтобы не выбирать этот лимит раньше времени. ======= в пхп есть понятие постояных подключений - это когда подключение после работы скрипта не закрываеться, а остаёться и другой скрипт который запросит подключение с темиже параметрами - получит то, что осталось от предыдущего скрипта. но если использовать только это, встаёт естественный вопрос - а как в коде узнать есть подключение или нет. по существу если, то синглтоном можно и не запоминать подключение, главное его октрыть при первом запросе, а потом функция квери сама по умолчанию использует последнее открытое. но - а если завтра надо будет два подключения - к двум различным базам мускла...поэтому и лучше синглтон, точнее его модификация - аля мультитон (задаем тип подключения - DB_Connection::instance('server1'); Код: php 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. предполагаем что метод гет_коннекшин сам вызывает исключение, если подключиться не удалось или както там разруливае ситуацию с подключением. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.06.2014, 18:17 |
|
||
|
singleton (РНР)
|
|||
|---|---|---|---|
|
#18+
ПрограмёрJude, Мне кажется структура понята не совсем верно :) Что значит "взять объект" и "отдать объект"? Мы просто запоминаем указатель (ссылку) на объект, а он остаётся там же где и был... А сам объект - это по большому счёту некий ресурс, который является прослойкой между клиентом и сервером mysql. Какой-нить конфликт может возникнуть при одновременном обращении к ресурсу... Но для каждого экземпляра скрипта (учитывая что php однопоточный по сути), ресурс будет отдельный... Потому конфликты по сути невозможны (а в пределах сервера при одновременном обращении - это уже забота самого сервера и он в этом плане всё делает сам). Так что я например не вижу никаких видимых помех при работе с singleton-ами :) Кроме как неочевидность того, создался ли объект или вернулся просто его указатель... Не помню точно, но где-то я об этом читал, что иногда бывают трудности из-за такого непрозрачного поведения (хотя сам ниразу не сталкивался :) ) гурята пхп скажут, что синглтон отстой, потому что он не покрываеться юниттестами хорошо :) чтото ты напутал - идея синглтона в том, что обьект должен быть один...грубо говоря сдесь ещо и отложенная инициализация просматриваеться. по сути можешь щитать что этот обьект существует всегда, он никогда не создаёться, всегда возвращаеться ссылка, реально, создаться он при первом вызове, и не изза того что он синглтон, а изза ипользования отложеной инициализации. :) что вообщемто подчеркиваеться класической реализацией. Код: php 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2014, 12:24 |
|
||
|
singleton (РНР)
|
|||
|---|---|---|---|
|
#18+
alex564657498765453скажут, что синглтон отстой, потому что он не покрываеться юниттестами хорошо :) зависит от способа инстанцирования. В случае использования DI контейнера - проблем нет ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2014, 12:34 |
|
||
|
singleton (РНР)
|
|||
|---|---|---|---|
|
#18+
alex564657498765453, ну... у меня то вообще ничего из вышесказанного сложностей не вызывает. Как мы помним, очень плохим тоном является как в процедурном, так и в ОО программировании менять или использовать внутри метода то, что в него явно не передавалось как аргумент (ну то есть глобальные переменные в локальной области видимости - это зло). Отсюда прослеживается мысль, что создав статический метод класса, который будет возвращать сущность соединения (ресурс), мы нарушаем это правило, так как любой другой объект использующий этот метод становится неявно зависим от существования того самого класса и его метода. А ещё... Сам ресурс является меняемым.. то есть мы можем сменить активную db :) и все кто запросит данную инстанцию получат не то, что ожидали... Так что классическая реализация хромает в основном из-за возможности менять соответствующий объект (второстепенно из-за зависимости от наличия класса-синглтона) :) Как вариант, у mysql соединения например не так уж много разных возможных состояний/параметром (сервер, пользователь, база данных, выполнение транзакции, флаг autocommit). При том выполнение транзакции можно упустить, если прийти к договорённости, что транзакция никогда не будет начата напрямую, а только через изменения соответствующего флага объекта. Так вот, идеальный случай, это обязательный список аргументов getInstance: host, user, base, autoCommit, которые выставят соответствующие параметры соединения. Но опять же требуется явное соглашение, что нельзя выполнять непосредственно запросы типа "USE db" или "SET AUTOCOMMIT=0". При этом синглтон должен стать не статическим, а динамическим объектом и передаваться конечному объекту через конструктор (как необязательный параметр, если он не был передан, то стоит считать, что система в которой объявлен класс, реализовывает другим образом обращение к базе, и потому на сам объект возлагается задача создания под себя соединения, или вываливание ошибкой). Итак, для нормальной работы и структуры предлагаю в классическую реализацию внести такие изменения: 1. Не статический метод getInstance 2. getInstance получает на вход все данные о состоянии требуемого ресурса. (при том часть из них может иметь некое умолчание, в случае, если аргумент не был передан). Вообще я вижу это в виде уже привычной всем строки типа: "mysql://user@host:port/db?[nocommit]". В случае если у объекта в копилке нету подходящего ресурса - он создаётся. 3. Объект использующий singleton получает в конструкторе соответствующий объект, и в случае если не получил его - создаёт под себя соединение своими силами или вываливается исключением При том соблюдается соглашение, что состояние соединения не меняется напрямую в обход соответствующего этому соединению объекта. В таком виде я понимаю идеальную структуру работы с базой. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2014, 13:32 |
|
||
|
singleton (РНР)
|
|||
|---|---|---|---|
|
#18+
автор Не статический метод getInstance ты сделал мой день. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2014, 15:05 |
|
||
|
singleton (РНР)
|
|||
|---|---|---|---|
|
#18+
ScareCrowавтор Не статический метод getInstance ты сделал мой день. А что не так? Не нравится название? ну пускай будет getResource. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2014, 16:56 |
|
||
|
singleton (РНР)
|
|||
|---|---|---|---|
|
#18+
Програмёр, Открыл тему, понял что очередной велосипед о коннектах к базе..)) Вопрос - зачем? Уже сказали, PHP однопоточный. Оперировать коннектами вы может в рамках одного потока. Можете только настроить постоянные соединения, где сам процесс PHP будет вам давать открытые конекты к базе, если такого есть. Это если это какой то FPM или его разновидность. Все остальное, это велосипеды который порождают велосипеды. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.06.2014, 14:00 |
|
||
|
|

start [/forum/topic.php?fid=23&tid=1462663]: |
0ms |
get settings: |
11ms |
get forum list: |
18ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
50ms |
get topic data: |
11ms |
get forum data: |
2ms |
get page messages: |
68ms |
get tp. blocked users: |
2ms |
| others: | 255ms |
| total: | 425ms |

| 0 / 0 |
