_
en %
zijn geen jokertekens in MySQL in het algemeen, en mogen niet worden ontsnapt om ze in normale tekenreeksen te plaatsen. mysql_real_escape_string
is hiervoor correct en voldoende. addcslashes
mag niet worden gebruikt.
_
en %
zijn alleen speciaal in de context van LIKE
-bij elkaar passen. Als je strings wilt voorbereiden voor letterlijk gebruik in een LIKE
statement, zodat 100%
komt overeen met honderd procent en niet zomaar een tekenreeks die begint met honderd, je hebt twee ontsnappingsniveaus om je zorgen over te maken.
De eerste is LIKE ontsnappen. LIKE-afhandeling vindt volledig plaats binnen SQL, en als u een letterlijke tekenreeks in een letterlijke LIKE-expressie wilt veranderen, moet u deze stap uitvoeren zelfs als u geparametriseerde query's gebruikt !
In dit schema, _
en %
zijn speciaal en moeten worden ontsnapt. Het ontsnappingskarakter moet ook worden ontsnapt. Volgens ANSI SQL mogen andere tekens dan deze niet ontsnappen:\'
zou verkeerd zijn. (Hoewel MySQL je er normaal gesproken mee weg zal laten komen.)
Nadat je dit hebt gedaan, ga je verder naar het tweede niveau van ontsnappen, wat gewoon een oude string is, letterlijk ontsnappen. Dit vindt plaats buiten SQL, waardoor SQL wordt gemaakt, dus moet worden gedaan na de LIKE-escapestap. Voor MySQL is dit mysql_real_escape_string
zoals eerder; voor andere databases zal er een andere functie zijn, of u kunt gewoon geparametriseerde queries gebruiken om te voorkomen dat u dit hoeft te doen.
Het probleem dat hier tot verwarring leidt, is dat in MySQL een backslash wordt gebruikt als een escape-teken voor beide geneste escape-stappen! Dus als je een string wilt vergelijken met een letterlijk procentteken, moet je dubbele backslash-escape gebruiken en LIKE 'something\\%'
zeggen . Of, als dat in een PHP "
. is letterlijke die ook backslash-escaping gebruikt, "LIKE 'something\\\\%'"
. Argh!
Dit is onjuist volgens ANSI SQL, dat zegt dat:in letterlijke tekenreeksen backslashes letterlijke backslashes betekenen en de manier om aan een enkel aanhalingsteken te ontsnappen is ''
; in LIKE-expressies is er standaard helemaal geen escape-teken.
Dus als je LIKE-escape op een draagbare manier wilt, moet je het standaard (verkeerde) gedrag overschrijven en je eigen escape-teken specificeren, met behulp van de LIKE ... ESCAPE ...
bouwen. Voor gezond verstand kiezen we iets anders dan die verdomde backslash!
function like($s, $e) {
return str_replace(array($e, '_', '%'), array($e.$e, $e.'_', $e.'%'), $s);
}
$escapedname= mysql_real_escape_string(like($name, '='));
$query= "... WHERE name LIKE '%$escapedname%' ESCAPE '=' AND ...";
of met parameters (bijv. in PDO):
$q= $db->prepare("... WHERE name LIKE ? ESCAPE '=' AND ...");
$q->bindValue(1, '%'.like($name, '=').'%', PDO::PARAM_STR);
(Als je meer overdraagbaarheid op feestjes wilt, kun je ook plezier hebben door rekening te houden met MS SQL Server en Sybase, waar de [
karakter is ook, ten onrechte, speciaal in een LIKE
verklaring en moet worden ontsnapt. argh.)