post_ico4

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 :)

Co sądzisz o wpisie?
BeżnadziejnySłabyŚredniDobryBardzo dobry (1 głosów, średnia ocen: 5,00 z 5)
Loading...
  • sparhawk

    Z „ł” to też działa ?

    • Szczerze mówiąc nie zwróciłem na to uwagi, ale powinno działać :)

  • Nie jest to problem samego „LIKE” ale definicji tabeli/bazy, której nie przedstawiłeś.

  • thejw23

    Innym przykładem dlaczego warto ustawiać tabele na utf8_polish_ci zamiast utf8_general_ci jest ORDER BY. I to nie problem zapytania, ale definicji tabeli.

    • Standardowo ustawiam utf8_general_ci i szczerze mówiąc nie wiedziałem o tym. Człowiek cały czas się uczy.. :)