Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Cohabitation pages iso-8859-1 et utf-8 avec includes communs

3 réponses
Avatar
Dominique Ottello
Bonjour,

PHP 5.3.1 - Apache 2.2.14 - MySQL 5.1.42
Windows XP SP3 (Nobody is perfect !)

Toutes les pages de mon site sont avec jeu de caractères ISO-8859-1.
Une évolution d'un forum que j'utilise fait passer celui-ci de
iso-8859-1 à utf-8 et son intégration dans mes pages utilise quatre
fichiers "include" eux-mêmes utilisés par un très grand nombre de mes
autres pages.
Je n'ai pas voulu effectuer des duplications codées utf-8 et renommées
desdits fichiers, ceux-ci étant susceptibles d'être modifiés aux cours
des évolutions du site, ce qui m'aurait obligé à une gestion
supplémentaire.

J'ai cherché une solution pérenne et automatique permettant d'utiliser
les « mêmes » fichiers soit en iso-8859-1 (base de référence) soit en
utf-8 et je pense avoir trouvé.

Dans le fichier « maître » servant à l'intégration du forum (utf-8),
j'ai créé une fonction de recodage de fichier :

//--------------------------
//Change le jeu de caractères du fichier $fichier de iso-8859-1 en utf-8
//sauve le fichier recodé avec ajout de "utf8" à la fin du nom
//retourne le chemin du fichier modifié.
function include_utf8($fichier) {
$input = file_get_contents($fichier);
$parties = pathinfo($fichier);
$outfile =
$parties['dirname']."/".$parties['filename']."utf8.".$parties['extension'];
file_put_contents($outfile,iconv("ISO-8859-1","UTF-8",$input));
return $outfile;
}
//premier include d'intégration
include(include_utf8('chemin_fichier_a_inclure.php'));
//-----------------------

Ce premier fichier sera donc recodé utf8 avant d'être inclu (Mais
l'original ne sera ni modifié, ni renommé).

Dans les autres fichiers à inclure en cascade (a inclut b qui inclut c
qui inclut d...) il suffit de modifier la ou les lignes d'inclusion
originale comme : include('chemin_du_fichier'); par

if(function_exists('include_utf8'))
include(include_utf8('chemin_du_fichier'));
else include('chemin_du_fichier');[/code]

Cela fonctionne apparemment très bien :
- Forum iso-8859-1 : http://aviatechno.free.fr/punbb/
- Forum utf-8 : http://aviatechno.free.fr/fluxbb/

Néanmoins, je me demande si je n'aurais pas créé un genre « d'usine à
gaz » et si il n'y aurait pas plus simple. Sans oublier que sous
Windows, recode_file(...) n'existe pas.

Merci.
--
Aujourd'hui, l'idéal du progrès est remplacé par l'idéal de l'innovation :
il ne s'agit pas que ce soit mieux, il s'agit seulement que ce soit nouveau,
même si c'est pire qu'avant et cela de toute évidence. Montherlant
Technologie aéronautique - http://ottello.net - Les anciens de Vilgénis

3 réponses

Avatar
Olivier Miakinen
Bonjour,

Le 24/01/2010 20:54, Dominique Ottello a écrit :

[...]

Dans le fichier « maître » servant à l'intégration du forum (utf-8),
j'ai créé une fonction de recodage de fichier :

//--------------------------
//Change le jeu de caractères du fichier $fichier de iso-8859-1 en utf-8
//sauve le fichier recodé avec ajout de "utf8" à la fin du nom
//retourne le chemin du fichier modifié.
function include_utf8($fichier) {
$input = file_get_contents($fichier);
$parties = pathinfo($fichier);
$outfile = $parties['dirname']."/".$parties['filename']."utf8.".$parties['extension'];
file_put_contents($outfile,iconv("ISO-8859-1","UTF-8",$input));
return $outfile;
}
//premier include d'intégration
include(include_utf8('chemin_fichier_a_inclure.php'));
//-----------------------



Je ne vois pas beaucoup plus simple pour faire ce que tu souhaites.

Si tu veux simplifier au maximum, tu peux remplacer l'appel à iconv()
par un utf8_encode($input) mais ce sont vraiment des économies de bouts
de chandelle.

En revanche, je ne vois pas pourquoi tu ne ferais pas l'include() à
l'intérieur même de include_utf8() :

------------------------------------------------------------------
function include_utf8($fichier) {
$input = file_get_contents($fichier);
$parties = pathinfo($fichier);
$outfile = $parties['dirname'] . "/" . $parties['filename']
. "utf8." . $parties['extension'];
file_put_contents($outfile,iconv("ISO-8859-1","UTF-8",$input));
include($outfile);
}
//premier include d'intégration
include_utf8('chemin_fichier_a_inclure.php');
------------------------------------------------------------------

