Quando usar strtr vs str_replace?

86

Estou tendo dificuldade em entender quando strtrseria preferível str_replaceou vice-versa. Parece que é possível obter exatamente os mesmos resultados usando qualquer uma das funções, embora a ordem em que as substrings são substituídas seja invertida. Por exemplo:

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');

Isso produz

YeXY XYring
YeZ Zring
YeXY XYring
YeZ Zring

Além da sintaxe, há alguma vantagem em usar um em vez do outro? Algum caso em que um não seria suficiente para alcançar o resultado desejado?

andrewtweber
fonte
3
Do ponto de vista da legibilidade, strtrpode ser facilmente mal interpretado, pois strstré bem diferente. Estou começando a achar que sou disléxico. Não vou cometer esse erro com str_replace.
Programster

Respostas:

135

Primeira diferença:

Um exemplo interessante de um comportamento diferente entre strtre str_replaceestá na seção de comentários do Manual do PHP:

<?php
$arrFrom = array("1","2","3","B");
$arrTo = array("A","B","C","D");
$word = "ZBB2";
echo str_replace($arrFrom, $arrTo, $word);
?>
  • Eu esperaria como resultado: "ZDDB"
  • No entanto, este retorno: "ZDDD" (Porque B = D de acordo com nossa matriz)

Para fazer isso funcionar, use "strtr" ao invés:

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

Isso significa que str_replaceé uma abordagem mais global para substituições, enquanto strtrsimplesmente traduz os caracteres um por um.


Outra diferença:

Dado o seguinte código (retirado da comparação de velocidade de substituição de string PHP ):

<?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);
?>

As linhas de texto resultantes serão:

string (3) "PHP"
string (27) "PHP: Pré-processador de hipertexto"


A principal explicação:

Isso acontece porque:

  • strtr : classifica seus parâmetros por comprimento, em ordem decrescente, então:

    1. ele dará "mais importância" ao maior e, então, como o próprio texto do assunto é a maior chave do array de substituição, ele é traduzido.
    2. porque todos os caracteres do texto do assunto foram substituídos, o processo termina aí.
  • str_replace : funciona na ordem em que as chaves são definidas, então:

    1. ele encontra a chave “PHP” no texto do assunto e a substitui por: “PHP: Pré-processador de hipertexto”, o que dá como resultado:

      “PHP: Hypertext Preprocessor: Hypertext Preprocessor”.

    2. em seguida, ele encontra a próxima chave: “PHP: Pré-processador de hipertexto” no texto resultante da etapa anterior, então é substituído por "PHP", que dá como resultado:

      “PHP: Pré-processador de hipertexto”.

    3. não há mais chaves para procurar, portanto, a substituição termina aí.

Nicolás Ozimica
fonte
2
Ah ok obrigado! Não sabia que strtr estava traduzindo por comprimento - pensei que era na ordem inversa.
andrewtweber
Conforme documentado em php.net, a função str_replace tem mais 1 parâmetro chamado "contagem" para indicar quantas vezes a substituição deve ser realizada. Mas não consigo usar esse parâmetro de qualquer maneira. Alguem sabe por quê ?
vantrung -cuncon
1
@ vantrung-cuncon Não é para isso que serve esse parâmetro. Os documentos dizem: "Isso será definido para o número de substituições realizadas." Você precisará encontrar outra solução se quiser limitar str_replace a uma certa quantidade de substituições.
jdhartley
1
Limitar o número de substituições pode ser útil se você quiser substituir a primeira ocorrência de uma sigla pela versão estendida, ou seja, alterar a primeira ocorrência de "WHO" para "WHO (World Health Organization)".
Michał Tatarynowicz
strtrnão substituirá o texto inserido por substituições anteriores. strtr('foo', array('oo' => 'ie', 'e' => 't'))retorna em 'fie'vez de 'fit'como str_replacefaz. Assim, ele resolve automaticamente o problema levantado por @Pies.
David Harkness
21

Parece que é possível obter exatamente os mesmos resultados usando qualquer uma das funções

Isso nem sempre é verdade e depende dos dados de pesquisa e substituição que você fornece. Por exemplo, onde as duas funções diferem, consulte: PHP str_replace tem um limite de mais de 13 caracteres?

  • strtrnão substituirá partes da string que já foram substituídas - str_replacesubstituirá dentro de substituições.
  • strtrcomeçará com a chave mais longa primeiro, no caso de você chamá-la com dois parâmetros - str_replacesubstituirá da esquerda para a direita.
  • str_replacepode retornar o número de substituições feitas - strtrnão oferece esse valor de contagem.
hakre
fonte
7

Acho que strtroferece uma substituição mais flexível e condicional quando usado com dois argumentos, por exemplo: se string for 1, substitua por a, mas se string for 10, substitua por b. Este truque só poderia ser alcançado por strtr.

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

veja: Php Manual Strtr .

Arif RH
fonte
2

Observe no manual STRTR-- Descrição string strtr (string $ str, string $ de, string $ to) string strtr (string $ str, array $ replace_pairs) Se dados três argumentos, esta função retorna uma cópia de str onde ...

STR_REPLACE-- ... Se pesquisar ou substituir forem matrizes, seus elementos serão processados ​​do primeiro ao último . ...

STRTR de cada turno NÃO tem efeito para o próximo, MAS STR_REPLACE tem.

Nulo Nenhum
fonte