Problème d'interaction UTF-8 (forcé dans php.ini) et latin1

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : Problème d'interaction UTF-8 (forcé dans php.ini) et latin1

par Tracker » 28 oct. 2007, 10:49

Une petite remarque supplémentaire que j'ai remarqué après coup. Ca peut sembler évident aux anciens mais je ne savais pas que :

ISO-8859-1 = latin1 = cp1252


Je pensais que l'iso était encore autre chose, et ça m'a posé problème.
pas tout à fait,
je crois que c'est: ISO-8859-1 = latin1_swedish = cp1252
c'est pour ça que c'est le réglage par défaut de mysql


Tracker.

par Masahiro » 28 oct. 2007, 10:42

Une petite remarque supplémentaire que j'ai remarqué après coup. Ca peut sembler évident aux anciens mais je ne savais pas que :

ISO-8859-1 = latin1 = cp1252


Je pensais que l'iso était encore autre chose, et ça m'a posé problème.

par Masahiro » 25 oct. 2007, 12:55

Re-bonjour,


Je n'ai pas eu le temps de m'y mettre ces jours-ci. Ton script fonctionne parfaitement, merci pour ton aide une fois de plus.

J'espère que ça servira à d'autres.

par Tracker » 21 oct. 2007, 15:56

Re,

Bon j'ai mis un peu de temps, l'entête de ton fichier xml ne contient pas la balise 'encoding', mais ça n'a pas d'incidence quand tu charges le fichier via SimpleXML.

En fait tu oublies simplement d'indiquer à MySQL l'encodage des caractères que tu lui transmets.
J'ai fait un test qui fonctionne avec le code suivant:
header('Content-type: text/html; charset=utf-8');
$cnx = mysql_connect('localhost','root','');
mysql_select_db('test1',$cnx);

//Ligne à ajouter <<--------------------------------------------
mysql_query("set names 'utf8'");
	
$time_start = microtime(true);
$i = 0;

echo '<p>Insertion des <i>Kanji</i><br />';

$xml = simplexml_load_file('c:\\downloads\\kanjidic2.xml');
foreach ($xml->character as $char)
{
    $i++;
    $literal = $char->literal;
    echo $literal.'<br/>';
        
    $sql = 'INSERT INTO `dico_kanji` (`literal` ) VALUES ("'. $literal .'");';
    $req = mysql_query($sql) or die('Erreur SQL !<br>'. $sql .'<br>'. mysql_error());
}
$time_end = microtime(true);
$time = round($time_end - $time_start,2);

echo '<br />
<i>Kanji</i> insérés avec succès ('. $i .' entrées) <font color="grey">'. $time .' sec.</font></p>';
?>
Par contre tes caractères ne sont pas forcement visibles (remplacés par des carrés dans IE, ou des ? dans FF) si aucun glyph correspondant n'est disponible dans la police d'affichage.
Les Kanjis sont utilisables avec cette police

Rq1:
Un truc est étrange: tous tes champs en base sont NOT NULL, sans valeur par défaut, et on arrive quand même à inserer des lignes en ne donnant que le champ 'litéral' ??!! C'est sûrement le moteur MyISAM qui le permet, c'est n'importe quoi...

Rq2:
Attention à enregistrer ton code php en uft8, sinon les caractères accentuées tapés en dur à l'intérieur seront érronnés.


Tracker.

par Masahiro » 21 oct. 2007, 11:45

Salut Tracker ! Merci de m'accorder un peu de ton temps.

Voici la structure :

Code : Tout sélectionner

-- Structure de la table `dico_kanji` -- CREATE TABLE `dico_kanji` ( `id` smallint(5) unsigned NOT NULL auto_increment, `literal` varchar(10) NOT NULL, `cp_type_ucs` char(4) NOT NULL, `cp_type_jis208` varchar(5) NOT NULL, `cp_type_jis212` varchar(5) NOT NULL, `cp_type_jis213` varchar(7) NOT NULL, `rad_type_classical` varchar(254) NOT NULL, `rad_type_nelson_c` varchar(255) NOT NULL, `misc_grade` varchar(255) NOT NULL, `misc_stroke_count` varchar(255) NOT NULL, `misc_var_type_jis208` varchar(5) NOT NULL, `misc_var_type_jis212` varchar(255) NOT NULL, `misc_var_type_jis213` varchar(255) NOT NULL, `misc_var_type_deroo` varchar(255) NOT NULL, `misc_var_type_njecd` varchar(255) NOT NULL, `misc_var_type_s_h` varchar(255) NOT NULL, `misc_var_type_nelson_c` varchar(255) NOT NULL, `misc_var_type_oneill` varchar(255) NOT NULL, `misc_var_type_ucs` varchar(255) NOT NULL, `dr_type_nelson_c` varchar(4) NOT NULL, `dr_type_nelson_n` varchar(4) NOT NULL, `dr_type_halpern_njecd` varchar(4) NOT NULL, `dr_type_halpern_kkld` varchar(4) NOT NULL, `dr_type_heisig` varchar(4) NOT NULL, `dr_type_gakken` varchar(4) NOT NULL, `dr_type_oneill_names` varchar(5) NOT NULL, `dr_type_oneill_kk` varchar(4) NOT NULL, `dr_type_moro` varchar(7) NOT NULL, `dr_type_m_vol` varchar(255) NOT NULL, `dr_type_m_page` varchar(4) NOT NULL, `dr_type_henshall` varchar(4) NOT NULL, `dr_type_sh_kk` varchar(4) NOT NULL, `dr_type_sakade` varchar(255) NOT NULL, `dr_type_jf_cards` varchar(255) NOT NULL, `dr_type_henshall3` varchar(255) NOT NULL, `dr_type_tutt_cards` varchar(255) NOT NULL, `dr_type_crowley` varchar(255) NOT NULL, `dr_type_kanji_in_context` varchar(4) NOT NULL, `dr_type_busy_people` varchar(255) NOT NULL, `dr_type_kodansha_compact` varchar(4) NOT NULL, `q_type_skip` varchar(255) NOT NULL, `q_type_sh_desc` varchar(9) NOT NULL, `q_type_four_corner` varchar(6) NOT NULL, `q_type_deroo` varchar(255) NOT NULL, `q_type_misclass` varchar(255) NOT NULL, `r_type_pinyin` varchar(8) NOT NULL, `r_type_korean_r` varchar(255) NOT NULL, `r_type_korean_h` varchar(255) NOT NULL, `r_type_ja_on` varchar(255) NOT NULL, `r_type_ja_kun` varchar(80) NOT NULL, `meaning_m_lang_en` varchar(167) NOT NULL, `meaning_m_lang_es` varchar(153) NOT NULL, `meaning_m_lang_pt` varchar(146) NOT NULL, `meaning_m_lang_de` varchar(0) NOT NULL, `reading_nanori` text NOT NULL, PRIMARY KEY (`id`), KEY `literal` (`literal`), KEY `cp_type_ucs` (`cp_type_ucs`), KEY `cp_type_208` (`cp_type_jis208`), KEY `cp_type_212` (`cp_type_jis212`), KEY `cp_type_213` (`cp_type_jis213`), KEY `rad_type_classical` (`rad_type_classical`), KEY `rad_type_nelson_c` (`rad_type_nelson_c`), KEY `misc_grade` (`misc_grade`), KEY `misc_stroke_count` (`misc_stroke_count`), KEY `misc_var_type_jis208` (`misc_var_type_jis208`), KEY `misc_var_type_jis212` (`misc_var_type_jis212`), KEY `misc_var_type_jis213` (`misc_var_type_jis213`), KEY `misc_var_type_deroo` (`misc_var_type_deroo`), KEY `misc_var_type_njecd` (`misc_var_type_njecd`), KEY `misc_var_type_s_h` (`misc_var_type_s_h`), KEY `misc_var_type_nelson_c` (`misc_var_type_nelson_c`), KEY `misc_var_type_oneill` (`misc_var_type_oneill`), KEY `misc_var_type_ucs` (`misc_var_type_ucs`), KEY `dr_type_nelson_c` (`dr_type_nelson_c`), KEY `dr_type_nelson_n` (`dr_type_nelson_n`), KEY `dr_type_halpern_njecd` (`dr_type_halpern_njecd`), KEY `dr_type_halpern_kkld` (`dr_type_halpern_kkld`), KEY `dr_type_heisig` (`dr_type_heisig`), KEY `dr_type_gakken` (`dr_type_gakken`), KEY `dr_type_oneill_names` (`dr_type_oneill_names`), KEY `dr_type_oneill_kk` (`dr_type_oneill_kk`), KEY `dr_type_moro` (`dr_type_moro`), KEY `dr_type_m_vol` (`dr_type_m_vol`), KEY `dr_type_m_page` (`dr_type_m_page`), KEY `dr_type_henshall` (`dr_type_henshall`), KEY `dr_type_sh_kk` (`dr_type_sh_kk`), KEY `dr_type_sakade` (`dr_type_sakade`), KEY `dr_type_jf_cards` (`dr_type_jf_cards`), KEY `dr_type_henshall3` (`dr_type_henshall3`), KEY `dr_type_tutt_cards` (`dr_type_tutt_cards`), KEY `dr_type_crowley` (`dr_type_crowley`), KEY `dr_type_kanji_in_context` (`dr_type_kanji_in_context`), KEY `dr_type_kodansha_compact` (`dr_type_kodansha_compact`), KEY `q_type_skip` (`q_type_skip`), KEY `q_type_sh_desc` (`q_type_sh_desc`), KEY `q_type_four_corner` (`q_type_four_corner`), KEY `q_type_deroo` (`q_type_deroo`), KEY `r_type_pinyin` (`r_type_pinyin`), KEY `r_type_korean_r` (`r_type_korean_r`), KEY `r_type_korean_h` (`r_type_korean_h`), KEY `r_type_ja_on` (`r_type_ja_on`), KEY `r_type_ja_kun` (`r_type_ja_kun`), KEY `dr_type_busy_people` (`dr_type_busy_people`), KEY `q_type_misclass` (`q_type_misclass`) ) ENGINE=MyISAM AUTO_INCREMENT=16582 DEFAULT CHARSET=utf8 AUTO_INCREMENT=16582 ;

Concernant le XML, il est un peu gros (15 Mo), mais ça devrait aller vite à l'époque du haut débit :-)

http://www.grossebertha.net/database/di ... jidic2.xml (note le super nom de domaine)

par Tracker » 21 oct. 2007, 10:46

Salut,

Tu peux filer ton fichier XML et la stucture de ta table (create table ...) ?



Tracker.

Problème d'interaction UTF-8 (forcé dans php.ini) et latin1

par Masahiro » 21 oct. 2007, 10:16

Bonjour,


J'ai décidé de laisser un message ici après plusieurs heures à farfouiller un peu partout.

Mon serveur force l'utilisation de l'UTF-8 dans php.ini. Ici apparemment, ça pose problème.

Voici ma source (en partie) :
if (isset($_GET['step']) && $_GET['step'] == 1)
{
	$time_start = microtime(true);
	$i = 0;
	echo '<p>Insertion des <i>Kanji</i><br />';
	foreach ($xml->character as $char)
	{
		$i++;
		$literal = $char->literal;
		//$literal = utf8_to_html($char->literal);
		//$literal = mb_convert_encoding($char->literal, "latin1", "UTF-8");
		//mysql_query("SET NAMES 'latin1'");
		//$literal = utf8_decode($literal);
		echo $literal .'<br>';
		
		$sql = 'INSERT INTO `dico_kanji` ( `id` , `literal` ) VALUES (NULL , "'. $literal .'");';
		if (isset($_GET['action']) && $_GET['action'] == 1) $req = @mysql_query($sql) or die('Erreur SQL !<br>'. $sql .'<br>'. mysql_error());
		//echo '<img src="../images/bar.gif" alt="bar"/>';
	}
	$time_end = microtime(true);
	$time = round($time_end - $time_start,2);
	echo '<br />
	<i>Kanji</i> insérés avec succès ('. $i .' entrées) <font color="grey">'. $time .' sec.</font></p>';
	if (isset($_GET['action']) && $_GET['action'] == 1)
	{
		echo '<a href="./kanjidic2.php?action=1&step=2">Etape suivante</a>';
	}
	else
	{
		echo '<a href="./kanjidic2.php?step=2">Etape suivante</a>';
	}
}

Alors, je vous explique ma démarche :

Il y a un document XML que je dois parser, il n'y a pas de souci à ce niveau. Je le fais avec simpleXML.

Les entrées "literal" sont des caractères japonais encodées en UTF-8. Apparemment, il y a un souci quand l'UTF-8 est forcé, soit disant il part du principe que l'encodage de base est latin1 (cp1252) et du coup, il encode une seconde fois en UTF-8, ce qui donne un résultat incorrect.

Voici plus de détail sur le problème :

http://dev.mysql.com/doc/refman/5.1/en/ ... -sets.html


Ils indiquent de faire un dump mais moi je ne veux pas faire ça ! Je veux convertir à la volée et injecter l'enregistrement dans la BDD.

Je suis sur que c'est trois fois rien à faire, mais j'en ai un peu marre. Merci de m'accorder un peu de votre temps !