Quand utiliser strtr vs str_replace?

86

J'ai du mal à comprendre quand strtrcela serait préférable str_replaceou vice versa. Il semble qu'il soit possible d'obtenir exactement les mêmes résultats en utilisant l'une ou l'autre fonction, bien que l'ordre dans lequel les sous-chaînes sont remplacées soit inversé. Par exemple:

echo strtr('test string', 'st', 'XY')."\n";
echo strtr('test string', array( 's' => 'X', 't' => 'Y', 'st' => 'Z' ))."\n";
echo str_replace(array('s', 't', 'st'), array('X', 'Y', 'Z'), 'test string')."\n";
echo str_replace(array('st', 't', 's'), array('Z', 'Y', 'X'), 'test string');

Cette sortie

YeXY XYring
YeZ Zring
YeXY XYring
YeZ Zring

Mis à part la syntaxe, y a-t-il un avantage à utiliser l'un par rapport à l'autre? Y a-t-il des cas où l'un ne serait pas suffisant pour obtenir le résultat souhaité?

andrewtweber
la source
3
Du point de vue de la lisibilité, strtrpourrait facilement être mal interprété car strstrce qui est tout à fait différent. Je commence à penser que je suis dyslexique. Je ne ferai pas cette erreur avec str_replace.
Programster

Réponses:

135

Première différence:

Un exemple intéressant d'un comportement différent entre strtret se str_replacetrouve dans la section commentaires du manuel PHP:

<?php
$arrFrom = array("1","2","3","B");
$arrTo = array("A","B","C","D");
$word = "ZBB2";
echo str_replace($arrFrom, $arrTo, $word);
?>
  • J'attendrais comme résultat: "ZDDB"
  • Cependant, ce retour: "ZDDD" (Parce que B = D selon notre tableau)

Pour que cela fonctionne, utilisez plutôt "strtr":

<?php
$arr = array("1" => "A","2" => "B","3" => "C","B" => "D");
$word = "ZBB2";
echo strtr($word,$arr);
?>
  • Cela renvoie: "ZDDB"

Cela signifie qu'il str_replaces'agit d'une approche plus globale des remplacements, tout strtren traduisant simplement les caractères un par un.


Une autre différence:

Étant donné le code suivant (tiré de PHP String Replacement Speed ​​Comparison ):

<?php
$text = "PHP: Hypertext Preprocessor";

$text_strtr = strtr($text
    , array("PHP" => "PHP: Hypertext Preprocessor"
        , "PHP: Hypertext Preprocessor" => "PHP"));
$text_str_replace = str_replace(array("PHP", "PHP: Hypertext Preprocessor")
    , array("PHP: Hypertext Preprocessor", "PHP")
    , $text);
var_dump($text_strtr);
var_dump($text_str_replace);
?>

Les lignes de texte résultantes seront:

string (3) "PHP"
string (27) "PHP: Hypertext Preprocessor"


La principale explication:

Cela se produit parce que:

  • strtr : il trie ses paramètres par longueur, par ordre décroissant, donc:

    1. cela donnera "plus d'importance" au plus grand, puis, comme le texte sujet est lui-même la plus grande clé du tableau de remplacement, il sera traduit.
    2. parce que tous les caractères du texte sujet ont été remplacés, le processus s'arrête là.
  • str_replace : il fonctionne dans l'ordre dans lequel les clés sont définies, donc:

    1. il trouve la clé «PHP» dans le texte du sujet et la remplace par: «PHP: Hypertext Preprocessor», ce qui donne comme résultat:

      «PHP: préprocesseur hypertexte: préprocesseur hypertexte».

    2. puis il trouve la clé suivante: «PHP: Hypertext Preprocessor» dans le texte résultant de l'étape précédente, donc elle est remplacée par «PHP», ce qui donne comme résultat:

      «PHP: préprocesseur hypertexte».

    3. il n'y a plus de clés à rechercher, donc le remplacement s'arrête là.

Nicolás Ozimica
la source
2
Ah ok merci! Je ne savais pas que strtr traduisait par longueur - je pensais que c'était dans l'ordre inverse.
andrewtweber
Comme documenté dans php.net, la fonction str_replace a 1 paramètre supplémentaire nommé "count" pour indiquer combien de fois le remplacement doit être exécuté. Mais je ne peux pas utiliser ce paramètre de toute façon. Quelqu'un sait-il pourquoi ?
vantrung -cuncon
1
@ vantrung-cuncon Ce n'est pas à cela que sert ce paramètre. La documentation dit: "Cela sera défini sur le nombre de remplacements effectués." Vous devrez trouver une autre solution si vous souhaitez limiter str_replace à un certain nombre de remplacements.
jdhartley
1
Limiter le nombre de remplacements peut être utile si vous souhaitez remplacer la première occurrence d'un acronyme dans la version étendue, c'est-à-dire changer la première occurrence de «WHO» en «WHO (World Health Organization)».
Michał Tatarynowicz
strtrne remplacera pas le texte inséré par les remplacements précédents. strtr('foo', array('oo' => 'ie', 'e' => 't'))renvoie 'fie'au lieu de 'fit'comme le str_replacefait. Ainsi, il résout automatiquement le problème soulevé par @Pies.
David Harkness
21

Il semble qu'il soit possible d'obtenir exactement les mêmes résultats en utilisant l'une ou l'autre des fonctions

Ce n'est pas toujours vrai et dépend de la recherche et du remplacement des données que vous fournissez. Par exemple, là où les deux fonctions diffèrent, voir: PHP str_replace a-t-il une limite supérieure à 13 caractères?

  • strtrne remplacera pas les parties de la chaîne qui ont déjà été remplacées - str_replaceremplacera les remplacements intérieurs.
  • strtrcommencera par la clé la plus longue en premier au cas où vous l'appelez avec deux paramètres - str_replaceremplacera de gauche à droite.
  • str_replacepeut renvoyer le nombre de remplacements effectués - strtrn'offre pas une telle valeur de comptage.
hakre
la source
7

Je pense que strtrfournit un remplacement plus flexible et conditionnel lorsqu'il est utilisé avec deux arguments, par exemple: si la chaîne est 1, remplacez par a, mais si la chaîne est 10, remplacez par b. Cette astuce ne pouvait être réalisée que par strtr.

$string = "1.10.0001";  
echo strtr($string, array("1" => "a", "10" => "b"));  
// a.b.000a  

voir: Php Manual Strtr .

Arif RH
la source
2

Remarque dans le manuel STRTR-- Description string strtr (string $ str, string $ from, string $ to) string strtr (string $ str, array $ replace_pairs) Si on lui donne trois arguments, cette fonction renvoie une copie de str où ...

STR_REPLACE-- ... Si la recherche ou le remplacement sont des tableaux, leurs éléments sont traités du premier au dernier . ...

STRTR à chaque tour PAS d'effet au suivant, MAIS STR_REPLACE le fait.

Null Aucun
la source