2012-04-14 22 views
30

Mam php document signup.php, który zapisuje treść z formularza (w dokumencie form.php) do bazy MySQL. Problem pojawia się, gdy chcę sformatować zawartość wejściową. Chcę odszyfrować znaki UTF-8, takie jak à-> a.PHP zastępując znaki specjalne, takie jak à-> a, è-> e

$first_name=$_POST['first_name']; 
    $last_name=$_POST['last_name']; 
    $course=$_POST['course']; 

    $chain="prêt-à-porter"; 

$pattern = array("'é'", "'è'", "'ë'", "'ê'", "'É'", "'È'", "'Ë'", "'Ê'", "'á'", "'à'", "'ä'", "'â'", "'å'", "'Á'", "'À'", "'Ä'", "'Â'", "'Å'", "'ó'", "'ò'", "'ö'", "'ô'", "'Ó'", "'Ò'", "'Ö'", "'Ô'", "'í'", "'ì'", "'ï'", "'î'", "'Í'", "'Ì'", "'Ï'", "'Î'", "'ú'", "'ù'", "'ü'", "'û'", "'Ú'", "'Ù'", "'Ü'", "'Û'", "'ý'", "'ÿ'", "'Ý'", "'ø'", "'Ø'", "'œ'", "'Œ'", "'Æ'", "'ç'", "'Ç'"); 

$replace = array('e', 'e', 'e', 'e', 'E', 'E', 'E', 'E', 'a', 'a', 'a', 'a', 'a', 'A', 'A', 'A', 'A', 'A', 'o', 'o', 'o', 'o', 'O', 'O', 'O', 'O', 'i', 'i', 'i', 'I', 'I', 'I', 'I', 'I', 'u', 'u', 'u', 'u', 'U', 'U', 'U', 'U', 'y', 'y', 'Y', 'o', 'O', 'a', 'A', 'A', 'c', 'C'); 

$chain = preg_replace($pattern, $replace, $chain); 

echo $chain; // print pret-a-porter 

$first_name = preg_replace($pattern, $replace, $first_name); 

echo $first_name; // does not change the input!?! 

Dlaczego działa idealnie dla łańcucha $, ale dla $ nazwa_wylarki lub nazwa_udziału $ nie działa?

Również próbuję

echo $first_name; // print áááááábéééééébšššš 
$trans = array("á" => "a", "é" => "e", "š" => "s"); 
echo strtr("áááááábéééééébšššš", $trans); // print aaaaaabeeeeeebssss 
echo strtr($first_name,$trans); // print áááááábéééééébšššš 

ale problem, jak widać, jest to samo!

+2

Czy Twój plik ma odpowiedniego kodowania? Czy rzeczy w $ _POST mają takie samo kodowanie? (tj. ten, który ustawiłeś dla przeglądarki, aby wyświetlić stronę z?) Możesz także ustawić flagę Unicode dla preg_replace – phant0m

+1

Jak wspomina phant0m, musisz uważnie obserwować wszystkie kodowania. Domyślne kodowanie z POST to ISO-8859-1, chyba że powiesz mu dokładnie, czego chcesz. (accept-charset = 'UTF-8') – dmp

+0

dodano kilka przykładowych funkcji :) – dmp

Odpowiedz

63

Jest to znacznie łatwiejszy sposób, aby to zrobić, używając iconv - z notatek użytkownika, to wydaje się być to, co chcesz zrobić: characters transliteration

// PHP.net User notes 
<?php 
    $string = "ʿABBĀSĀBĀD"; 

    echo iconv('UTF-8', 'ISO-8859-1//TRANSLIT', $string); 
    // output: [nothing, and you get a notice] 

    echo iconv('UTF-8', 'ISO-8859-1//IGNORE', $string); 
    // output: ABBSBD 

    echo iconv('UTF-8', 'ISO-8859-1//TRANSLIT//IGNORE', $string); 
    // output: ABBASABAD 
    // Yay! That's what I wanted! 
?> 

Bądź bardzo sumienny ze swoimi kodowania znaków, więc zachowujesz to samo kodowanie na wszystkich etapach procesu - front end, składanie formularzy, kodowanie plików źródłowych. Domyślne kodowanie w PHP i formularzach to ISO-8859-1, przed PHP 5.4, gdzie zmieniono go na UTF8 (wreszcie!).

Istnieje kilka funkcji, w które można się bawić pomysłami. Pierwszym z nich jest z CakePHP w klasie inflector, zwany slug:

