Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Sortowanie danych w utf-8
Forum PHP.pl > Forum > PHP
ziemot
Witam!

Problem to generalnie sortowanie danych pochodzacych z bazy MySQL. Mimo przewertowania forum nie udalo mi sie znalezc rozwiazania, ktore by zadzialalo w moich warunkach... no ale moze od poczatku, najpierw konfiguracja:

serwer bazy danych: MySQL 4.1.16, dziala na Windows XP, uruchamia sie jako serwis przy starcie systemu, w pliku konfiguracyjnym my.ini ustawione jest:

[mysql]
default-character-set=utf8
[mysqld]
default-character-set=utf8

php: 4.4.2

aplikacja nad ktora siedze zawiera nazwy miast i wojewodztw.

1. Problem pojawia sie przy sortowaniu nazw wojewodztw:
konfiguracja tabeli:
storage engine: MyISAM
collation: utf8_polish_ci
wybieram z tabeli wszystkie wojewodztwa nastepujacym zapytaniem:
SELECT * FROM wojewodztwa ORDER BY NazwaWoj COLLATE "utf8_polish_ci"
a wynik jest cokolwiek dziwny:
Dolnośląskie
Kujawsko-Pomorskie
Łódzkie
Śląskie -> exclamation.gif!!!!!
Lubelskie
Lubuskie
Świętokrzyskie -> exclamation.gif!!!

dalej jest juz w porzadku

Co z tym zrobic?

2. Drugi problem wychodzi przy wyszukiwarce miast, użytkownik podaje nazwę miasta, aplikacja łączy się z bazą danych, wyszukuje miasto i zwracana jest tablica z wszystkimi wystąpieniami zadanego ciągu znaków.
Wszystko jest ok dopoki na poczatku ciagu znakow nie ma polskiej litery -> pierwszy znak przerabiam ucfirst() na wielka litere i dziala, natomiast jesli pierwszym znakiem jest polska litera (np Łomża) to podajac w wyszukiwarce nazwe miasta z malej litery nie dziala ucfirst() - nie zamienia mi malej polskiej litery na duza, a potem baza nie wyszukuje danych. Wrowadzajac ta sama nazwe miasta do wyszukiwarki z wielka pierwsza litera, otrzymuje poprawny wynik.

Co jest nie tak?
konfiguracja tabeli:
storage engine: MyISAM
collation: utf8_general_ci

zapytanie SQL:
SELECT ms.ID_Miejsca, ms.NazwaMiejsca, ms.ID_TypuMiejsca, ms.MiejsceAKT, wms.OldNazwaMiejsca FROM miejsca AS ms LEFT JOIN wydarzenia_miejsca AS wms ON ms.ID_Miejsca = wms.ID_Miejsca WHERE ms.MiejsceAKT = 1 AND (ms.NazwaMiejsca LIKE "%'.$string.'%" OR wms.OldNazwaMiejsca LIKE "%'.$string.'%") GROUP BY ms.ID_Miejsca ORDER BY ms.NazwaMiejsca COLLATE "utf8_polish_ci"

formularz html do ktorego wprowadza sie nazwe miasta jest ustwiony na wprowadzanie znakow w stronie kodowej utf-8:
<form action="i.php?id=51" method="POST" accept-charset="utf-8">

Gdzie tkwi blad? Oczywiscie mozna dorobic jakas funkcje przerabiajaca male polskie znaki na poczatku ciagu znakow na duze litery..., ale to jest rozwiazanie takie, hmm, lopatologiczne, czy na prawde nie ma rozwiazania innego, latwiejszego?

ZiemoT
eai
1. Po pierwsze stosuj wszędzie to samo kodowanie, utf8_polish_ci i sprawdź czy kodowanie tabeli i jednocześnie pola z nazwami województw jest utf8_polish_ci.
2. Skorzystaj z 3 funkcji: http://pl.php.net/manual/pl/function.mb-in...al-encoding.php http://pl.php.net/manual/pl/function.mb-strtoupper.php http://pl.php.net/manual/pl/function.mb-substr.php

  1. <?php
  2. mb_internal_encoding("UTF-8");
  3.  
  4.    function mb_ucfirst($string) {
  5.        $string = mb_strtoupper(mb_substr($string, 0, 1)) . mb_substr($string, 1);
  6.        return $string;
  7.    }
  8. ?>


Pisane z palca, nie testowane.
ziemot
Hej!

Dzieki za podpowiedzi...

ad.1. Stosuje wszedzie to samo kodowanie utf-8, a utf8_polish_ci to o ile sie orientuje okresla sposob sortowania - schemat wg ktorego sortuje baza danych dane z zapytania - ci to podobno case insensitive - gdzies grzebiac na tym forum to znalazlem.
Wiec tak na prawde to nie wiem czy tutaj tkwi blad.

ad.2.
Dziwna sprawa, mam php 4.4.2 wg dokumentacji podane przez Ciebie funkcje powinny byc od 4.0.2. a u mnie za kazdym razem gdy chce uzyc mb_internal_encoding lub mb_strtoupper wola call to undefined function... dziwne...

ZiemoT
nevt
założyłem sobie tabelkę z nazwami województw, wpisałem twoje zapytanie i u mnie sortuje 100% poprawnie.

wniosek? dane są wprowadzone w innym kodowaniu niż utf8 ... albo zawierają na początku jakieś śmieci w postaci niewidocznych białych znaków (spacje, tabulatory itp.) spróbuj zapytania w postaci:
  1. SELECT * FROM wojewodztwa ORDER BY LTRIM(NazwaWoj) COLLATE 'utf8_polish_ci';
ziemot
Tak gwoli zamkniecia watku....

Udalo mi sie w koncu doprowadzic do porzadku te polskie literki. Faktycznie wychodzi na to, że wszystkie dane jakie mialem w bazie (mimo wpisu w znacznikach form accept-charset="utf-8" oraz ustawienia bazy danych na utf8 i collate na utf8_general_ci lub utf8_polish_ci) byly w jakims tajemniczym kodowaniu totalnie od czapy.

Rozwiazanie bylo proste choc do tej pory nie moge sobie wytlumaczyc dlaczego akurat to pomoglo:

1. zaraz po podlaczeniu do bazy danych nalezy ustawic: SET NAMES utf8
2. wywalilem ze wszystkich formularzy html: accept-charset="utf-8"

oczywiscie baza danych w utf8, collate akurat u mnie w utf8_general_ci.

o ile SET NAMES potrafie sobie wytlumaczyc, o tyle dlaczego nalezalo wywalic accept-charset ze znacznikow form... tego nie wiem. Ma ktos jakis pomysl? ;-)
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.