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

[SF] Probleme de __toString avec ac cents

3 réponses
Avatar
Jeremie
Bonjour à tous,

J'ai développé une appli symfony sous Linux, nickel chrome.
En la déployant chez mon client, sur un serveur W2K8, un phénomène
étrange apparaît :

lorsque j'utilise ce bout de code <?php echo $stagiaire ?>, où
$stagiaire est un objet Stagiaire venant de mon modèle, si la valeur
contient des accents, rien n'apparaît, alors que les valeurs sans
accents apparaissent sans problème.

Pour indication, ma classe stagiaire est ainsi :

<?php
class Stagiaire extends BaseStagiaire
{
public function __toString()
{
return ucwords(strtolower($this->nom . ' ' . $this->prenom));
}
...
}

J'ai tenté d'utiliser des accesseurs, mais ce n'est pas ça.

Auriez-vous une idée ?

Merci d'avance,

Jérémie

3 réponses

Avatar
Olivier Miakinen
Bonjour,

Le 10/05/2010 11:36, Jeremie a écrit :

[...] si la valeur
contient des accents, rien n'apparaît, alors que les valeurs sans
accents apparaissent sans problème.



Comme tu n'indiques ni le jeu de caractères supposé de ta variable, ni
celui du fichier, ni celui annoncé dans les entêtes HTTP, je suppose que
tu ne sais pas ce que c'est. Alors avant de continuer la discussion
voici une lecture indispensable :
<http://french.joelonsoftware.com/Articles/Unicode.html>.

Pour indication, ma classe stagiaire est ainsi :

<?php
class Stagiaire extends BaseStagiaire
{
public function __toString()
{
return ucwords(strtolower($this->nom . ' ' . $this->prenom));
}
...
}



Ah. Si tu veux pouvoir utiliser strtolower() sur autre chose que de
l'Ascii (lequel ne comprend aucune lettre accentuée), il faut préciser
la « locale », mais avec le risque de faire buguer tout un tas d'autres
appels de fonction ; quant à ucwords, je ne sais même pas s'il a une
chance de fonctionner.

Une idée (non testée, et dépend de $encoding) :
return mb_convert_case(
mb_strtolower($this->nom . ' ' . $this->prenom, $encoding),
MB_CASE_TITLE, $encoding);

Ou bien :
mb_internal_encoding($encoding);
return mb_convert_case(
mb_strtolower($this->nom . ' ' . $this->prenom), MB_CASE_TITLE);

Cordialement,
--
Olivier Miakinen
Avatar
Jeremie
Le 10/05/2010 12:08, Olivier Miakinen a écrit :
Bonjour,

Le 10/05/2010 11:36, Jeremie a écrit :

[...] si la valeur
contient des accents, rien n'apparaît, alors que les valeurs sans
accents apparaissent sans problème.



Comme tu n'indiques ni le jeu de caractères supposé de ta variable, ni
celui du fichier, ni celui annoncé dans les entêtes HTTP, je suppose que
tu ne sais pas ce que c'est. Alors avant de continuer la discussion
voici une lecture indispensable :
<http://french.joelonsoftware.com/Articles/Unicode.html>.



Pardon pour cet oubli, en fait toute l'appli est codée en UTF-8
(définition dans les fichiers de conf symfony).

Pour indication, ma classe stagiaire est ainsi :

<?php
class Stagiaire extends BaseStagiaire
{
public function __toString()
{
return ucwords(strtolower($this->nom . ' ' . $this->prenom));
}
...
}



Ah. Si tu veux pouvoir utiliser strtolower() sur autre chose que de
l'Ascii (lequel ne comprend aucune lettre accentuée), il faut préciser
la « locale », mais avec le risque de faire buguer tout un tas d'autres
appels de fonction ; quant à ucwords, je ne sais même pas s'il a une
chance de fonctionner.

Une idée (non testée, et dépend de $encoding) :
return mb_convert_case(
mb_strtolower($this->nom . ' ' . $this->prenom, $encoding),
MB_CASE_TITLE, $encoding);

Ou bien :
mb_internal_encoding($encoding);
return mb_convert_case(
mb_strtolower($this->nom . ' ' . $this->prenom), MB_CASE_TITLE);



Je vais tester cela, en espérant que PHP a été installé avec l'extension
adéquate.
Je n'avais pourtant pas de problème lors de mon dev sous ma bécane
linux. Sûrement une politique différente en ce qui concerne les encodages...

Merci en tout cas.
Cordialement,
Avatar
Olivier Miakinen
Le 10/05/2010 12:51, Jeremie a écrit :

[...] en fait toute l'appli est codée en UTF-8
(définition dans les fichiers de conf symfony).



Ok, déjà un problème en moins. ;-)

return ucwords(strtolower($this->nom . ' ' . $this->prenom));



Ah. Si tu veux pouvoir utiliser strtolower() sur autre chose que de
l'Ascii (lequel ne comprend aucune lettre accentuée), il faut préciser
la « locale », mais avec le risque de faire buguer tout un tas d'autres
appels de fonction ; quant à ucwords, je ne sais même pas s'il a une
chance de fonctionner.

Une idée (non testée, et dépend de $encoding) :
return mb_convert_case(
mb_strtolower($this->nom . ' ' . $this->prenom, $encoding),
MB_CASE_TITLE, $encoding);

Ou bien :
mb_internal_encoding($encoding);
return mb_convert_case(
mb_strtolower($this->nom . ' ' . $this->prenom), MB_CASE_TITLE);



Je vais tester cela, en espérant que PHP a été installé avec l'extension
adéquate.



Ah oui, en effet ce n'est pas gagné d'avance, mais avec un peu de chance...

Je n'avais pourtant pas de problème lors de mon dev sous ma bécane
linux. Sûrement une politique différente en ce qui concerne les encodages...



Cela doit vouloir dire que :
1) par défaut une locale différente de "C" est positionnée sur ta
machine de dev ;
2) ucwords en tient compte tout comme strtolower (bien que ce ne soit
pas clairement dit dans la doc) ;
3) si le reste fonctionne, c'est que tes programmes ne semblent pas
gênés par cette locale.

Et donc, un setlocale(LC_CTYPE, ...) ou setlocale(LC_ALL, ...) a des
chances de fonctionner sur ta machine de prod, à condition de trouver la
valeur qui conviendra à ton système d'exploitation (peut-être "UTF8" ou
"UTF-8", ou "fr.UTF8", ou "fr_FR.UTF8", ou..., ou...)

Cela dit, je te conseillerais plutôt de faire un setlocale(LC_ALL, "C")
sur ta machine de dev, et d'éviter d'utiliser toutes ces fonctions
telles que strtolower(), initialement prévues pour de l'Ascii 7bits, sur
des chaînes pouvant contenir autre chose que de l'Ascii. Mais bon, ce
n'est que mon avis.

Cordialement,
--
Olivier Miakinen