Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [SOLVED] Odbc, Access i kodowanie znaków
Forum PHP.pl > Forum > PHP
patrycjusz
Witam,

Walczę z tym już dobre pare godzin smile.gif
Zastrzele się jak rozwiązanie się okaże bajecznie proste tongue.gif

Otóż mamy sobie plik PHP który łączy się po ODBC do Access'a i ciągnie sobie dane.
Problem jest z kodowaniem znaków:
1. rekordy mają różne kodowanie - raz ASCII raz UTF-8,
2. iconv mimo iż bym chciał - nie działa smile.gif

Poniżej kod (troche już zamotany tongue.gif)
  1. <?php
  2. ini_set('default_charset', 'UTF-8');
  3.  
  4. mb_internal_encoding("UTF-8");
  5.  
  6. echo implode(", ", mb_detect_order());
  7.  
  8. $dsn = "odbc:Driver={Driver do Microsoft Access (*.mdb)};Dbq=C:dane.mdb;Uid=Admin";
  9. $pdo = new PDO($dsn);
  10. $sql = "tutaj jesst select";
  11. iconv_set_encoding("internal_encoding", "UTF-8");
  12. //iconv_set_encoding("input_encoding", "UTF-8");
  13. iconv_set_encoding("output_encoding", "UTF-8");
  14.  
  15. $member = "pierwsza linia w pliku CSV";
  16.  
  17. foreach($pdo->query($sql) AS $row){
  18. $data = "";
  19. if($row['E-MAIL'] == null || $row['EMAIL_FIRMA'] == null){
  20.  
  21. }else{
  22. echo mb_detect_encoding($row['FIRMA']);
  23.  
  24. if(is_null($row['E-MAIL'])){
  25. $emails = explode(";",$row['EMAIL']);
  26. $data .= iconv('iso-8859-2','UTF-8',$email[0])."|";
  27. }else{
  28. $data .= iconv('iso-8859-2','UTF-8',$data['E-MAIL'])."|";
  29. }
  30.  
  31. $data .= iconv('iso-8859-2','UTF-8',$row['KOLUMNA'])"; //nie pomaga :)
  32. }
  33. echo mb_detect_encoding($data); //raz jest ASCII raz utf-8
  34. if(mb_detect_encoding($data) == 'UTF-8'){
  35. $member .= $data;
  36. }else{
  37. echo mb_detect_encoding($data);//raz wyswietla sie raz nie ;)
  38. }
  39. echo "n";
  40. }
  41. ?>


Nie będę tłumaczył do czegoż ma to służyć bo historia jest tak długa że hej a baza jest w takim stanie, że szok smile.gif

Temu kto rozwiąze problem stawiam browarów 5 smile.gif

pzdr, patS
SongoQ
To zamiast od razu komplikowac kod zrob prosty odczyt z bazy i operacje wykrywania kodowania na 1 polu a nastepnie konwersje bo patrzac na kod nie wiadomo czy blad jest po stronie funkcji konwersji czy w kodzie.

Bazka jakie ma domyslne kodowanie ustawione? Bo mozliwe jest ze zrobil jakas glupia konwersje, z krora iconv nie potrafi sobie poradzic.
patrycjusz
no właśnie ten drugi wariant mi się wydaje najbardziej prawdopodobny smile.gif
Bo kod ten już był prosty do bólu smile.gif ta wersja jest ostatnią, co prawda najbardziej skomplikowaną - ale obrazuje miejsce do którego zabrnąłem smile.gif

Problem też polega na tym, że mam tylko plik .mdb który otwieram OpenOfficofskim Base i OO widzi wszystko ok, PHP niestety dostaje na przemian ASCII z UTF-8.

