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.

Struktura bazy 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.

Nieprawidłowy var_dump

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.

Prawidłowy var_dump

Samemu szukałem chwilę czasu rozwiązania problemu, stąd też ten wpis – może komuś się przyda :)

Print Friendly, PDF & Email