По темата..
Днес ми се наложи да сравнявам предимства и недостатъци на няколко framework-чета. При едното от тях липсваше вграден database model, така че се наложи да ползвам нещо отделно. В конкретният случай се спрях на PDO и реших да си напиша няколко базови класчета..
За да съкратя историята, направо ще ви синтезирам това което Ви е нужно да знаете ;)
При МySQL имате два вида сравнение на низ от символи (string) - това са равенство и сравнение с pattern, посредством LIKE или регулярен израз. В моят случай използвам LIKE, защото е най-бърз за имплементация и защото отговаря на нуждите ми и няма смисъл от overengineering.
Случаят е простичък - имам данни в базата, имам и търсачка която търси с LIKE. Това което ме изненада, беше, че mysql_real_escape_string() допусна символи в низа които са със специално значение, а именно - символите за процент (%) и долно тире (_). В най-общият случай - при вмъкване на данни или сравнение със равенство това не ви бърка, но когато ползвате LIKE нещата стоят по малко по-различен начин.
Получи се ситуация, при която аз търся в базата данни къде е споменато "100%", но тъй като символът за процент не се escape-ва, се получава, че търся низ който съдържа 100.
Query-то което се генерира е следното:
SELECT * FROM SomeTable WHERE `textField` LIKE '%100%%'
Очевидно, това не е поведението което би се очаквало, след като имаш илюзията, че данните са ти escape-нати правилно.
След като разбрах какъв е проблема си помислих, че може би е проблем на mysql_real_escape_string() и веднага си отворих http://www.php.net/mysql_real_escape_string - но се оказа, че това е очаквано поведение. В документацията на функцията ясно са писали, че тя "prepends backslashes to the following characters: \x00, \n, \r, \, ', " and \x1a".
Ето го точният цитат от сайта:
Може би символите за wildcard попадат точно в тези изключения които са споменали.mysql_real_escape_string() calls MySQL's library function mysql_real_escape_string, which prepends backslashes to the following characters: \x00, \n, \r, \, ', " and \x1a.This function must always (with few exceptions) be used to make data safe before sending a query to MySQL.
Изводът е простичък - винаги минавайте един профилактичен str_ireplace() или preg_replace() на данните които използвате при генериране на заявка за търсене в базата данни за да няма изненади. Нека това, че ползвате prepared statements не ви дава чувство за сигурност.
Няма коментари:
Публикуване на коментар