Этот пост я хочу посвятить решению одной проблемы, которая доставила мне массу проблем. Хотя, если говорить о неприятностях, то они скорее были не у меня, а у пользователей проекта, в котором я участвую1.
Проблема заключалась в том, что пользователи не могли сохранить на сервере данные, если они превышали определённый объём. При чем, не могли сохранить на столько, что отправляли апач в «кору». Честно говоря, это сильно раздражало, потому что происходило буквально на ровном месте.
В конце концов такая ситуация надоела и я по локоть залез своими шаловливыми ручонками вглубь Zend_Db. Предположения о вероятной причине у нас были и это несколько облегчило задачу. Падения могли происходить из-за того, что регулярка уходила в глубокую рекурсию и там умирала. Эту гипотезу я и стал проверять. Почему я полез именно в Zend_Db? Очень просто — поиск причины показал, что скрипт умирает именно там.
И оказалось таки да — Zend_Db при создании экземпляра стэйтмента регуляркой вырезал все экранирующие символы. Если при этом тест запроса был достаточно объемным, то весь процесс завершался падением.
Вот так наш код выглядел ранее (естественно, код крайне упрощен):
$sql = "INSERT INTO tab (id,name)
VALUES (null,'очень ... длинный ... текст')";
$db->query($sql); // $db - экземпляр Zend_Db_Adapter_Mysqli
Пытливый ум некоторый читателей моего блога может зародить разумную мысль: «А зачем, собственно, писать текст запроса целиком, если есть методы и для вставки, и для выборки?». И, таки да, будет в чем-то прав. Но! К сожалению, Zend_Db реализует не все возможности SQL и иногда приходится идти на крайние меры и писать запросы явно.
Вернемся к проблеме. Покрутив и так, и эдак, я решил пойти по пути наименьшего сопротивления. А именно, воспользоваться плейсхолдерами. Теперь код стал выглядеть так:
$sql = "INSERT INTO tab (id,name)
VALUES (null, ?)";
$name = 'очень ... длинный ... текст'; // значение поступает от пользователя
$db->query($sql, array($name)); // $db - экземпляр Zend_Db_Adapter_Mysqli
Это изменение полностью решило данную проблему. Ура!
Пытливый читатель может опять спросить: «А чего же не вы не воспользовались плейсхолдерами сразу?!». И будет снова прав! Надо было поступать именно так. Но богомерзкое желание сохранить пару тактов процессора сделало свое грязное дело и мы нашли приключения на свой зад проблемы на свою голову.
Мораль сей басни такова: пользуйтесь плейсхолдерами и ваши волосы будут мягкими и шелковистыми!
P.S.: Я надеюсь, что после прочтения этого поста у вас не сложилось впечатление, что мы запросы к базе пишем исключительно текстом. Спешу развеять это впечатление: поиск по нашему (очень не маленькому) проекту выявил всего 4 или 5 таких мест. Код исправлен, виновные понесли заслуженное поощрение.
Постовой:
Если Вам нужен эвакуатор, то заказать его можете тут: эвакуатор в Москве. А если хочется экзотики, то можете съездить на отдых в Японии
-
Для справки: проект представляет из себя некий веб-сервис развлекательного характера. ↩
Метки: database, php, zend framework



(3 голосов, средний: 4.00 из 5)