Encore un problème d'accent

Résolu
Herve_be Messages postés 1123 Date d'inscription   Statut Membre Dernière intervention   -  
mamiemando Messages postés 33778 Date d'inscription   Statut Modérateur Dernière intervention   -

Bonjour,

Je ne parviens pas à résoudre une fois pour toutes mes problèmes d'accent,
par exemple j'appelle un script php comme ceci

<?php
header('Content-Type: text/html; charset=iso-8859-1');
$SubTitle="Sous-titre contenant é è ù ...";
include 'RVRTheader.php';

script du module inclus RVRTheader.php

<?php
header('Content-Type: text/html; charset=iso-8859-1');
Echo "<h3>titre contenant é è ù ..."</h3>"; // les accents sont bien reproduits
if (isset($SubTitl)) Echo "<h4>".$SubTitl."</h4>"; // è devient è
if (isset($SubTitl)) Echo "<h4>".utf8_encode($SubTitl)."</h4>"; // idem

Pourtant le module RVRTheader.php étant inclus dans le module appelant le tag h4 devrait être restitué comme le h3 qui précède non ?

Merci de m'aider

7 réponses

Bruno83200_6929 Messages postés 625 Date d'inscription   Statut Membre Dernière intervention   141
 

Bonjour,

Je vois bien ton souci , et oui, c’est le classique problème mélange UTF-8 / ISO-8859-1 qui fait apparaître les fameux è à la place des è.

Ton raisonnement est juste : puisque tu définis le header en ISO-8859-1, tu t’attends à ce que tout ton contenu en é è ù … sorte correctement.
Mais en pratique, il y a trois maillons de la chaîne qui doivent être cohérents :

L’encodage physique des fichiers PHP (le .php que tu as sauvegardé dans ton éditeur : UTF-8 ou ISO-8859-1).

Le header envoyé par PHP (Content-Type: text/html; charset=...).

Le <meta charset="..."> dans le HTML (qui doit correspondre).

Dans ton exemple, si le fichier qui contient é è ù est sauvegardé en UTF-8 mais que tu déclares charset=iso-8859-1, le navigateur ne sait pas comment interpréter les octets, et tu vois è à la place de è.

Pourquoi le h3 sort bien et pas le h4 ?

C’est probablement un typo : tu utilises $SubTitl au lieu de $SubTitle.

$SubTitl n’existe pas ⇒ isset($SubTitl) est false.

Du coup, rien ne devrait s’afficher dans le h4.

Quand tu testes avec utf8_encode($SubTitl), ça encode une chaîne vide ou mal définie, ce qui produit ce rendu bizarre.

Tu as deux chemins :

Recommandé : tout passer en UTF-8

Sauvegarde tous tes fichiers .php en UTF-8 sans BOM (dans ton éditeur, il y a une option « convertir / enregistrer en UTF-8 »).

Envoie l’entête correct :

header('Content-Type: text/html; charset=UTF-8');

Dans ton HTML, ajoute :

<meta charset="UTF-8">

Et surtout : n’utilise jamais utf8_encode() si tout est déjà cohérent.

Option B : rester en ISO-8859-1

Alors, assure-toi que tes fichiers .php sont bien enregistrés en ISO-8859-1 dans ton éditeur.

Garde :

header('Content-Type: text/html; charset=iso-8859-1');

Et n’utilise pas utf8_encode().

Ton problème ne vient pas de include, mais d’un mélange entre typo dans la variable et mauvais encodage du fichier.


3
Bruno83200_6929 Messages postés 625 Date d'inscription   Statut Membre Dernière intervention   141
 

Veux-tu que je te montre une petite méthode en PHP pour détecter automatiquement si tes fichiers sont sauvés en UTF-8 ou en ISO-8859-1 (genre avec mb_detect_encoding) ? Ça peut t’aider à repérer où ça coince.

0
Herve_be Messages postés 1123 Date d'inscription   Statut Membre Dernière intervention   10 > Bruno83200_6929 Messages postés 625 Date d'inscription   Statut Membre Dernière intervention  
 

Oui, merci.

0
Herve_be Messages postés 1123 Date d'inscription   Statut Membre Dernière intervention   10
 

Merci pour ton analyse,

D'abord l'erreur de typo vient du copier/coller, voici le script réel (j'ai supposé que l'include est fait)

<?php
header('Content-Type: text/html; charset=iso-8859-1');
$SubTitle="Sous-titre contenant é è ù ...";

// inclusion de 'RVRTheader.php';
<?php
header('Content-Type: text/html; charset=iso-8859-1');
if (isset($SubTitle)) Echo "<h3><b>".$SubTitle."</b></h3>";