public static function slug($string, $replacement = '_') { 
    $quotedReplacement = preg_quote($replacement, '/'); 

    $merge = array(
     '/[^\s\p{Ll}\p{Lm}\p{Lo}\p{Lt}\p{Lu}\p{Nd}]/mu' => ' ', 
     '/\\s+/' => $replacement, 
     sprintf('/^[%s]+|[%s]+$/', $quotedReplacement, $quotedReplacement) => '', 
    ); 

    $map = self::$_transliteration + $merge; 
    return preg_replace(array_keys($map), array_values($map), $string); 
} 

To zależy od self::$_transliteration tablicy, która jest podobna do tego, co robisz w swoim pytaniu - można see the source for inflector on github.

Inną funkcją, której używam osobiście, jest comes from here.

function slugify($text,$strict = false) { 
    $text = html_entity_decode($text, ENT_QUOTES, 'UTF-8'); 
    // replace non letter or digits by - 
    $text = preg_replace('~[^\\pL\d.]+~u', '-', $text); 

    // trim 
    $text = trim($text, '-'); 
    setlocale(LC_CTYPE, 'en_GB.utf8'); 
    // transliterate 
    if (function_exists('iconv')) { 
     $text = iconv('utf-8', 'us-ascii//TRANSLIT', $text); 
    } 

    // lowercase 
    $text = strtolower($text); 
    // remove unwanted characters 
    $text = preg_replace('~[^-\w.]+~', '', $text); 
    if (empty($text)) { 
     return 'empty_$'; 
    } 
    if ($strict) { 
     $text = str_replace(".", "_", $text); 
    } 
    return $text; 
} 

Co te funkcje zrobić to transliteracji i tworzyć „slugs” z dowolnego wprowadzania tekstu, która jest bardzo przydatna rzecz mieć w swojej Biblioteki szablonów podczas tworzenia aplikacji internetowych. Mam nadzieję że to pomoże!

+2

Dziękuję za odpowiedź. Problem polegał na tym, że w formularzu nie dodałem "accept-charset =" UTF-8 "". –

+0

witam, domyślam się, że wszystkie te funkcje nie były naprawdę potrzebne :), ale mogą równie dobrze wyglądać. – dmp

+1

Nadal używam mojej funkcji, ponieważ dzięki niej mogę dokładnie określić, z jaką literą zastąpię jakąś literę. –

5

Łańcuch $ łańcuch jest w tym samym kodzie znaków, co znaki w tablicy - możliwe, że najprawdopodobniej łańcuch $ first_name ma inne kodowanie, a więc te znaki nie pasują do siebie. Zamiast tego możesz spróbować użyć funkcji ciągu wielobajtowego.

Spróbuj mb_convert_encoding. Możesz również spróbować użyć HTML_ENTITIES jako parametru to_encoding, wtedy nie musisz się martwić o to, jak konwertowane zostaną postacie - będzie to bardzo przewidywalne.

Zakładając, że wejście do tego skryptu jest w UTF-8, prawdopodobnie nie jest to złe miejsce, aby rozpocząć ...

$first_name = mb_convert_encoding($first_name, "HTML-ENTITIES", "UTF-8"); 
+0

Próbowałem tego, a nie jest. echo $ pierwsza_nazwa; // print áááááábéééééébészése $ first_name = mb_convert_encoding ($ first_name, "HTML-ENTITIES", "UTF-8"); echo $ pierwsza_nazwa; // print áááááábéééééé ébészése –

+0

Dziękuję za odpowiedź, problem polegał na tym, że nie dodałem w formularzu "accept-charset =" UTF-8 "". –

14

Oto sposób na pewną elastyczność w tym, co należy wyrzucić, a co powinno być zastąpiony. Tak właśnie robię.

$ string = 'À jakiś ciąg ze śmieciami Ĩ Ę';

$replace = [ 
    '&lt;' => '', '&gt;' => '', '&#039;' => '', '&amp;' => '', 
    '&quot;' => '', 'À' => 'A', 'Á' => 'A', 'Â' => 'A', 'Ã' => 'A', 'Ä' => 'Ae', 
    '&Auml;' => 'A', 'Å' => 'A', 'Ā' => 'A', 'Ą' => 'A', 'Ă' => 'A', 'Æ' => 'Ae', 
    'Ç' => 'C', 'Ć' => 'C', 'Č' => 'C', 'Ĉ' => 'C', 'Ċ' => 'C', 'Ď' => 'D', 'Đ' => 'D', 
    'Ð' => 'D', 'È' => 'E', 'É' => 'E', 'Ê' => 'E', 'Ë' => 'E', 'Ē' => 'E', 
    'Ę' => 'E', 'Ě' => 'E', 'Ĕ' => 'E', 'Ė' => 'E', 'Ĝ' => 'G', 'Ğ' => 'G', 
    'Ġ' => 'G', 'Ģ' => 'G', 'Ĥ' => 'H', 'Ħ' => 'H', 'Ì' => 'I', 'Í' => 'I', 
    'Î' => 'I', 'Ï' => 'I', 'Ī' => 'I', 'Ĩ' => 'I', 'Ĭ' => 'I', 'Į' => 'I', 
    'İ' => 'I', 'IJ' => 'IJ', 'Ĵ' => 'J', 'Ķ' => 'K', 'Ł' => 'K', 'Ľ' => 'K', 
    'Ĺ' => 'K', 'Ļ' => 'K', 'Ŀ' => 'K', 'Ñ' => 'N', 'Ń' => 'N', 'Ň' => 'N', 
    'Ņ' => 'N', 'Ŋ' => 'N', 'Ò' => 'O', 'Ó' => 'O', 'Ô' => 'O', 'Õ' => 'O', 
    'Ö' => 'Oe', '&Ouml;' => 'Oe', 'Ø' => 'O', 'Ō' => 'O', 'Ő' => 'O', 'Ŏ' => 'O', 
    'Œ' => 'OE', 'Ŕ' => 'R', 'Ř' => 'R', 'Ŗ' => 'R', 'Ś' => 'S', 'Š' => 'S', 
    'Ş' => 'S', 'Ŝ' => 'S', 'Ș' => 'S', 'Ť' => 'T', 'Ţ' => 'T', 'Ŧ' => 'T', 
    'Ț' => 'T', 'Ù' => 'U', 'Ú' => 'U', 'Û' => 'U', 'Ü' => 'Ue', 'Ū' => 'U', 
    '&Uuml;' => 'Ue', 'Ů' => 'U', 'Ű' => 'U', 'Ŭ' => 'U', 'Ũ' => 'U', 'Ų' => 'U', 
    'Ŵ' => 'W', 'Ý' => 'Y', 'Ŷ' => 'Y', 'Ÿ' => 'Y', 'Ź' => 'Z', 'Ž' => 'Z', 
    'Ż' => 'Z', 'Þ' => 'T', 'à' => 'a', 'á' => 'a', 'â' => 'a', 'ã' => 'a', 
    'ä' => 'ae', '&auml;' => 'ae', 'å' => 'a', 'ā' => 'a', 'ą' => 'a', 'ă' => 'a', 
    'æ' => 'ae', 'ç' => 'c', 'ć' => 'c', 'č' => 'c', 'ĉ' => 'c', 'ċ' => 'c', 
    'ď' => 'd', 'đ' => 'd', 'ð' => 'd', 'è' => 'e', 'é' => 'e', 'ê' => 'e', 
    'ë' => 'e', 'ē' => 'e', 'ę' => 'e', 'ě' => 'e', 'ĕ' => 'e', 'ė' => 'e', 
    'ƒ' => 'f', 'ĝ' => 'g', 'ğ' => 'g', 'ġ' => 'g', 'ģ' => 'g', 'ĥ' => 'h', 
    'ħ' => 'h', 'ì' => 'i', 'í' => 'i', 'î' => 'i', 'ï' => 'i', 'ī' => 'i', 
    'ĩ' => 'i', 'ĭ' => 'i', 'į' => 'i', 'ı' => 'i', 'ij' => 'ij', 'ĵ' => 'j', 
    'ķ' => 'k', 'ĸ' => 'k', 'ł' => 'l', 'ľ' => 'l', 'ĺ' => 'l', 'ļ' => 'l', 
    'ŀ' => 'l', 'ñ' => 'n', 'ń' => 'n', 'ň' => 'n', 'ņ' => 'n', 'ʼn' => 'n', 
    'ŋ' => 'n', 'ò' => 'o', 'ó' => 'o', 'ô' => 'o', 'õ' => 'o', 'ö' => 'oe', 
    '&ouml;' => 'oe', 'ø' => 'o', 'ō' => 'o', 'ő' => 'o', 'ŏ' => 'o', 'œ' => 'oe', 
    'ŕ' => 'r', 'ř' => 'r', 'ŗ' => 'r', 'š' => 's', 'ù' => 'u', 'ú' => 'u', 
    'û' => 'u', 'ü' => 'ue', 'ū' => 'u', '&uuml;' => 'ue', 'ů' => 'u', 'ű' => 'u', 
    'ŭ' => 'u', 'ũ' => 'u', 'ų' => 'u', 'ŵ' => 'w', 'ý' => 'y', 'ÿ' => 'y', 
    'ŷ' => 'y', 'ž' => 'z', 'ż' => 'z', 'ź' => 'z', 'þ' => 't', 'ß' => 'ss', 
    'ſ' => 'ss', 'ый' => 'iy', 'А' => 'A', 'Б' => 'B', 'В' => 'V', 'Г' => 'G', 
    'Д' => 'D', 'Е' => 'E', 'Ё' => 'YO', 'Ж' => 'ZH', 'З' => 'Z', 'И' => 'I', 
    'Й' => 'Y', 'К' => 'K', 'Л' => 'L', 'М' => 'M', 'Н' => 'N', 'О' => 'O', 
    'П' => 'P', 'Р' => 'R', 'С' => 'S', 'Т' => 'T', 'У' => 'U', 'Ф' => 'F', 
    'Х' => 'H', 'Ц' => 'C', 'Ч' => 'CH', 'Ш' => 'SH', 'Щ' => 'SCH', 'Ъ' => '', 
    'Ы' => 'Y', 'Ь' => '', 'Э' => 'E', 'Ю' => 'YU', 'Я' => 'YA', 'а' => 'a', 
    'б' => 'b', 'в' => 'v', 'г' => 'g', 'д' => 'd', 'е' => 'e', 'ё' => 'yo', 
    'ж' => 'zh', 'з' => 'z', 'и' => 'i', 'й' => 'y', 'к' => 'k', 'л' => 'l', 
    'м' => 'm', 'н' => 'n', 'о' => 'o', 'п' => 'p', 'р' => 'r', 'с' => 's', 
    'т' => 't', 'у' => 'u', 'ф' => 'f', 'х' => 'h', 'ц' => 'c', 'ч' => 'ch', 
    'ш' => 'sh', 'щ' => 'sch', 'ъ' => '', 'ы' => 'y', 'ь' => '', 'э' => 'e', 
    'ю' => 'yu', 'я' => 'ya' 
]; 

echo str_replace(array_keys($replace), $replace, $string); 
3

Życzenie I znaleziono wątek wcześniej.Funkcja zrobiłem (który zabrał mnie zbyt długo) jest poniżej:

function CheckLetters($field){ 
    $letters = [ 
     0 => "a à á â ä æ ã å ā", 
     1 => "c ç ć č", 
     2 => "e é è ê ë ę ė ē", 
     3 => "i ī į í ì ï î", 
     4 => "l ł", 
     5 => "n ñ ń", 
     6 => "o ō ø œ õ ó ò ö ô", 
     7 => "s ß ś š", 
     8 => "u ū ú ù ü û", 
     9 => "w ŵ", 
     10 => "y ŷ ÿ", 
     11 => "z ź ž ż", 
    ]; 
    foreach ($letters as &$values){ 
     $newValue = substr($values, 0, 1); 
     $values = substr($values, 2, strlen($values)); 
     $values = explode(" ", $values); 
     foreach ($values as &$oldValue){ 
      while (strpos($field,$oldValue) !== false){ 
       $field = preg_replace("/" . $oldValue . '/', $newValue, $field, 1); 
      } 
     } 
    } 
    return $field; 
} 
+1

To genialny kawałek kodu. Szczególnie do przeszukiwania baz danych, które mają niespójne dane. Używam go do przeszukiwania bazy danych krajów, która jest wypełniona danymi dostarczonymi przez użytkownika. To naprawdę pomaga w dodawaniu nieprawidłowo napisanej treści użytkownika. Wielkie kciuki ode mnie. –

+0

Dzięki za opinię. Niepoprawnie wpisana treść użytkownika jest właśnie powodem, dla którego została napisana :) – ChickenFeet

+0

po prostu sidenote, dodatkowe początkowe nawiasy na początku funkcji powinny zostać usunięte oczywiście –

1

CodeIgniter sposób:

$this->load->helper('text'); 

$string = convert_accented_characters($string); 

Funkcja ta wykorzystuje plik konfiguracyjny towarzysz application/config/foreign_chars.php do zdefiniowania celu i od tablicy do transliteracji.

https://www.codeigniter.com/user_guide/helpers/text_helper.html#ascii_to_entities

+1

1- Pytanie zadano więcej niż 2 lata temu. - Pytanie ma zaakceptowaną odpowiedź. 3- OP nie wspomniał o _CI Framework_ i używa _plain php_, więc twoja odpowiedź nie ma nic wspólnego z pytaniem. proszę zwrócić większą uwagę na pytania przed wysłaniem odpowiedzi – EhsanT

+0

Pomogło mi to po dniu frustracji. Naprawdę dobra odpowiedź na Codeigniter –

4

Od PHP> = 5.4.0

$translatedString = transliterator_transliterate('Any-Latin; Latin-ASCII; [\u0080-\u7fff] remove', $string); 
+0

działa jak urok – brnmonteiro