[...]

Dans les autres fichiers à inclure en cascade (a inclut b qui inclut c
qui inclut d...) il suffit de modifier la ou les lignes d'inclusion
originale comme : include('chemin_du_fichier'); par

if(function_exists('include_utf8'))
include(include_utf8('chemin_du_fichier'));
else include('chemin_du_fichier');[/code]



Personnellement, je remplacerais *tous* les appels à include() par
un appel à une fonction commune, mettons include_any(), laquelle
détecterait elle-même si le charset est ISO-Latin1 ou UTF-8.

Un truc du genre :
------------------------------------------------------------------
function include_any($fichier) {
if (ord("é") == 0xE9) {
// é = E9 en ISO-Latin1
include($fichier);
return;
}
// é = C3 A9 en UTF-8
$input = file_get_contents($fichier);
$parties = pathinfo($fichier);
$outfile = $parties['dirname'] . "/" . $parties['filename']
. "utf8." . $parties['extension'];
file_put_contents($outfile,iconv("ISO-8859-1","UTF-8",$input));
include($outfile);
}
//include tenant compte du charset
include_any('chemin_fichier_a_inclure.php');
------------------------------------------------------------------

L'inconvénient de cette méthode, c'est qu'il faut définir include_any
dans chaque script de premier niveau (et surtout pas dans les scripts
inclus).

Une autre idée, c'est juste de définir une constante dans chacun des
scripts de premier niveau, soit un booléen qu'il conviendra de changer
de valeur en recodant le fichier, soit la chaîne de caractères "é" qui
changera de valeur automatiquement. Dans chacun de ces cas, la fonction
include_any peut être définie dans un tout premier include.

Quoi qu'il en soit je n'apporte pas d'idée révolutionnaire par rapport à
celle que tu as eue (et qui fonctionne) !

Néanmoins, je me demande si je n'aurais pas créé un genre « d'usine à
gaz » et si il n'y aurait pas plus simple.



C'est possible, mais encore une fois je ne vois pas plus simple. Dommage
que la fonction include() ne prévoie pas une option de transcodage !

--
Olivier Miakinen
Avatar
Dominique Ottello
Olivier Miakinen <om+ écrivait :

En revanche, je ne vois pas pourquoi tu ne ferais pas l'include() à
l'intérieur même de include_utf8() :



Parce que ça fiche le bocson :

Si l'inclusion intervient à l'intérieur d'une fonction, le code inclus
sera alors considéré comme faisant partie de la fonction et on se
retrouve avec un problème de portée des variables.

C'est possible, mais encore une fois je ne vois pas plus simple. Dommage
que la fonction include() ne prévoie pas une option de transcodage !



Une fonction include() avec une option de transcodage, ce serait
vraiment le pied ! Peut-être avec PHP 6

Merci pour ta réponse qui, entre autres, va me faire étudier
utf8_encode() que je ne connaisais pas bien que je regarde les docs php
très souvent (http://fr.php.net/manual/fr/)
--
Ce n'est pas parce que l'erreur se propage qu'elle devient vérité. Gandhi
Technologie aéronautique : http://aviatechno.free.fr (http://ottello.net)
Concorde dans la presse de 1965 à 2003 : http://le.pointu.free.fr
Avatar
Olivier Miakinen
Le 25/01/2010 16:59, Dominique Ottello m'a répondu :

En revanche, je ne vois pas pourquoi tu ne ferais pas l'include() à
l'intérieur même de include_utf8() :



Parce que ça fiche le bocson :

Si l'inclusion intervient à l'intérieur d'une fonction, le code inclus
sera alors considéré comme faisant partie de la fonction et on se
retrouve avec un problème de portée des variables.



Bon sang, mais c'est bien sûr ! Désolé.

C'est possible, mais encore une fois je ne vois pas plus simple. Dommage
que la fonction include() ne prévoie pas une option de transcodage !



Une fonction include() avec une option de transcodage, ce serait
vraiment le pied ! Peut-être avec PHP 6



Il semblerait que oui, à moins que ça ne concerne que file_get_contents
et file_put_contents :
<cit. http://fr.php.net/file_get_contents>
FILE_TEXT Depuis PHP 6, l'encodage par défaut pour la lecture des
données est UTF-8. Vous pouvez spécifier un encodage différent en créant
un contexte personnalisé ou en modifiant celui par défaut en utilisant
la fonction stream_default_encoding().
</cit.>

Cordialement,
--
Olivier Miakinen