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 :

Probleme avec STRTR dans une CLI ubuntu


Sujet :

Langage PHP

  1. #1
    Membre régulier
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    233
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 233
    Points : 107
    Points
    107
    Par défaut Probleme avec STRTR dans une CLI ubuntu
    Bonjour,

    J'aimerais savoir pourquoi ceci ne fonctionne pas dans mon terminal :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    	function sansAccent($chaine)
    	{
    		return strtr($chaine,	"ÀÁÂÃÄÅàáâãäåÒÓÔÕÖØòóôõöøÈÉÊËèéêëÇçÌÍÎÏìíîïÙÚÛÜùúûüÿÑñ",
    					"AAAAAAaaaaaaOOOOOOooooooEEEEeeeeCcIIIIiiiiUUUUuuuuyNn");
    	}
    alors que ceci ... qui en impose quand même plus , fonctionne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
    function str_replace_special($str) {
    	$trade = array(	'á'=>'a','ŕ'=>'a','ă'=>'a',
    		  	'ä'=>'a','â'=>'a',
    			'Á'=>'A','Ŕ'=>'A','Ă'=>'A',
    			'Ä'=>'A','Â'=>'A',
    			'é'=>'e','č'=>'e',
    			'ë'=>'e','ę'=>'e',
    			'É'=>'E','Č'=>'E',
    			'Ë'=>'E','Ę'=>'E',
    			'í'=>'i','ě'=>'i','ï'=>'i',
    			'ď'=>'i','î'=>'i',
    			'Í'=>'I','Ě'=>'I',
    			'Ď'=>'I','Î'=>'I',
    			'ó'=>'o','ň'=>'o','ő'=>'o',
    			'ö'=>'o','ô'=>'o',
    			'Ó'=>'O','Ň'=>'O','Ő'=>'O',
    			'Ö'=>'O','Ô'=>'O',
    			'ú'=>'u','ů'=>'u',
    			'ü'=>'u','ű'=>'u',
    			'Ú'=>'U','Ů'=>'U',
    			'Ü'=>'U','Ű'=>'U',
    			'ç'=>'c','Ç'=>'C',
    			' '=>'','/'=>'',
    			'*'=>'','|'=>'',
    			';'=>'',':'=>'',
    			','=>'','!'=>'','-'=>'',
    			'\\'=>'','\"'=>'','\''=>'');
     
    	return(strtolower(strtr($str,$trade)));
    }

  2. #2
    Modératrice
    Avatar de Celira
    Femme Profil pro
    Développeuse PHP/Java
    Inscrit en
    Avril 2007
    Messages
    8 633
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Développeuse PHP/Java
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2007
    Messages : 8 633
    Points : 16 372
    Points
    16 372
    Par défaut
    Aucune idée, mais ça ne marche pas chez moi non plus (avec les 2 fonctions dans un même script, encodé UTF-8, appliquées à la même chaine)

    Résultat d'un var dump (dans l'ordre : chaine source, 1ere fonction, 2e fonction)
    string 'éèÄëôsã' (length=13)
    
    string 'n�n�nan�nisno' (length=13)
    
    string 'eèaeosã' (length=9)
    
    Au passage, la 2e fonction ne gère pas le è, ni le ã

  3. #3
    Membre régulier
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    233
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 233
    Points : 107
    Points
    107
    Par défaut
    La 2eme aurait du ... normalement fonctionner mais il y a deja un probleme d'encodage avec le copier coller , dû probablement au forum.

    Il faut virer tous les &#.

    Même l'exemple sur le site php.net ne fonctionne pas dans un terminal :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    $addr = strtr("Tädåö", "äåö", "aao");
    echo $addr;

  4. #4
    Membre régulier
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    233
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 233
    Points : 107
    Points
    107
    Par défaut
    Je viens d'essayer aussi au seins d'une page web ... même constat

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    <!doctype html>
    <html>
     
    	<head>
    		<meta charset="utf-8">
    		<title>Test</title>
    	</head>
     
    	<body>
    		toto
     
    		Yooo
    		<?php
    			function sansAccent($chaine)
    			{
    				return strtr($chaine,	"ÀÁÂÃÄÅàáâãäåÒÓÔÕÖØòóôõöøÈÉÊËèéêëÇçÌÍÎÏìíîïÙÚÛÜùúûüÿÑñ",
    										"AAAAAAaaaaaaOOOOOOooooooEEEEeeeeCcIIIIiiiiUUUUuuuuyNn");
    			}
     
    			$addr = strtr("Tädåö", "äåö", "aao");
    			echo $addr;
    		?>
    	</body>
     
    </html>

  5. #5
    Membre régulier
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    233
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 233
    Points : 107
    Points
    107
    Par défaut
    J'ai un peu parcouru le web et j'ai entendu dire que strtr n'aimait pas trop l'UTF-8 ... même si la chaine (encodage fichier, terminal ou page web) est toute en UTF-8

    Je cherche une solution. Apparemment certains se tourneraient vers les methodes PHP mb_* ou str_* mais je n'ai pas encore trouvée l'equivalent a strtr.

  6. #6
    Membre habitué
    Homme Profil pro
    Collégien
    Inscrit en
    Septembre 2014
    Messages
    65
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 21
    Localisation : Nouvelle-Zélande

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : Septembre 2014
    Messages : 65
    Points : 158
    Points
    158
    Par défaut
    strstr fonctionne très bien quand on ne modifie qu'une valeur à la fois, mais pourquoi ne pas utiliser les regex qui sont bien utiles dans les cas comme celui ci, une fois "couplée" à htmlentities.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    function purge_accent($str)
    	{
    	     $str = preg_replace("/&(.)(tilde|uml|acute|cedil|circ|ring|grave);/", "$1", htmlentities($str));
    	     return preg_replace("/([^a-zA-Z0-9]+)/", "$1", $str);
    	}

  7. #7
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2007
    Messages
    748
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 748
    Points : 1 022
    Points
    1 022
    Par défaut
    juste sur la question de départ, pourquoi la première fonctionne différemment de la deuxième :

    le jeu de caractère n'est pas le même

    tu es capable de convertir '*' avec la deuxième fonction, mais à priori ce caractère est inexistant dans la première fonction.


    bon, quelque soit cette réponse, de toute façon, ton approche comme tu t'en rend compte est pas optimum.

    Le format est soit UTF8 soit pas utf8... si le jeu de donnée est latin, et que tu veux convertir en utf8 : AUCUN PROBLEME!; par contre convertir certains caractères qui ne sont pas dans la table utf-8 en latin, ca deviens un problème logiciel.


    admet que convertir un caractère "*" en rien ou en autre chose comme '-', bon ca permet de parser éventuellement une url, mais si c'est juste pour le "fun" ca sert à rien.

    la deuxième fonction est plus "crado" que la première celon les besoins....

  8. #8
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 888
    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 888
    Points : 6 632
    Points
    6 632
    Par défaut
    Le problème vient du fait que strtr() sous sa forme strtr($input, $search, $replace); fait un remplacement octet par octet et non pas caractère par caractère. Donc tout va bien quand on se limite à la zone ASCII (car tous les caractères sont codés sur un seul octet), mais tout part en vrille si on mélange des caractères qui sont codés sur un nombre d'octets différents car tout se décale. Pour mémoire, un caractère UTF-8 peut occuper entre 1 et 6 octets.

    Un petit exemple pour illustrer ce qui se passe:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    <meta charset="UTF-8"/><pre><?php
    $input = 'aôîæ';
    $search = 'aôî';
    $replace = 'aoi';
    $output = strtr($input, $search, $replace);
     
    function str2hex($str) {
        $length = strlen($str);
     
        if ($length > 0) {
            $result = dechex(ord($str[0]));
            for($i=1; $i < $length; $i++) {
                $result .= ' ' . dechex(ord($str[$i]));    
            }
            return $result;
        }
        return null;
    }
     
    echo "\n" . $search .  "\t" . str2hex($search)
       . "\n" . $replace . "\t" . str2hex($replace)
       . "\n"
       . "\n" . $input .   "\t" . str2hex($input)
       . "\n" . $output .  "\t" . str2hex($output);
    affichera:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    aôî	61 c3 b4 c3 ae
    aoi	61 6f 69
     
    aôîæ	61 c3 b4 c3 ae c3 a6
    aoio?o?	61 6f 69 6f ae 6f a6
    On voit bien que le "ô" est codé sur les deux octets c3 b4, du coup tout octet égal à c3 est remplacé par un "o".

    Donc une solution pour contourner le problème est d'utiliser l'autre syntaxe de strtr() qui utilise un tableau associatif dont les clefs sont les sous-chaînes à chercher et les valeurs les chaînes de remplacement.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $trans = array(
        'à' => 'a', 'â' => 'a', 'ä' => 'a',
        'è' => 'e', 'ê' => 'e', // ...
        'î' => 'i' // ...
    );
    $output = strtr($input, $trans);
    Le tout est de composer ton tableau de remplacement en fonction de ton besoin sans forcément chercher à remplacer tous les caractères accentués de la planète.

    Nota bene: il ne faut pas s'alarmer du fait que le tableau de remplacement "en impose", strtr est une fonction d'une rapidité redoutable, et qui plus est, a l'avantage de ne parcourir la chaîne qu'une seule fois tout en effectuant plusieurs remplacements différents (ce dont sont incapables str_replace et preg_replace).

  9. #9
    Membre régulier
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    233
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 233
    Points : 107
    Points
    107
    Par défaut
    Merci a tous pour ces explications claires.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Probleme avec CTimer dans une vue d'une appli
    Par vdaanen dans le forum MFC
    Réponses: 16
    Dernier message: 24/08/2011, 11h19
  2. probleme avec property dans une class
    Par Dereck07 dans le forum Débuter
    Réponses: 3
    Dernier message: 03/01/2010, 23h07
  3. Probleme avec critere dans une requete sur access..
    Par emirov dans le forum Requêtes et SQL.
    Réponses: 1
    Dernier message: 05/04/2008, 23h11
  4. [linker]Probleme avec SDL dans une application Ogre3D
    Par smarties dans le forum Visual C++
    Réponses: 2
    Dernier message: 15/01/2007, 14h29
  5. Réponses: 3
    Dernier message: 26/01/2004, 17h59

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