Asked  7 Months ago    Answers:  5   Viewed   44 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?



First difference:

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

$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:

$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):

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

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.

Wednesday, March 31, 2021
answered 7 Months ago

OK, based on refinements to your question, what you probably want is ltrim.

$out = ltrim($in, "0");

This will strip all leading zeroes from $in. It won't remove zeroes from anywhere else, and it won't remove anything other than zeroes. Be careful; if you give it "000" you'll get back "" instead of "0".

You could use typecasting instead, as long as $in is always a number (or you want it to result in 0 if it isn't):

$out = (int) $in;
  • 007 becomes 7
  • 000 becomes 0
  • 100 stays as 100
  • 456 stays as 456
  • 00a becomes 0
  • 56a becomes 0
  • ab4 becomes 0
  • -007 becomes -7


Now, in the unlikely event that you only want to replace the first 0, so for example "007" becomes "07", then your latest attempt mentioned in your question is almost there. You just need to add a "caret" character to make sure it only matches the start of the string:

$out = preg_replace('/^0/', '', $in);
Wednesday, March 31, 2021
answered 7 Months ago

As the documentation mention :

When you call the redirect helper with no parameters, an instance of IlluminateRoutingRedirector is returned, allowing you to call any method on the Redirector instance. For example, to generate a RedirectResponse to a named route, you may use the route method

As you can see in the API methods(link below) there is a lot of methods that you can use and also there is one specific helper method home() it's just a shortcut for redirect()->route('home') as highlighted by @ceejayoz.

Now the we will talk about return redirect('/'); and return redirect()->route('home'); the two of them redirects properly to the intended route as you said BUT the second one is really useful if in the future.

Why ?

Because if you want to change the URL structure in the routes file all you would need to change is the route only for example :

Route::get('/', 'IndexController@index')->name('home');

Will be :

Route::get('/home_page', 'IndexController@index')->name('home');

and all the redirects would refer to that route and there is no other thing that you should change => all redirects will still work perfectly.


If you choose to use the first one (i mean return redirect('/');) then after the change in the route you will need to parse all your controllers to check if there is some redirects that uses then changed route and the change them :p

Friday, May 28, 2021
answered 5 Months ago

To expand on Waage's response, you could use an array to replace both sets of characters

$teams = str_replace(array("rn", "n"),",",$teams);
echo $teams;

This should handle both items properly, as a single n is valid and would not get caught if you were just replacing rn

Saturday, May 29, 2021
answered 5 Months ago

You should use out unless you need ref.

It makes a big difference when the data needs to be marshalled e.g. to another process, which can be costly. So you want to avoid marshalling the initial value when the method doesn't make use of it.

Beyond that, it also shows the reader of the declaration or the call whether the initial value is relevant (and potentially preserved), or thrown away.

As a minor difference, an out parameter needs not be initialized.

Example for out:

string a, b;
person.GetBothNames(out a, out b);

where GetBothNames is a method to retrieve two values atomically, the method won't change behavior whatever a and b are. If the call goes to a server in Hawaii, copying the initial values from here to Hawaii is a waste of bandwidth. A similar snippet using ref:

string a = String.Empty, b = String.Empty;
person.GetBothNames(ref a, ref b);

could confuse readers, because it looks like the initial values of a and b are relevant (though the method name would indicate they are not).

Example for ref:

string name = textbox.Text;
bool didModify = validator.SuggestValidName(ref name);

Here the initial value is relevant to the method.

Tuesday, June 1, 2021
answered 5 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :