IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

strtr en unicode pour passer au caractère accentué en majuscule (é => É)


Sujet :

Langage PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Janvier 2015
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2015
    Messages : 29
    Par défaut strtr en unicode pour passer au caractère accentué en majuscule (é => É)
    Bonjour,

    J'ai une au question qui me turlupine depuis pas mal d'heures...
    Je viens de modifier tout l'encodage de mon site passé à l'unicode. Tout est ok aucun problème dans l'immédiat, les caractères spéciaux sont invisibles à l’œil dans l'ensemble des environnements...
    le serveur, les bdd, la méta html... okii

    Cette modification à des impacts indirects sur les fonctions (latines) incompatibles du aux caractère accentués (nbre d'octets...).
    Notamment strlen, substr, substr_count qui sont remplacé respectivement par mb_strlen, mb_substr, mb_substr_count.

    Mais malheureusement certaine fonctions n'ont pas leur équivalent direct.. bien sûre, ce serait trop façile...
    Donc ça se complique au niveau de la fonction strtr!!! ainsi que pour les regex (mais bon je traiterais ce second impact après)

    Je note bien les moyens de contourner expliqués sur ce site (array de remplacement des accents (suppression)). ce que je comprends sur les divers forum, pour ma part, c'est une fois les accents supprimés les caractères sont bien sur un octet et donc la fonction latines applicable. Ce n'est qu'un moyen de contourner qui peut vite trouver ses limites car c'est bien sur une chaîne UFT-8 qu'on applique la fonction latine strtr(), la variable étant vidée des accents cette dernières fonctionne...
    Pour confirmer cela on remarque bien que les fonction strlen, substr, substr_count fonctionnent très bien dans l'unicode quand il n'y a pas d'accent... Le moyen de contournement expliqué ci dessus pourrait aussi s'appliquer si ces dernières n'avaient par leur équivalent pour l'unicode...

    Le problème, dans mon cas, c'est que je ne veux pas supprimer l'accent mais le mettre en majuscule, quand c'est la première lettre de ma variable!! ainsi étant tout en UTF-8 j'ai pensé à cela:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $adresse_post = strtr(utf8_decode($_POST['adresse'][0]), 'ç, é, è, ê, ë, à, â, î, ï, ô, ù, û', 'Ç, É, È, Ê, Ë, À, Â, Î, Ï, Ô, Ù, Û');
    $adresse_post = utf8_encode($adresse_post);
    Sans succès..

    alors j'ai essayé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $adresse_post=iconv("UTF-8","ISO-8859-1",$_POST['adresse']);
    $adresse_post = str_replace($adresse_post[0], 'ç, é, è, ê, ë, à, â, î, ï, ô, ù, û', 'Ç, É, È, Ê, Ë, À, Â, Î, Ï, Ô, Ù, Û');
    $adresse_post=iconv("ISO-8859-1","UTF-8",$adresse_post);
    toujours sans succès..

    Je pensais que repasser en latin pour appliquer des fonctions (latines)était un bon moyen de contournement...

    Quelqu'un pourrait m'aider!!? une idée? S'il-vous-plaît.
    Je vous remercie.

  2. #2
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Par défaut
    Un peu difficile de te suivre mais si ton besoin est de mettre en majuscule : mb_strtoupper()
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  3. #3
    Membre averti
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Janvier 2015
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2015
    Messages : 29
    Par défaut
    Merci pour votre retour, je pensais avoir été clair..
    La fonction mb_strtoupper ne fonctionne pas dans ce cas..
    Je souhaite seulement une fonction me permettant de mettre la première lettre en majuscule.
    ce que j’arrive à faire en effet avec la fonction mb_strtoupper qui met tout en majuscule sauf les lettre accentués, et, c'est bien cela le problème...
    => Je souhaite seulement une fonction me permettant de mettre la première lettre en majuscule =>
    => Lorsque la première lettre est accentué je souhaite aussi la mettre en majuscule... !!

    Ce que je faisait avant le passage à l'unicode avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $adresse_post = strtr($_POST['adresse'][0], 'ç, é, è, ê, ë, à, â, î, ï, ô, ù, û', 'Ç, É, È, Ê, Ë, À, Â, Î, Ï, Ô, Ù, Û');
    Merci de votre aide

  4. #4
    Expert confirmé Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 987
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 987
    Par défaut
    Si comme tu dis, mb_strtoupper ne fonctionne pas, c'est probablement parce que tu n'as pas renseigné le second paramètre qui précise l'encodage:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    echo mb_strtoupper('é', 'utf-8');
    renvoie bien É en ce qui me concerne.

    Note: tu trouveras également plusieurs manières de simuler mb_ucfirst (qui n'existe pas) dans les commentaires sur la page ucfirst du manuel PHP.

    Pense aussi à l'autre syntaxe de strtr qui consiste à lui passer un tableau associatif plutôt que deux strings:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $trans = array('à' => 'À', 'é' => 'É', 'è' => 'È' ... 'œ' => 'Œ');
    $text = strtr($text, $trans);
    Avec cette syntaxe, il ne peut pas y avoir de découpage malheureux d'octets en plein milieu d'un caractère, puisque aussi bien les clefs que les valeurs peuvent être des chaînes. Donc on met en relation un groupe d'octets avec un autre groupe d'octets, ce qui évite les erreurs.

  5. #5
    Membre averti
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Janvier 2015
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2015
    Messages : 29
    Par défaut
    Super meric beaucoup !!
    En effet j’avais bien oublié de préciser l’encodage sur la fonction mb_strtoupper, de même que sur toutes les fonctions latines qui ont leur équivalent mb_..
    Merci aussi pour l’explication d’un strtr au sein d’un array, qui pemret de traiter les accents puisqu’il ne gère pas des octets…

    Pour finir sur ce sujet et simuler le mb_ucfirst j’ai fait une fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    		function trim_ucfirst_strtolower_utf8($stri) { //Pour le champs adresse et adresse complémentaire
    	//Met le premier caractère de la chaîne en majuscule et le reste de la chaîne en minuscule (accentué ou non)
    		$stri = trim(($stri)," "); //On supprime les espases en début et fin de chaînes ..
    		$ucfirst = mb_strtoupper(mb_substr($stri, 0, 1,'utf-8'),'utf-8');
    		$strtolower = mb_strtolower(mb_substr($stri, 1, 1000,'utf-8'),'utf-8');
    		$stri = $ucfirst.$strtolower;
    		return $stri;
    			}
    ensuite je met une majuscule au autres mots de la chaînes, la je ne gère plus les accents...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    	function ucwords_utf8($stri) { //Pour le champs adresse et adresse complémentaire
    	//Met le premier caractère de chacun des mots en majuscule excepté les mots listés [PBLM : ne gère pas les accents]
    		$stri = ucwords($stri); // On met la première lettre en majuscule de chaque mot! (si elle n'est pas accentuée..., déjà fait en var1)
    		$stri = strtr($stri, 'De, Du, Des, Un, Une, Au, Le, La, Les, Ça', 'de, du, des, un, une, au, le, la, les, ça'); //Mais si il y a de déterminants.. on supprime les majuscules
    		$stri = ucfirst($stri); //Mais si ce déterminant est en début de Nom, alors on conserve la majuscule...
    		return $stri;
    			}
    Puis je supprime les répétions, la non plus je ne gère pas les accents...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    	function lettre_multiple_utf8($stri) { //Pour le champs adresse et adresse complémentaire
    	//Gère les lettres doublés de manière anormale [PBLM : ne gère pas les accents]
    		$stri = preg_replace('<([nmstplé])\\1{2,}(?!\\1)>i','$1',$stri); //pour les lettres doublées, si plus de deux on remplace par une...
    		$stri = preg_replace('<([^nmstplé0-9])\\1+(?!\\1)>i','$1', $stri); //pour les autres, si plus de une on remplace par une...
    		return $stri;
    			}
    enfin j'applique ma véritable regex
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    						$pattern = '`[^A-Za-z0-9\'\-,:( )&çéèêëàâîïôùûÇÉÈÊËÀÂÎÏÔÙÛ]`i';
    						if (!preg_match($pattern,$adresse_post)) 
    							{ }
    A ma grande surprise ma regex marche en l'état sur mon site (en utf-8) est-ce normal??


    Si elle n'est pas respecté je voudrais énoncé le caractère qui pose problème de telle manière:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    else {
    									$pattern_interdit = '`[^A-Za-z0-9\'\-,:( )&çéèêëàâîïôùûÇÉÈÊËÀÂÎÏÔÙÛ]`i';
    									$position_carac_interdit = mb_strpos ($adresse_post,$pattern_interdit, 0, 'utf-8') ; //position du premier caract ineterdit
    									$carac_interdit = mb_substr($adresse_post, $position_carac_interdit,$position_carac_interdit, 'utf-8'); //on veut retourner le 1er carac interdi
    							        $erreur='L\'adresse contient des caractères non autorisés ('.$carac_interdit.')';}
    Mais cette dernière ne fonctionne pas, elle marche seulement si dans la foction mb_substr je remplace la variable $pattern_interdit par un caractère interdit du style "?"
    Quelqu'un aurait une idée?
    Merci pour votre aide

  6. #6
    Expert confirmé Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 987
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 987
    Par défaut
    Il y a plusieurs choses bizarres:
    • Ta façon d'utiliser strtr ou mb_strtr avec deux chaînes en paramètre est fausse. À la base cette fonction a pour vocation de remplacer un caractère par un autre. Les paramètres sont donc vus comme une suite de caractères pas de mots. Le caractère de remplacement est identifier grâce à la position des caractères dans ces chaînes (voir le manuel): $chaine = strtr($chaine, 'abcde', 'ABCDE');. En aucun cas on peut lui passer une liste de mots séparés par des virgules! Écrire $chaine = strtr($chaine, 'Le, De, Ce', 'le, de, ce'); revient strictement à écrire $chaine = strtr($chaine, 'LDC', 'ldc');. À la limite tu pourrais écrire $chaine = strtr($chaine, array('Le' => 'le', 'De' => 'de', 'Ce' => 'ce')); mais rien ne l'empêchera de procéder au remplacement sur un mot commençant par "Le" comme "Levallois-Perret".
    • Concernant: preg_replace('<([nmstplé])\\1{2,}(?!\\1)>i','$1',$stri);, il est inutile d'utiliser le double échappement en PHP, il est simplement ignoré. Le lookahead ne sert à rien car les quantificateurs sont gourmands par défaut, donc: preg_replace('<([nmstplé])\1{2,}>i','$1',$stri); fera la même chose.
    • mb_strpos ($adresse_post,$pattern_interdit, 0, 'utf-8') ;: strpos et mb_strpos ne prennent pas de pattern regex en argument. Donc il faut mieux se tourner vers preg_match avec l'option PREG_OFFSET_CAPTURE.

Discussions similaires

  1. [WD17] [Accès natif Mysql]Unicode: plantage requête avec caractère accentué..
    Par Christophe Charron dans le forum WinDev
    Réponses: 4
    Dernier message: 03/03/2013, 17h59
  2. Réponses: 8
    Dernier message: 11/05/2012, 11h25
  3. [XL-2007] Macro pour remplacer les caractéres accentué
    Par Rinzler dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 05/04/2011, 15h55
  4. [pb de caractere] Conversion de caractères accentué pour url
    Par smyley dans le forum Général Conception Web
    Réponses: 7
    Dernier message: 04/11/2005, 16h55

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo