Pages :
Il existe tout un tas de fonction, mais apparament en UTF8 ca ne fonctionne pas très bien.

Une fonction trouvé sur expreg.com
<?php
$chaine='Hélène Dupont';
function ote_accent($str){
$ch = strtr($str,
      'ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïðòóôõöùúûüýÿ',
      'AAAAAACEEEEIIIIOOOOOUUUUYaaaaaaceeeeiiiioooooouuuuyy');
return $ch;
}
echo ote_accent($chaine);
?> 

Je crée un fichier avec le notepad, j'enregistre en UTF8 (le codage). Donc le fichier et les données sont en UTF8 ?
J'obtient ...
http://pix.nofrag.com/8/b/f/dc845b58504cc52001dff88b82aeb.png
Je bloque vraiment ...


Voila la page au complet :
<?php
function ote_accent($str)
{
$ch = strtr($str,
      'ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïðòóôõöùúûüýÿ',
      'aaaaaceeeeiiiiooooouuuuyaaaaaaceeeeiiiioooooouuuuyy');
return $ch;
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Document sans titre</title>
</head>
<body>
<?php
$chaine='Héléne Dupont';
echo $chaine.'<br />';
echo ote_accent($chaine);
?>
</body>
</html>

Modifié par SpaceCowboy (01 May 2008 - 17:36)
Et le rapport avec la choucroute?

Comme ce sujet n'a apparemment rien à voir avec HTML, je le déplace dans le salon Encodage et internationalisation. Smiley cligne

Pour le reste...
$ch = strtr($str,
      'ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïðòóôõöùúûüýÿ',
      'aaaaa[b][#red]ceeeeiiiiooooouuuuyaaaaaaceeeeiiiioooooouuuuyy[/#][/b]');
return $ch;
Il te manque un caractère dans la suite des caractères de remplacement.
Modérateur
Salut SpaceCowboy Smiley cligne ,

je pense que même avec le bon nombre de caractères ça ne pourra pas fonctionner car l'encodage de l'utf-8 est multi-octets et donc un caractère nécessite 2 octets (qu'on m'arrête si je me gourge Smiley langue ) alors que la fonction strtr remplace caractère par caractère. Une solution qui devrait marcher :

page_utf8.php (encodée en utf-8)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
	<head>
	<title>test</title>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<style type="text/css">
	</style>
	</head>
<body>
<?php
include('page_iso.php');
$chaine='Héléne Dupont';
echo $chaine.'<br />';
echo ote_accent($chaine);
?> 
</body>
</html>


page_iso.php (encodée en iso-8859-1)
<?php
function ote_accent($str){
$str = utf8_decode($str);
$ch = strtr($str,
      'ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïðòóôõöùúûüýÿ',
      'AAAAAACEEEEIIIIOOOOOUUUUYaaaaaaceeeeiiiioooooouuuuyy');
return utf8_encode($ch);
}
?>

D'autres solutions possibles (notamment un seul tableau dans la fonction avec des paires Smiley murf ) en regardant le lien...

A+
Modifié par Heyoan (01 May 2008 - 18:41)
Heyoan a écrit :
l'encodage de l'utf-8 est multi-octets et donc un caractère nécessite 2 octets (qu'on m'arrête si je me gourge Smiley langue )

Ben alors je t'arrête. L'encodage d'un caractère en UTF-8 prend de 1 à 4 octets suivant les cas. Les caractères ASCII sont codés sur un octet, et tous les autres sur 2 à 4 octets (plutôt 2 pour les caractères européens, 3 ou 4 pour les kanji du japonnais, etc.).

Heyoan a écrit :
alors que la fonction strtr remplace caractère par caractère.

Tu te contredis. Si la fonction remplace caractère par caractère, elle devrait être capable de remplacer un caractère par un autre quel que soit le nombre d'octets du caractère de départ et le nombre d'octets du caractère d'arrivée. C'est uniquement si elle remplace octet par octet que cela pose problème (ou bien s'il y a un autre problème de support d'UTF-8 un peu plus subtil Smiley cligne ).

Je tenterais l'utilisation de strtr avec un tableau de correspondance passé comme variable.
Hop, à tester:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
	<title>Test page</title>
	<style type="text/css" media="screen">
	body {
		margin: 100px 200px;
		background: #432;
		color: white;
		font-size: 1.5em;
	}
	</style>
</head>

<body>

<p>
<?php

function ote_accent_1($str) {
	$ch = strtr($str,
		'Àé',
		'Ae');
	return $ch;
}
function ote_accent_1_bis($str) {
	$ch = strtr($str,
		'Àé',
		'Éû');
	return $ch;
}
function ote_accent_2($str) {
	$table = array(
		'À' => 'A',
		'é' => 'e'
	);
	$ch = strtr($str, $table);
	return $ch;
}

$chaine = 'À Héléne Dupont';
echo $chaine.'<br />';
echo ote_accent_1($chaine).'<br />';
echo ote_accent_1_bis($chaine).'<br />';
echo ote_accent_2($chaine);

?>
</p>

</body>
</html>

Si on ne lui passe pas un tableau de correspondance en paramètre pour les remplacements, mais deux chaines de caractères, strtr a l'air de travailler octet par octet, effectivement. On le voit avec les fonctions ote_accent_1 et ote_accent_1_bis (dans la deuxième, on remplace des caractères faisant chacun deux octets (en UTF-8) par des caractères de deux octets également. Donc ça marche (quoi que ça puisse poser problème à d'autres caractères qui utiliseraient un de ces deux octets!). Mais s'il y a une différence entre le nombre d'octets d'un caractère de départ et de son caractère de remplacement, c'est la merde.

En passant par un tableau ça marche bien.
Modérateur
Florent V. a écrit :
Ben alors je t'arrête. L'encodage d'un caractère en UTF-8 prend de 1 à 4 octets suivant les cas. Les caractères ASCII sont codés sur un octet, et tous les autres sur 2 à 4 octets (plutôt 2 pour les caractères européens, 3 ou 4 pour les kanji du japonnais, etc.).
Arf Smiley ravi !

Florent V. a écrit :
C'est uniquement si elle remplace octet par octet que cela pose problème
C'est qu'est-ce que je voulais dire (double arf Smiley biggol !) mais je ne suis pas sûr non plus que ça fonctionne comme ça...
Hillo,

Petite reflexion bête : s'il est besoin de supprimer les caractères accentués, c'est qu'il est besoin de se limiter à un certain jeux de caractères. Alors pourquoi ne pas tout simplement appliquer un filtrage sur la base de ce jeux de caractères restreint ?

Parce que la question des caractères possibles peut aussi se poser plus que celle des caractères interdits. Dans ton cas, si des caractères spéciaux d'une autre langue sont entrés, que ce passera t-il ?

Définir des caractères interdits, ne garanti rien sur le résultat en sorti, puisqu'il pourra toujours éventuellement contenir des éléments imprévus, ce qui est assez possible, si on identifie pas clairement l'ensemble de sortie. Définir un jeu de caractères permis, ça offre déjà des résultats plus prévisibles.
Modifié par hibou57 (12 Apr 2009 - 02:20)
@hibou: Tu as tout à fait raison. J'étais peut-être jeune et naïf quand j'ai eu l'idée de cette fonction. En même temps elle fait ce qu'elle dit, elle enlève les accents des caractères accentués, et en bonus elle s'occupe également des ligatures.

En ce qui concerne "d'autre langues", et je pense tout de suite au chinois (parce que j'ai déjà travaillé en chinois), cette solution ne sert évidement à rien, et il faut recourir à la translittération.
Gofromiel a écrit :
@hibou: Tu as tout à fait raison. J'étais peut-être jeune et naïf quand j'ai eu l'idée de cette fonction. En même temps elle fait ce qu'elle dit, elle enlève les accents des caractères accentués, et en bonus elle s'occupe également des ligatures.

En ce qui concerne "d'autre langues", et je pense tout de suite au chinois (parce que j'ai déjà travaillé en chinois), cette solution ne sert évidement à rien, et il faut recourir à la translittération.

Ce que permet la fonction iconv (). Smiley cligne
Malheureusement les résultats produits par iconv() sont inconsistants suivant le système d'exploitation (peut-être aussi la version de PHP) :

Suivant le système (ou la version), "l'été est là" sera transformé en "L'ete est la" ou "L''et'e est l`a".

J'en parle dans mon billet.
Gofromiel a écrit :
J'en parle dans mon billet.

Billet qui oublie la solution strtr($chaine, $tableCorrespondance), non?
(Ah ok, ça dit à la fin que cette solution n'était pas souhaitée. Dommage cependant de laisser entendre que strtr est une solution nulle alors que ça peut être une solution fonctionnelle.)
Modifié par Florent V. (12 Jul 2010 - 13:04)
Modérateur
Florent V. a écrit :
Dommage cependant de laisser entendre que strtr est une solution nulle alors que ça peut être une solution fonctionnelle.
+1

D'autant plus qu'en utilisant des tableaux de translittération au lieu de chaines de caractères (comme indiqué plus haut dans le sujet) la solution fonctionnera aussi bien en LATIN1 qu'en UTF8 et que cela permet de rajouter autant de correspondances que souhaitées :
function oteAccents($str) {
	$translit = array('Á'=>'A','À'=>'A','Â'=>'A','Ä'=>'A','Ã'=>'A','Å'=>'A','Ç'=>'C','É'=>'E','È'=>'E','Ê'=>'E','Ë'=>'E','Í'=>'I','Ï'=>'I','Î'=>'I','Ì'=>'I','Ñ'=>'N','Ó'=>'O','Ò'=>'O','Ô'=>'O','Ö'=>'O','Õ'=>'O','Ú'=>'U','Ù'=>'U','Û'=>'U','Ü'=>'U','Ý'=>'Y','á'=>'a','à'=>'a','â'=>'a','ä'=>'a','ã'=>'a','å'=>'a','ç'=>'c','é'=>'e','è'=>'e','ê'=>'e','ë'=>'e','í'=>'i','ì'=>'i','î'=>'i','ï'=>'i','ñ'=>'n','ó'=>'o','ò'=>'o','ô'=>'o','ö'=>'o','õ'=>'o','ú'=>'u','ù'=>'u','û'=>'u','ü'=>'u','ý'=>'y','ÿ'=>'y');
	$str = strtr($str, $translit);
	return preg_replace('#[^a-zA-Z0-9\-\._]#', '_', $str); // Pour des noms de fichiers par exemple
}

Modifié par Heyoan (21 Sep 2010 - 11:42)
Bonjour Heyoan,

J'ai une question concernant ta fonction ci-dessus, qui fonctionne extrêmement bien.

Lorsque dans un même fichier PHP, je déclare la fonction et que je l'utilise sur une chaîne de caractères, ça fonctionne : "Télévision" devient "Television".

En revanche, lorsque je déclare la fonction dans mon fichier fonctions.php que j'inclue dans ma page où la fonction est utilisée, les caractères accentués sont mal remplacés : "Télévision" devient "Ta-la-vision"

Qu'est ce qui peut expliquer ça ?

Merci d'avance,
Rémy
uado a écrit :
"Télévision" devient "Ta-la-vision"

Qu'est ce qui peut expliquer ça ?

Je dirais que si ta page est en UTF-8, mais que ton fichier fonctions.php est en ISO-8859-1, c'est normal. Je ne sais pas exactement comment marche l'inclusion de fichiers en PHP vis-à-vis des codages de caractères, donc je ne peux pas détailler, mais "A-" c'est ce qui ressort de la fonction si tu lui donnes "é" en entrée, et "é" c'est l'interprétation en ISO-8859-1 d'un "é" en UTF-8 (c'est à dire que les octets sont les mêmes dans ces deux cas de figure).

Vérifie que tous tes fichiers utilisent bien le même codage (à priori UTF-8). Pas sûr que ça suffise, mais c'est la première chose à faire.
Gofromiel a écrit :
Malheureusement les résultats produits par iconv() sont inconsistants suivant le système d'exploitation (peut-être aussi la version de PHP) :

Suivant le système (ou la version), "l'été est là" sera transformé en "L'ete est la" ou "L''et'e est l`a".

J'en parle dans mon billet.


C'est parce qu'elle est dépendante du réglage Localisation de la machine, il faut précéder iconv() par

setlocale(LC_CTYPE, 'fr_FR.UTF-8'); 


pour que cela fonctionne correctement
Modérateur
Ah tiens ! J'avais loupé la question de Rémy.

Florent V. a écrit :
Vérifie que tous tes fichiers utilisent bien le même codage
+1


Dadou a écrit :
C'est parce qu'elle est dépendante du réglage Localisation de la machine, il faut précéder iconv() par
setlocale(LC_CTYPE, 'fr_FR.UTF-8'); 
pour que cela fonctionne correctement
Après avoir fait des tests sur différents systèmes ça n'est pas toujours le cas.

Toujours d'après ces tests le fonctionnement d'iconv varie également selon son implémentation. Extrait de code :
	// Traitement différent selon l'implémentation d'iconv (glibc ou libiconv)
	if(trim(ICONV_IMPL) == 'glibc') {
		$variable = iconv("UTF-8", "ISO-8859-15//TRANSLIT//IGNORE", $variable);
	} else {
		$variable = iconv("UTF-8", "ISO-8859-15//TRANSLIT", $variable);
	}
Du coup je vais dans le même sens que Gofromiel : en fonction de la configuration du serveur on n'aura pas toujours les mêmes résultats en utilisant iconv. Smiley murf
Modifié par Heyoan (07 Aug 2010 - 10:50)
Je me permet de proposer ma fonction.

Elle semble bien se comporter alors que j'utilise exclusivement l'utf8.

function supprimerAccent($cc)
	{
		$cc = str_replace(	array(
								'à', 'â', 'ä', 'á', 'ã', 'å',
								'î', 'ï', 'ì', 'í', 
								'ô', 'ö', 'ò', 'ó', 'õ', 'ø', 
								'ù', 'û', 'ü', 'ú', 
								'é', 'è', 'ê', 'ë', 
								'ç', 'ÿ', 'ñ', 'ý',
							),
							array(
								'a', 'a', 'a', 'a', 'a', 'a', 
								'i', 'i', 'i', 'i', 
								'o', 'o', 'o', 'o', 'o', 'o', 
								'u', 'u', 'u', 'u', 
								'e', 'e', 'e', 'e', 
								'c', 'y', 'n', 'y',
							),
							$cc
						);
		$cc = str_replace(	array(
								'À', 'Â', 'Ä', 'Á', 'Ã', 'Å',
								'Î', 'Ï', 'Ì', 'Í', 
								'Ô', 'Ö', 'Ò', 'Ó', 'Õ', 'Ø', 
								'Ù', 'Û', 'Ü', 'Ú', 
								'É', 'È', 'Ê', 'Ë', 
								'Ç', 'Ÿ', 'Ñ', 'Ý',
							),
							array(
								'A', 'A', 'A', 'A', 'A', 'A', 
								'I', 'I', 'I', 'I', 
								'O', 'O', 'O', 'O', 'O', 'O', 
								'U', 'U', 'U', 'U', 
								'E', 'E', 'E', 'E', 
								'C', 'Y', 'N', 'Y',
							),
							$cc
						);

		return $cc;				
	}


J'ai simplement complété une fonction trouvée sur le net ici : http://www.developpez.net/forums/d284411/php/langage/fonctions/suppression-daccents-utf-8-a/
fvsch a écrit :
Billet qui oublie la solution strtr($chaine, $tableCorrespondance), non?
(Ah ok, ça dit à la fin que cette solution n'était pas souhaitée. Dommage cependant de laisser entendre que strtr est une solution nulle alors que ça peut être une solution fonctionnelle.)


Quand je parle de solution toute nulle, cela n'est évidement pas un avis sur la fonction strtr, mais de son emploi dans ce cas précis.

La fonction que je propose répond à deux préoccupations :

1. Avoir une solution qui marche partout.
2. Pouvoir utiliser la même fonction quelque soit le jeu de caractères de la source.

C'est dommage, mais on ne peut pas compter sur ICONV. Comme l'a soulevé Heyoan, cela n'a rien à voir avec les paramètres de localisation (ou si peu), mais plutôt avec la version de la bibliothèque utilisée par PHP (libiconv ou glibc) : Avec glibc, "é" sera traduit en "e", avec GNU libiconv, ce sera "e’".

Concernant les tableaux de traductions, il suffit que la source ne soit pas dans le même jeu de caractères que le fichier dans lequel est déclarée la fonction, et c'est la merde. C'est pour cela que je n'en voulais pas.

La fonction que je propose n'est qu'un palliatif à une véritable solution qui tarde à venir. Il faut croire que j'en avais marre de voir la solution toute nulle partout, et de fouetter les stagiaires qui l'utilisaient Smiley smile
Modifié par Gofromiel (02 Feb 2011 - 15:19)
Pages :