Wyszukiwanie za pomocą LIKE i polskie znaki diakrytyczne
Niedawno robiłem dla klienta prosty formularz, gdzie skrypt miał za zadanie wyszukiwać rekord po nazwie ulicy. Pisząc skrypt napotkałem na dość nietypowy problem z funkcją LIKE.
Opis problemu
Najlepiej będzie jak opiszę problem na konkretnym przykładzie. W tym celu stworzyłem testową tabelę w bazie danych.
W tabeli są 2 rekordy – test pięć (ze znakami diakrytycznymi) i test piec (bez znaków diakrytycznych).
Skrypt
<?php $pdo = new PDO('mysql:host=localhost;dbname=***', '***', '***', array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8')); $pdo->exec("SET CHARACTER SET 'utf8'"); $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); $search='pięć'; $items = $pdo->prepare("SELECT * from test WHERE name LIKE :name"); $items->bindValue('name', '%' . $search . '%', PDO::PARAM_STR); $items->execute(); foreach ($items->fetchAll(PDO::FETCH_GROUP|PDO::FETCH_ASSOC) as $item) { var_dump($item); }
Powyższy skrypt wyświetla dwa rekordy.
Funkcja LIKE nie wyszukuje prawidłowo rekordów ze znakami takimi jak ą, ę, ś, ć itp.
Rozwiązanie problemu
Wystarczy nieco zmodyfikować zapytanie SQL.
$items = $pdo->prepare("SELECT * from test WHERE name COLLATE utf8_polish_ci LIKE :name");
Po tej poprawce skrypt prawidłowo wyświetla jeden rekord.
Samemu szukałem chwilę czasu rozwiązania problemu, stąd też ten wpis – może komuś się przyda :)