Dans la partie html j'ai aussi
<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
Les 2 fichiers sont sauvés en ANSI.

J'ai mis charset=UTF-8 partout (dans les 2 fichiers, dans header et dans meta).
J'ai sauvé les 2 fichiers en UTF-8.

Maintenant les caractères accentués sont mal reproduits partout et pas seulement dans Subtitle !

Voici les 2 fichiers ANSI
https://www.rudyv.be/Aquarium/RVRT/RVRTerror.php
https://www.rudyv.be/Aquarium/RVRT/RVRTheader.php
et les 2 fichiers UTF-8
https://www.rudyv.be/Aquarium/RVRT/RVRTerrorUTF8.php
https://www.rudyv.be/Aquarium/RVRT/RVRTheaderUTF8.php




 

0
mamiemando Messages postés 33778 Date d'inscription   Statut Modérateur Dernière intervention   7 884
 

Bonjour,

Approche 1 : utiliser autant que possible de l'UTF-8 partout

C'est l'approche suggérée au travers des les réponses #1#5, #8, et #10. C'est le choix fait sous Linux et ça évite tous ces problèmes !

Pour cela, veille à utiliser de l'UTF8

  1. Au moment de sauver tes fichiers textes (dont le code PHP) assure-toi d'utiliser de l'UTF-8 (en particulier si tu utilises des caractères accentués)
  2. Au niveau de PHP php.ini (et c'est probablement là ton oubli). Par exemple, sous Linux, deux fichiers sont mis en jeu :
    • /etc/php/8.4/cli/php.ini
    • /etc/php/8.4/apache2/php.ini
    • Tout deux contiennent de nombreuses directives, dont celle qui nous intéresse. 
      default_charset = "UTF-8"
  3. Si ça ne suffit pas, au niveau du serveur web lui-même :
    • Soit dans la configuration de serveur web (e.g., httpd.conf)
    • Soit dans un .htaccess (si activé par ton serveur web), voir ici

Ainsi, l'encodage ne devrait jamais être une considération gérée dans le code (PHP ou HTML), sauf dans le cas très particulier où tu télécharges des données tierces qui ne sont pas en UTF-8. Dans toute autre situation, si tu utilises des fonctions comme utf8_encode ou utf8_decode, tu commets très probablement une erreur de design.

Approche 2 : s'affranchir de l'encodage

La solution (évoquée dans #6) consiste à corriger des caractères accentués par leur séquence HTML correspondante permet certes de s'affranchir de l'encodage mais pose plusieurs problèmes :

  • à moins d'utiliser (correctement) des outils comme sed ou équivalent, elle est extrêmement fastidieuse à mettre en œuvre (et sujette aux erreurs) ;
  • il faut par quoi substituer chaque caractère spéciaux ;
  • le code source des pages modifiées sera beaucoup moins lisible ;
  • le problème de fond (une gestion correcte de l'encodage) reste non résolu et continuera donc de se poser pour les futures pages.

Bonne chance

2
Herve_be Messages postés 1123 Date d'inscription   Statut Membre Dernière intervention   10
 

Les fichiers sont sauvés en UTF-8

.htaccess : AddCharset utf-8 .html .css .php .txt .js

php ini : default_charset = "UTF-8"

Résultat : Aucune erreur non corrigée

0
mamiemando Messages postés 33778 Date d'inscription   Statut Modérateur Dernière intervention   7 884 > Herve_be Messages postés 1123 Date d'inscription   Statut Membre Dernière intervention  
 

As-tu enlevé toute présence d'encodage forcé dans le code, notamment les :

header('Content-Type: text/html; charset=iso-8859-1');

Mêmes vérifications dans la configuration apache et de php. Si tu as modifié la configuration apache, pense à relancer apache pour que les changements soient pris en compte.

0
Bruno83200_6929 Messages postés 625 Date d'inscription   Statut Membre Dernière intervention   141
 

Re bonjour,

Je n'ai pas pu répondre avant.

Tu peux utiliser la fonction mb_detect_encoding() pour tester le contenu de tes variables (ou d’un fichier entier) et voir si elles sont en UTF-8, ISO-8859-1, etc.

Voici un petit exemple pratique :

<?php
// Exemple avec une variable
$SubTitle = "Sous-titre contenant é è ù ...";

$encodage = mb_detect_encoding($SubTitle, "UTF-8, ISO-8859-1, ISO-8859-15", true);

echo "Encodage détecté : " . $encodage . "<br>";

// Exemple avec un fichier
$contenu = file_get_contents("RVRTheader.php");
$encodageFichier = mb_detect_encoding($contenu, "UTF-8, ISO-8859-1, ISO-8859-15", true);

echo "Encodage fichier RVRTheader.php : " . $encodageFichier;
?>

Explication :

mb_detect_encoding() essaie de deviner l’encodage parmi ceux que tu lui donnes (ici : UTF-8, ISO-8859-1, ISO-8859-15).

Le troisième paramètre true force une détection stricte (plus fiable).

Tu peux tester une variable ou carrément tout le contenu d’un fichier avec file_get_contents().

Conseil :

Si tu vois que tes fichiers sont en UTF-8 mais que ton header envoie iso-8859-1, c’est là le problème.

Dans ce cas : passe tout en UTF-8 et oublie utf8_encode() / utf8_decode().

Je vais te donner un petit script PHP qui peut convertir automatiquement tes fichiers .php (ou .html, etc.) depuis ISO-8859-1 vers UTF-8 sans BOM.

Avant de lancer ça : fais une sauvegarde de ton projet (copie du dossier) — car la conversion écrase les fichiers.

<?php
/**
 * Convertit tous les fichiers .php et .html d'un dossier
 * de ISO-8859-1 vers UTF-8 (sans BOM).
 */

$dir = __DIR__; // Dossier courant (ou mets le chemin absolu ici)

$rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir));

foreach ($rii as $file) {
    if ($file->isDir()) continue;

    $ext = strtolower(pathinfo($file->getFilename(), PATHINFO_EXTENSION));

    // On cible uniquement .php et .html (tu peux en rajouter)
    if (!in_array($ext, ['php', 'html', 'htm'])) continue;

    $filePath = $file->getPathname();
    $content = file_get_contents($filePath);

    // Détection d'encodage
    $enc = mb_detect_encoding($content, ['UTF-8', 'ISO-8859-1', 'ISO-8859-15'], true);

    if ($enc === 'ISO-8859-1' || $enc === 'ISO-8859-15') {
        echo "Conversion : $filePath ($enc → UTF-8)\n";
        $utf8Content = mb_convert_encoding($content, 'UTF-8', $enc);
        file_put_contents($filePath, $utf8Content);
    } elseif ($enc === 'UTF-8') {
        echo "Déjà en UTF-8 : $filePath\n";
    } else {
        echo "Encodage inconnu : $filePath ($enc)\n";
    }
}

echo "✅ Conversion terminée.\n";

Ce que fait ce script

Il parcourt récursivement tous les fichiers d’un dossier.

Détecte l’encodage (UTF-8, ISO-8859-1, ISO-8859-15).

Si c’est du ISO-8859-1, il convertit en UTF-8.

Écrase le fichier avec la version convertie (d’où la sauvegarde indispensable).

Étapes à suivre

Sauvegarde ton projet.

Crée un fichier convert.php avec ce code, mets-le dans le dossier racine de ton site.

Lance dans ton navigateur ou via CLI :

php convert.php

Mets ensuite dans ton code :

header('Content-Type: text/html; charset=UTF-8');

et dans tes pages HTML :

<meta charset="UTF-8">

Après ça, tu es tranquille, plus de utf8_encode() ni è


1
Herve_be Messages postés 1123 Date d'inscription   Statut Membre Dernière intervention   10
 

Bonjour,
Je n'ai pas pu répondre avant :-)

J'ai essayé mb_detect_encoding sur les 2 fichiers, résultat :
Encodage fichier RVRTheaderUTF8.php : UTF-8
Encodage fichier RVRTerrorUTF8.php : UTF-8

Pourtant j'ai toujours
heRVé Reef Tools
Utilitaires pour aquarium récifal
Dernière version : 250807

alors que j'ai bien

header('Content-Type: text/html; charset=UTF-8');
?>
<meta http-equiv=Content-Type content="text/html; charset=UTF-8">
0
Bruno83200_6929 Messages postés 625 Date d'inscription   Statut Membre Dernière intervention   141
 

D’après ce que tu montres :

tes fichiers sont bien UTF-8 

tes headers/<meta> sont en UTF-8

et pourtant tu obtiens encore des é, è…

Ça veut dire une chose très précise :

le texte a déjà été encodé deux fois (double encodage).

Exemple typique

Tu as é en UTF-8 → octets 0xC3 0xA9

Si ce texte est pris pour de l’ISO-8859-1 et reconverti en UTF-8 → ça devient é

C’est exactement ce que tu observes (é, è, è).

Causes possibles

Tu as utilisé utf8_encode() quelque part → ça re-convertit un texte déjà en UTF-8, et ça casse tout.
→ Solution : supprimer tous les utf8_encode() / utf8_decode() de ton projet.

Ton serveur applique une configuration par défaut ISO-8859-1 (Apache ou PHP).
→ Vérifie dans php.ini s’il existe une ligne :

default_charset = "UTF-8"

(ou mets-la si elle n’existe pas).
→ Vérifie aussi qu’il n’y a pas de .htaccess qui force AddDefaultCharset ISO-8859-1.

Ton éditeur/FTP ré-encode les fichiers en les envoyant (certains clients FTP convertissent encore en latin1…).

Plan de correction

Supprime toutes les fonctions utf8_encode() et utf8_decode().

Vérifie qu’au tout début de tes scripts tu as bien :

header('Content-Type: text/html; charset=UTF-8');

Vérifie que tu n’as aucun espace, ni BOM avant le <?php de tes fichiers.
→ En UTF-8 sans BOM.

Mets dans php.ini ou .htaccess :

AddDefaultCharset UTF-8

et/ou

default_charset = "UTF-8"

Je t'ai écris un petit script de test minimal (10 lignes max) que tu pourras lancer sur ton serveur pour vérifier si le serveur lui-même renvoie bien UTF-8, indépendamment de tes fichiers ?

<?php
// test_utf8.php

// Force l'en-tête UTF-8
header('Content-Type: text/html; charset=UTF-8');

// Vérification côté PHP
echo "<pre>";
echo "default_charset = " . ini_get("default_charset") . "\n";
echo "mb_internal_encoding = " . mb_internal_encoding() . "\n";
echo "</pre>";

// Test d'affichage de caractères accentués
echo "<h2>Affichage direct :</h2>";
echo "é è ù à ç ô É È Ù À Ç Ô <br>";

$texte = "héRvé Reef Tools - dernière version";
echo "<h2>Depuis variable PHP :</h2>";
echo $texte;

Ce que ça doit donner dans ton navigateur

Un petit bloc <pre> avec :

default_charset = UTF-8
mb_internal_encoding = UTF-8

(si tu vois ISO-8859-1, ton PHP est mal configuré).

Deux lignes de texte :

é è ù à ç ô É È Ù À Ç Ô
héRvé Reef Tools - dernière version

Les accents doivent être nickels.

Si ça s’affiche bien ici mais pas dans tes scripts → problème dans ton code (double utf8_encode() ou variable déjà mal encodée).

Si ça s’affiche mal même ici → problème serveur (Apache/PHP envoie du ISO-8859-1 malgré tout).

Si tu veux je t’indique comment corriger côté serveur si tu vois que default_charset ≠ UTF-8 dans ce test ?


1
Herve_be Messages postés 1123 Date d'inscription   Statut Membre Dernière intervention   10
 

Tu as utilisé utf8_encode() quelque part → ça re-convertit un texte déjà en UTF-8, et ça casse tout.
→ Solution : supprimer tous les utf8_encode() / utf8_decode() de ton projet.
Exact, dans RVRTheader.php
if (isset($SubTitl2)) Echo "<h4><b>".utf8_encode($SubTitl2)."</b></h4>"; 
if (isset($SubTitl3)) Echo "<h5><b>".utf8_encode($SubTitl3)."</b></h5>"; 
Je les ai supprimés mais ça ne fonctionne toujours pas.


Ton serveur applique une configuration par défaut ISO-8859-1 (Apache ou PHP).
→ Vérifie dans php.ini s’il existe une ligne :

default_charset = "UTF-8"
(ou mets-la si elle n’existe pas).
→ Vérifie aussi qu’il n’y a pas de .htaccess qui force AddDefaultCharset ISO-8859-1.
php.ini contient seulement
<?php
date.timezone = "Europe/Brussels"
file_uploads = On
?>

Je t'ai écris un petit script de test minimal (10 lignes max) que tu pourras lancer sur ton serveur pour vérifier si le serveur lui-même renvoie bien UTF-8, indépendamment de tes fichiers ?

default_charset = UTF-8
mb_internal_encoding = UTF-8
Affichage direct :
é è ù à  Ã§ ô É È Ù À Ç Ô
Depuis variable PHP :
héRvé Reef Tools - dernière version

Si ça s’affiche bien ici mais pas dans tes scripts → problème dans ton code (double utf8_encode() ou variable déjà mal encodée).

Si ça s’affiche mal même ici → problème serveur (Apache/PHP envoie du ISO-8859-1 malgré tout).

Si tu veux je t’indique comment corriger côté serveur si tu vois que default_charset ≠ UTF-8 dans ce test ?

1

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
mamiemando Messages postés 33778 Date d'inscription   Statut Modérateur Dernière intervention   7 884
 

Bonjour,

Concernant #15

C'est un problème assez commun, pour lequel tu trouveras de nombreuses discussions sur Internet.

En bref, si le système de fichiers utilisé par ton disque dur est en iso-8859-1 alors scandir renvoie des chaînes de caractères en iso-8859-1. Comme ton code part du principe que tout est utf8, il s'ensuit un problème d'encodage.

Pour résoudre ce problème il faut :

  • soit utiliser un système de fichiers lui-même en utf8 (c'est le parti pris sous Linux) ;
  • soit convertir le système de fichier en question en utf8 (voir par exemple ici), mais tu peux avoir potentiellement d'autres effets de bord suite à cette conversion ;
  • soit dans le code PHP, faire l'éventuelle conversion, comme proposé ici.
    • Si tu pars sur cette approche, l'idéal serait sans doute d'envelopper cette considération dans une fonction dédiée (disons my_scandir) à laquelle tu feras appel dans le reste de ton code et qui mettra en jeu les fonctions suivantes :

Bonne chance

1
Herve_be Messages postés 1123 Date d'inscription   Statut Membre Dernière intervention   10
 

utf8_encode donne Sars-la-Bruyère

utf8_decode donne Sars-la-Bruyère : OK

Merci

0
mamiemando Messages postés 33778 Date d'inscription   Statut Modérateur Dernière intervention   7 884 > Herve_be Messages postés 1123 Date d'inscription   Statut Membre Dernière intervention  
 

Merci pour ton retour @Herve_be StatutMembre

  • Si tu as toutes tes réponses, merci de voter pour les différents messages qui t'ont aidé et de marquer le problème en résolu.
  • Sinon, merci d'indiquer quels points restent à régler.

Bonne continuation :-)

1
Herve_be Messages postés 1123 Date d'inscription   Statut Membre Dernière intervention   10
 

Bonjour,

Grand merci pour votre aide, maintenant ça fonctionne sauf dans un cas : l'affichage du nom des fichiers

<?php
header('Content-Type: text/html; charset=utf-8'); // pour éviter les ?
$dir = 'Itineraires';
$files = scandir($dir);
sort($files);
foreach ($files as $file)
	{
...
	echo "<TD>".$file."</TD>"; // Libellé
...

par exemple pour le fichier "Sars-la-Bruyère.xml" j'obtiens "Sars-la-Bruyère.xml".

Le script php est bien sauvé en UTF-8 !

0
Utilisateur anonyme
 

Bonjour,

Le problème est lié à l'html. Les caractère étandus s'écrivent é pour le é &grave pour le è et ainsi de suite il te faut trouver sur internet la table de conv

Caractères réservés HTML

Ces caractères ont une signification particulière en HTML, donc il faut les encoder pour les afficher correctement :

&lt; → <

&gt; → >

&amp; → &

&quot; → "

&apos; → '



---

2. Caractères accentués (latin étendu)

Très utiles pour les langues comme le français :

&eacute; → é

&egrave; → è

&ecirc; → ê

&ccedil; → ç

&agrave; → à

&ocirc; → ô

&iuml; → ï
-1
Herve_be Messages postés 1123 Date d'inscription   Statut Membre Dernière intervention   10
 

Je viens d'ajouter des caractères < et > dans un paramètre $Subtitle
ils sont correctement reproduits.

Je ne peux quand même pas remplacer tous les caractères accentués par &xxxx; !

D'ailleurs dans la plupart de mes scripts ils ne le sont pas et sont pourtant correctement rendus, exemple https://www.rudyv.be/Aquarium/RVRT/RVRT.php

0
Utilisateur anonyme > Herve_be Messages postés 1123 Date d'inscription   Statut Membre Dernière intervention  
 

Ton script provient de sources différentes. Une en UTF-8 qui correspond à l'encodage par défaut a l'encodage de ton site et d'un texte qui provient certainement de copier-coller d'un encodages iso.

Soit tu utilises une fonction php pour encoder le zones litigieuses. Soit tu fais un replace dans ton éditeur avec & eacute; par exemple. Soit réécrire ton HTML avec le bon encodages. 

Il existe des convertisseurs iso UTF-8 accessoirement mais attention à ne pas envenimer la situation.

Personnellement, sauf pour les valeurs sauvegardé en base de données, je ne laisse pas au navigateur le choix d'afficher de irogliphes.

0