2012-04-14 6 views
30

Ho php document signup.php che salva il contenuto dal modulo (nel documento form.php) alla base MySQL. Il problema sorge quando voglio riformattare il contenuto di input. Voglio decodificare i caratteri UTF-8 come à-> a.PHP sostituendo caratteri speciali come à-> 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!?! 

Perché funziona perfettamente per $ chain, ma per $ first_name o $ last_name non funziona?

Inoltre provo

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šššš 

ma il problema, come si può vedere, è lo stesso!

+2

Fa il file hanno la codifica corretta? Le cose in $ _POST hanno la stessa codifica? (cioè quello impostato per il browser per visualizzare la pagina con?) Si potrebbe anche voler impostare il flag unicode per preg_replace – phant0m

+1

Come menziona phant0m, è necessario tenere sotto stretta osservazione tutte le codifiche. La codifica predefinita con POST è ISO-8859-1 a meno che tu non specifichi specificamente quale vuoi. (accept-charset = 'UTF-8') – dmp

+0

aggiunto un paio di funzioni di esempio :) – dmp

risposta

63

C'è un modo molto semplice per fare questo, utilizzando iconv - dalle note utente, questo sembra essere ciò che si vuole fare: 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! 
?> 

Essere molto coscienzioso con le codifiche dei caratteri, in modo da stai mantenendo la stessa codifica in tutte le fasi del processo: front end, invio di moduli, codifica dei file di origine. La codifica predefinita in PHP e nelle forme è ISO-8859-1, prima di PHP 5.4, dove è cambiata in UTF8 (finalmente!).

Ci sono un paio di funzioni che puoi giocare con idee. In primo luogo è dalla classe inflettore di CakePHP, chiamato 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); 
} 

Dipende da una matrice self::$_transliteration che è simile a quello che stavi facendo nella sua interrogazione - si può see the source for inflector on github.

Un'altra è una funzione che uso personalmente, quale 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; 
} 

Che quelle funzioni che fanno è traslitterare e creare 'slugs' da input di testo arbitraria, che è una cosa molto molto utile per avere nel vostro toolchest quando si effettuano applicazioni web. Spero che questo ti aiuti!

+2

Grazie per la risposta, il problema era che non ho aggiunto "accept-charset =" UTF-8 "" nel modulo. –

+0

benvenuto, immagino che tutte quelle funzioni non fossero realmente necessarie :) ma potrebbe anche dare un'occhiata. – dmp

+1

Ho continuato a utilizzare la mia funzione, perché con essa posso determinare esattamente con quale lettera sostituirò una lettera. –

5

La stringa $ chain ha lo stesso carattere di codifica dei caratteri nell'array: è possibile, anche probabile, che la stringa $ first_name si trovi in ​​una codifica diversa, quindi tali caratteri non corrispondono. Potresti provare a utilizzare invece le funzioni di stringa multibyte.

Prova mb_convert_encoding. Potresti anche provare a utilizzare HTML_ENTITIES come parametro to_encoding, quindi non devi preoccuparti di come i caratteri verranno convertiti: sarà molto prevedibile.

Supponendo che il vostro contributo a questo script è in UTF-8, probabilmente non è un brutto posto per iniziare ...

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

Ho provato questo e non lo è. echo $ first_name; // print áááááábéééééébšššš $ first_name = mb_convert_encoding ($ first_name, "HTML-ENTITIES", "UTF-8"); echo $ first_name; // print áááááábéééééébšššš –

+0

Grazie per la risposta, il problema era che non ho aggiunto "accept-charset =" UTF-8 "" nel modulo. –

14

Ecco un modo per avere una certa flessibilità in quello che dovrebbe essere scartato e quello che dovrebbe essere sostituito. Questo è il modo in cui attualmente lo faccio.

$ string = 'À una stringa con junk Ĩ Ä';

$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

desiderio I pensa che questa discussione prima.La funzione che ho fatto (che mi ha portato via troppo a lungo) è al di sotto:

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

Questo è un pezzo geniale di codice. Soprattutto per la ricerca di database con dati incoerenti. Lo uso per cercare un database di un paese che è pieno di dati forniti dall'utente. Questo aiuta davvero a non aggiungere un contenuto scritto in modo errato. Un grande pollice in alto da me. –

+0

Grazie per il feedback. Il contenuto utente immesso in modo errato è esattamente il motivo per cui questo è stato scritto :) – ChickenFeet

+0

solo un sidenote, le parentesi all'avvio devono essere rimosse ovviamente –

1

CodeIgniter modo:

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

$string = convert_accented_characters($string); 

Questa funzione utilizza un file di configurazione compagna application/config/foreign_chars.php per definire il da e per array per traslitterazione.

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

+1

1- La domanda è stata posta più di 2 anni fa 2- La domanda ha una risposta accettata. 3- L'OP non ha menzionato _CI Framework_ e sta usando _plain php_ così la tua risposta non ha nulla a che fare con la domanda. si prega di prestare maggiore attenzione alle domande prima di inviare una risposta – EhsanT

+0

Questo mi ha aiutato dopo una giornata di frustrazione .. Davvero una buona risposta per Codeigniter –

4

Dal PHP> = 5.4.0

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

funziona come un incantesimo – brnmonteiro