Viewed   226 times

I'm having a hard time understanding when strtr would be preferable to str_replace or vice versa. It seems that it's possible to achieve the exact same results using either function, although the order in which substrings are replaced is reversed. For example:

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

This outputs

YeXY XYring
YeZ Zring
YeXY XYring
YeZ Zring

Aside from syntax, is there any benefit to using one over the other? Any cases where one would not be sufficient to achieve a desired result?

 Answers

1

First difference:

An interesting example of a different behaviour between strtr and str_replace is in the comments section of the PHP Manual:

<?php
$arrFrom = array("1","2","3","B");
$arrTo = array("A","B","C","D");
$word = "ZBB2";
echo str_replace($arrFrom, $arrTo, $word);
?>
  • I would expect as result: "ZDDB"
  • However, this return: "ZDDD" (Because B = D according to our array)

To make this work, use "strtr" instead:

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

This means that str_replace is a more global approach to replacements, while strtr simply translates the chars one by one.


Another difference:

Given the following code (taken from 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);
?>

The resulting lines of text will be:

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


The main explanation:

This happens because:

  • strtr: it sorts its parameters by length, in descending order, so:

    1. it will give "more importance" to the largest one, and then, as the subject text is itself the largest key of the replacement array, it gets translated.
    2. because all the chars of the subject text have been replaced, the process ends there.
  • str_replace: it works in the order the keys are defined, so:

    1. it finds the key “PHP” in the subject text and replaces it with: “PHP: Hypertext Preprocessor”, what gives as result:

      “PHP: Hypertext Preprocessor: Hypertext Preprocessor”.

    2. then it finds the next key: “PHP: Hypertext Preprocessor” in the resulting text of the former step, so it gets replaced by "PHP", which gives as result:

      “PHP: Hypertext Preprocessor”.

    3. there are no more keys to look for, so the replacement ends there.

Tuesday, October 11, 2022
1

Try this:

    <?php

$string = '<html><h1> some text i want to replace</h1><p>
    some stuff i want to replace </p>';
$text_to_echo =  preg_replace_callback(
    "/(<([^.]+)>)([^<]+)(<\/\2>)/s", 
    function($matches){
        /*
         * Indexes of array:
         *    0 - full tag
         *    1 - open tag, for example <h1>
         *    2 - tag name h1
         *    3 - content
         *    4 - closing tag
         */
        // print_r($matches);
        $text = str_replace(
           array("text", "want"), 
           array('TEXT', 'need'),
                $matches[3]
        );
        return $matches[1].$text.$matches[4];
    }, 
    $string
);
echo $text_to_echo;
Monday, November 7, 2022
 
wolphin
 
3

Whenever you use SingleOrDefault, you clearly state that the query should result in at most a single result. On the other hand, when FirstOrDefault is used, the query can return any amount of results but you state that you only want the first one.

I personally find the semantics very different and using the appropriate one, depending on the expected results, improves readability.

Sunday, July 31, 2022
 
gdejohn
 
4

You can pass arrays as parameters to str_replace(). Check the manual.

// Provides: You should eat pizza, beer, and ice cream every day
$phrase  = "You should eat fruits, vegetables, and fiber every day.";
$healthy = ["fruits", "vegetables", "fiber"];
$yummy   = ["pizza", "beer", "ice cream"];

$newPhrase = str_replace($healthy, $yummy, $phrase);
Wednesday, August 24, 2022
 
vicente
 
3

ScottGu explains some of this in his blogpost about MVC V2.

From what I gather this will create inputs for each of the properties of the object you pass to the helper. So if you have the object:

public class Customer
{
    public string Name { get; set; }
    [UIHint("MyCoolCalendar")]
    public DateTime CoolDate { get; set; }
}

And then create an editor:

<%= Html.EditorFor(customer => customer) %>

It will produce a text input for the name of the customer, and a MyCoolCalendar (which is a customdefined control) for CoolDate without you having to write a custom control to wrap the entire object. It automatically deduces the type of control from the type/uihint of the property. At least this is as I have understood it without having time to test it out yet.

Monday, September 19, 2022
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :