The only proper guide on PDO (eng.)

Фанат

oncle terrible
Команда форума
Родил тут очередное: http://phpdelusions.net/pdo

Очень хотелось бы фидбека от тех кто осилит.
В пeрвую очередь по поводу троллинга с IoC - это приемлемо, или все же дикари, не поймут-с?
Ну и по остальным пунктам, если кому чего интересно.

В основном написано по мотивам баталий с ламерами на Стаковерфлое, плюс всякие личные изыскания.

Перевод планируется, текущая русская версия и половины не охватывает.
Впрочем, объем - отдельная тема, которая меня пугает.
 

fixxxer

К.О.
Партнер клуба
Я смотрю, у тебя это вечная тема. Теперь на английском :)

В пeрвую очередь по поводу троллинга с IoC - это приемлемо, или все же дикари, не поймут-с?
Юмор очевиден. Смешно, кстати :)
 

Absinthe

жожо
Про mysqlnd я бы еще добавил, что они возвращают целочисленные данные как int, а не string, это было для меня неожиданностью (когда тот же код на той же версии PHP на другом сервере выдавал другие результаты).

Note that despite of a widespread delusion, you should never catch errors to report them.
Имхо нужно их все поймать и типизировать (в зависимости от кода ошибки и СУБД). После чего снова выкинуть.
Иначе не обеспечивается абстракция.

И код я советую отформатировать:
Он не в PSR-2
Выравнивание только в половине случаев.
Имена переменных в стиле C: $stmt, $opts.
 

Фанат

oncle terrible
Команда форума
Про mysqlnd я бы еще добавил, что они возвращают целочисленные данные как int, а не string, это было для меня неожиданностью (когда тот же код на той же версии PHP на другом сервере выдавал другие результаты).
О, кстати да, точно. Спасибо, совсем забыл про это написать.

Имхо нужно их все поймать и типизировать (в зависимости от кода ошибки и СУБД). После чего снова выкинуть.
Иначе не обеспечивается абстракция.
Ну, у меня там примерно это и написано, что если ты пишешь враппер и хочешь как-то дополнить.

И код я советую отформатировать:
Он не в PSR-2
Выравнивание только в половине случаев.
Имена переменных в стиле C: $stmt, $opts.
Ага, спасибо, посмотрю.
Код надерган из разных ответов на стаковерфлое , действительно надо привести в порядок.

Только вместо $stmt вряд ли что-то другое - это служебная переменная, именованная практически по соглашению. Делать ее длинной - только тратить место, имхо.
Очень раздражают прилежные рисовальщики, старательно выводящие $queryCountStuffWithSalary = ""; $stmtCountStuffWithSalary...
Сам по себе стейтмент или строка запроса никакого отношения к бизнес-логике не имеют - это или SQL или стейтмент. А вот уже полученный результат - да, надо именовать по всем правилам.
 

AnrDaemon

Продвинутый новичок
Ну, у меня там примерно это и написано
Видимо, не очень очевидно написано?

Очень раздражают прилежные рисовальщики
Плюсадын. Если переменная не используется за пределами текущего экрана, достаточно, если из её названия понятно её назначение. Я вообще почти сплошь использую однобуквенные конструкции ($q/$r) для хранения промежуточных результатов.

Я смотрю, у тебя это вечная тема. Теперь на английском
Не вижу проблемы. Да, я тоже стараюсь всегда переводить свои опусы обратно на русский, но иногда объём просто неподъёмный, и забиваю… Если только не изначально на русском пишу. Что для меня лично сложнее. Но надо, надо себя заставлять. Родной язык надо уважать.

P.S.
Почитаю поже.
Исходник есть/где? Может, помогу с правкой, если будет настроение и время.
 

Вурдалак

Продвинутый новичок
Имхо нужно их все поймать и типизировать (в зависимости от кода ошибки и СУБД). После чего снова выкинуть.
Иначе не обеспечивается абстракция.
Это нужно, если ты пишешь свой DBAL (хотя бы в виде интерфейсов). В противном случае, я особо не вижу кейсов, где тебе это понадобится: исключения базы данных — классические runtime exceptions, которые в @throws указывать не нужно.
 

Фанат

oncle terrible
Команда форума
Это нужно, если ты пишешь свой DBAL (хотя бы в виде интерфейсов). В противном случае, я особо не вижу кейсов, где тебе это понадобится: исключения базы данных — классические runtime exceptions, которые в @throws указывать не нужно.
Золотые слова!
Я тут со стаковерфлоя на реддит переместился, и уже успел знатно посраться как раз по этому поводу.
Реддит, кстати, отличное место для тусоваццо.
 

Фанат

oncle terrible
Команда форума
Я смотрю, у тебя это вечная тема. Теперь на английском :)
Вообще интересно, как оно получилось.
Убегая в ужасе от цунами адовых вопросов по тегу пхп на Стаковерфлое, я огородился в тегах PDO и mysqli.
Поскольку если человек пользовался этими апи, это автоматически означало, что он не совсем дебил.
Но тут пхп тим подложил мне свинью, запретив топлое лампвовое mysql. И поток пошел в мою уютненькую заводь.
В итоге, по результатам двух эпичнейших срачей со скандалами, интригами и расследованиями, я прешил плюнуть и забить.

Но накопленный опыт ответов на тупые вопросы требовал выхода.

Поэтому сначала написал на стаковерфлое тэг-вики по пдо, потом перекатал его на русску, потом переписал обратно на английский, а где-то месяц назад подорвался объять вообще все что я знаю про ПДО.

Юмор очевиден. Смешно, кстати :)
Ну вот в чувстве юмора англоязычного читателя я не уверен. Может метку какую поставить, JK или там /сарказм...
 

Фанат

oncle terrible
Команда форума
Видимо, не очень очевидно написано?
Не, там просто четь дальше прочитать надо :)
Вообще, на реддите меня уже попинали за излишнюю категричность формулировок.
Но тут палка о двух концах. С одной стороны - да, всегда есть исключения.
С другой - есть тупая необразованная масса, которая исключения применяет как правила.
И чтобы донести до неё, надо формулировать предельно однозначно.

Исходник есть/где? Может, помогу с правкой, если будет настроение и время.
Как раз вчера осилил переписать с внуреннего формата пхпфака на маркдаун.
На гитжаб к себе положу наверное, и кину ссылку.
 

fixxxer

К.О.
Партнер клуба
Ну вот в чувстве юмора англоязычного читателя я не уверен. Может метку какую поставить, JK или там /сарказм...
Да нормально все у них с чувством юмора, такие же люди, как и все. Это у тебя, наверное, деформация восприятия после зануд с SO :)
 

Вурдалак

Продвинутый новичок
neither make a "global" try..catch embracing the whole app or module.
Вот это звучит странно, ты имеешь в виду конкретно PDOException или в целом? try..catch глобальный или для отдельного модуля — вполне OK.
 

Фанат

oncle terrible
Команда форума
Вот это звучит странно, ты имеешь в виду конкретно PDOException или в целом? try..catch глобальный или для отдельного модуля — вполне OK.
Глобальный точно не ок - эту функцию должен выполнять хендлер.
А вот для модуля - да. Тут надо подумать.
 

Вурдалак

Продвинутый новичок
Глобальный точно не ок - эту функцию должен выполнять хендлер.
А вот для модуля - да. Тут надо подумать.
Я не согласен. Я бы даже сказал, что хендлер вместо обычного глобального — это как раз костыль.

Обрабатывая исключение, тебе нужно понимать контекст: если это web (https://github.com/symfony/symfony/blob/master/src/Symfony/Component/HttpKernel/HttpKernel.php#L63), то тут ты возможно захочешь отдать страницу ошибки. Если CLI, то возможно отобразить прямо в консоли exception с трейсом (если с -vvv, например, запустил). Устанавливать тот же глобальный обработчик, только через какой-то хендлер в зависимости от точки входа — это как раз по мне выглядит как костыль.

Для модулей — тем более. Если сфейлил отдельный блок страницы, то его можно просто не показывать; если сфейлила одна команда (command bus), то можно просто ее поставить на повторную обработку в очередь, не прекращая работу приложения в целом; если сфейлил обработчик события, то этот факт можно просто залоггировать и не прекращать работу приложения в целом; и т.д.

Хендер может быть OK для логгирования, но он никак не заменяет глобальный на уровне front controller'а и аналогичных, у них все-таки разные функции.
 

Фанат

oncle terrible
Команда форума
А это вообще нормально - советовать использовать глобальные переменные ?
Советовать - ненормально, использовать - нормально.

В любой программе есть глобальные сущности. Отрицать этот факт глупо.
Любой начинающий программист всегда сначала пытается использовать глобальные сущности неправильно, для передачи локальных параметров.
В итоге получается такая же лабуда, как моя борьба с try..catch - вопрос использования global становится религиозным табу, просто чтобы отбить руки нубам, поскольку они не понимают других формулировок.
Чтобы следовать этой религии, начинается изобретение всяких сущностей, которые по сути делают то же самое, но внешне не выглядят ересью.

И, да, "it is more complicated analogue"… со всем возможным уважением… http://9gag.com/gag/5533044
поправил )
 
Последнее редактирование:

AnrDaemon

Продвинутый новичок
Ну, религия или нет, спорить не буду, но меня всегда смущал вопрос того, откуда код метода какого-нибудь класса знает о том, как зовут переменную-инстанс PDO… Особенно если это какая-нибудь AR… >.<
 

Фанат

oncle terrible
Команда форума
Ну, религия или нет, спорить не буду, но меня всегда смущал вопрос того, откуда код метода какого-нибудь класса знает о том, как зовут переменную-инстанс PDO… Особенно если это какая-нибудь AR… >.<
Так речь не о классе ж.

Тем, у кого классы, объяснять про DI не нужно.
А тем, кто со скрипом переползает с mysql_query - бесполезно.

Но в общем да, надо наверное выкинуть эту двусмысленную фразу и начинать разжевывать.
Жаль, у меня там всего-то три шутки было, теперь две останется.
 

AnrDaemon

Продвинутый новичок
up to the handler usual way.
That's no moon English.

Do not use try..catch to report errors.
Думаю, стоит акцентировать "report"…

(optional) Create an error handler using set_error_handler() function if you want more flexible error reporting.
Пардон, но какое ЭТО имеет отношение к PDO в частности и к ловле исключений вообще?…
Убрать наф-наф.

Должно быть "$stmt = $pdo->prepare" по идее. Форматтер съел код?

Ты пишешь "all values will be bound as strings" и тут же "Will produce a query
UPDATE users SET param = NULL WHERE id = 1"

Да, я понимаю, что запросы эквивалентны, но надо быть честным хотя бы в пределах одного абзаца…

"dramatically with no reason" - "for no [apparent] reason".

so, use this function only if you have an idea what does it mean.
"so use this only if you have a very good idea, what exactly you are doing. Even then, you probably should not use it."

Английский язык довольно свободен в отношении запятых. Даже если ты пропустишь половину, никто не заметит.

"works in a slightly different way"… Так же "most of the time"…

"never outputs data right away during"

I was amased by the construction of that phrase… переставь in в начало. "… in how many".

"SELECT COUNT(1)" - COUNT(*). Я не знаю, почему COUNT(число) возвращает количество строк в таблице, это поведение недокументировано, и код по сути невалиден.

В части "Getting data out of statement. fetch()" стоит повесить большую красную тряпку
Do not, never ever use construction
PHP:
while($row = $stmt->fetch()) $arr[] = $row;
to get multiple rows from query result into a single array. If you want the resultset as an array, use PDOStatement::fetchAll() instead. F.e.
PHP:
$stmt->execute($params);
$smarty->assign('data', $stmt->fetchAll());
Это настолько часто встречается, что просто несмешно…

P.S.
server-side prepares+multiexec ощутимо ускоряют выполнение множества запросов (5-7% на insert). Проблема в том, что если сервер достаточно сильно нагружен, серверные препсы могут вытесняться и кэша и их приходится препарировать заново. Это усложняет код…
 

fixxxer

К.О.
Партнер клуба
Я не знаю, почему COUNT(число) возвращает количество строк в таблице, это поведение недокументировано, и код по сути невалиден
Нет, почему, это нормально. 1 - это expression, distinct-а нету, так что все сработает ожидаемо, разве что какая-нибудь особо тупая реализация может устроить фуллскан. Большинство СУБД оптимизируют count(CONST) в count(*). Исправить на *, конечно, лучше, но ничего невалидного.

Интересно, кстати, откуда это пошло - это довольно популярная форма записи, если погуглить. Может, в каком-нибудь ANSI SQL 19 века не было count(*)?
 
Сверху