Pare pytań:
1. Może jakiś program co wychwyci niuanse (kodowanie itp) w tej bazie?
2. Możliwe jest aby w accessie różne rekordy miały różne kodowanie?
3. Może jakiś zupełnie inny soft co sobie z tym poradzi (Java, C# znam jako tako) - potrzebuje wycisnąć z tej bazy CSV-kę.

patS
SongoQ
Jesli to jest operacja cykliczna to bedzie problem jesli jednorazowa to Access podejrzewam ze ma export do csv, oprocz tego jest wiele narzedzi ktore zrzuca albo konwertuje do innego formatu bazy danych np EMS (http://www.sqlmanager.net/)

Troche jest dziwne ze zwraca Ci kodowanie UTF-8 a powinno raczej cos windowsowego.
patrycjusz
Walcze, walcze,

ostatni kod:
  1. <?php
  2.  
  3. $tableName = "ms_access_members";
  4. $dsn = "odbc:Driver={Driver do Microsoft Access (*.mdb)};Dbq=C:dane.mdb;Uid=Admin";
  5. $pdo = new PDO($dsn);
  6. $sql = "select * ....";
  7.  
  8. $member = "email|firma";
  9.  
  10. foreach($pdo->query($sql) AS $row){
  11. echo "before: ".mb_detect_encoding($row['FIRMA']);
  12. $data = "";
  13. if($row['E-MAIL'] == null || $row['EMAIL_FIRMA'] == null){
  14.  
  15. }else{
  16. if(is_null($row['E-MAIL'])){
  17. $emails = explode(";",$row['EMAIL_FIRMA']);
  18. $data .= iconv('cp1250','UTF-8',$email[0])."|";
  19. }else{
  20. $data .= iconv('cp1250','UTF-8',$data['E-MAIL'])."|";
  21. }
  22.  
  23. $data .= iconv('cp1250','UTF-8',$row['FIRMA'])."n"; 
  24. }
  25. echo "after: ".mb_detect_encoding($data);
  26. echo "n";
  27. $member .= $data;
  28. }
  29. ?>

a teraz skrawek z wywołania z lini poleceń tego skryptu PHP
  1. before: ASCIIafter: UTF-8
  2. before: ASCIIafter: UTF-8
  3. before: UTF-8after: UTF-8
  4. before: UTF-8after: ASCII
  5. before: UTF-8after: ASCII
  6. before: ASCIIafter: ASCII
  7. before: ASCIIafter: ASCII
  8. before: ASCIIafter: UTF-8
  9. before: after: UTF-8
  10. before: after: UTF-8
  11. before: after: ASCII
  12. before: after: ASCII
  13. before: after: ASCII
  14. before: UTF-8after: ASCII


Ha! smile.gif poprostu boskie smile.gif

a tak poważnie, próbowałem już i windows-1250 i cp1250

Mam wrażenie, że iconv coś nie do końca to łapie.

Sam plik jest w utf-8.

pzdr, patS

Dobra Panowie, czuje, że jestem blisko,
stawka wzrasta do 7 piw smile.gif

Do odbioru na żoliborzu albo na polach mokotowskich smile.gif

Patrzcie, jak zacząłem printować poszczególne wartości i ich kodowanie to jest prawidłowość:
1. Tam gdzie są polskie fonty - jest utf-8
2. Tam gdzie nie ma polskich fontów - jest ASCII

pzdr, patS
SongoQ
Czyli problem moze byc samego sterownika odbc jesli masz krzaczki to konwertuje na utf-8 z tego co pamietam polskie krzaczki maja o 1 bajt wiecej, jesli nie masz krzakow to zostaje to dalej na 2 bajtach wiec moze wypluwac jako ascii. To takie moje przemyslenia. Mozesz szukac w czym jest problem mozliwe ze pdo ma jakiegos buga w tym.

A co do Twojego problemu to pewnie regexp bys zalatwil (A-z) z tego co pamietam nie lapie krzakow wiec wtedy wiesz co jest ok
Kicok
Wypluwa wszystko jako UTF-8. Po prostu jeśli w tekście nie masz żadnego znaku wielobajtowego, to mb_detect_encoding" title="Zobacz w manualu PHP" target="_manual rozpozna to jako ASCII. Odpal ten kod:

  1. <?php
  2.  
  3.  
  4. header( 'Content-Type: text/html; charset=UTF-8' );
  5.  
  6. $tableName = "ms_access_members";
  7. $dsn = "odbc:Driver={Driver do Microsoft Access (*.mdb)};Dbq=C:dane.mdb;Uid=Admin";
  8. $pdo = new PDO( $dsn );
  9. $sql = "select * ....";
  10.  
  11. foreach($pdo->query($sql) AS $row)
  12. {
  13. echo "E-AMIL: {$row['E-MAIL']}; EMAIL_FIRMA: {$row['EMAIL_FIRMA']}<br />";
  14. }
  15.  
  16. ?>


i powiedz na co zamienione zostały polskie znaki. Są trzy możliwości:
1. Na jeden pytajnik
2. Na jeden krzaczek, np: ±
3. Na dwa krzaczki/pytajniki, np: ź, albo �
patrycjusz
@kicok wypluwa � (jeden pytajnik)

Dobra pare pytań smile.gif

1. Idąc dalej tym tropem, a jeżeli mb_detect_encoding nic nie zwraca?
2. Czym się różnią te 3 pozycje @kicok które wymieniłeś?
3. Co oznacza wzięcie zmiennej w stringu w {} ?

Dobra będe kombinował, dzięki

pzdr, patS

P.S. Ale podpowiedzi piszczcie smile.gif @kicok co z tym jednym pytajnikiem? Co to oznacza?

P.S. 2. Jakiś kurcze dobry manual o kodowaniach znaków - linki wklejajcie. Do Moderatora: Może jakiś topic przyklejony na temat kodowania znaków warto by zrobić?

Dobra, hmm

faktycznie, jest tak, że jak nie ma polskiego krzaczka to zwraca ASCII które nie ma jak skonwertować na UTF-8 worriedsmiley.gif (iconv nie działa)
jeżeli jest zaś polski krzaczek to zwraca utf-8 ale z znakiem �

Koncepcje?

patS



Dobra mam smile.gif

genialny artykuł warto poczytać, szczególnie trzeba zwrócić uwagę na to iż iconv czy mb_convert ... nie operują na windowsowym kodowaniu. Odkryłem to przez przypadek, kod powyżej, uruchomiłem pod FF i przełączyłem z poziomu FF na windows-1250 smile.gif

Troche lameriada wyszła smile.gif Może zmęcznie materiału ... (czyt. mnie tongue.gif)

Tak czy owak, browar dla sonq i kicoka smile.gif


pzdr, patS

P.S. Kurcze bym zapomniał, użyłem funkcji pl_win2utf8 z przykładu pod podanym wyżej adresem smile.gif
SongoQ
Cytat
Tak czy owak, browar dla sonq i kicoka
A tak sie sklada ze nie daleko mieszkam tongue.gif
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.