note 117169 added to function.strtr
| From: | evan dot king at NOSPAM dot example dot com | Date: | Fri, 24 Apr 2015 15:05:23 +0000 |
| Subject: | note 117169 added to function.strtr | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-202366@lists.php.net to get a copy of this message | ||
Here's an important real-world example use-case for strtr where str_replace will not work or
will introduce obscure bugs:
<?php
$strTemplate = "My name is :name, not :name2.";
$strParams = [
':name' => 'Dave',
'Dave' => ':name2 or :password', // a wrench in the otherwise sensible
input
':name2' => 'Steve',
':pass' => '7hf2348', // sensitive data that maybe shouldn't be here
];
echo strtr($strTemplate, $strParams);
// "My name is Dave, not Steve."
echo str_replace(array_keys($strParams), array_values($strParams), $strTemplate);
// "My name is Steve or 7hf2348word, not Steve or 7hf2348word2."
?>
Any time you're trying to template out a string and don't necessarily know what the
replacement keys/values will be (or fully understand the implications of and control their content
and order), str_replace will introduce the potential to incorrectly match your keys because it does
not expand the longest keys first.
Further, str_replace will replace in previous replacements, introducing potential for unintended
nested expansions. Doing so can put the wrong data into the "sub-template" or even give
users a chance to provide input that exposes data (if they get to define some of the replacement
strings).
Don't support recursive expansion unless you need it and know it will be safe. When you do
support it, do so explicitly by repeating strtr calls until no more expansions are occurring or a
sane iteration limit is reached, so that the results never implicitly depend on order of your
replacement keys. Also make certain that any user input will expanded in an isolated step after any
sensitive data is already expanded into the output and no longer available as input.
Note: using some character(s) around your keys to designate them also reduces the possibility of
unintended mangling of output, whether maliciously triggered or otherwise. Thus the use of a colon
prefix in these examples, which you can easily enforce when accepting replacement input to your
templating/translation system.
----
Server IP: 72.52.91.14
Probable Submitter: 98.143.242.51
----
Manual Page -- http://php.net/manual/en/function.strtr.php
Edit -- https://master.php.net/note/edit/117169
Del: integrated -- https://master.php.net/note/delete/117169/integrated
Del: useless -- https://master.php.net/note/delete/117169/useless
Del: bad code -- https://master.php.net/note/delete/117169/bad+code
Del: spam -- https://master.php.net/note/delete/117169/spam
Del: non-english -- https://master.php.net/note/delete/117169/non-english
Del: in docs -- https://master.php.net/note/delete/117169/in+docs
Del: other reasons-- https://master.php.net/note/delete/117169
Reject -- https://master.php.net/note/reject/117169
Search -- https://master.php.net/manage/user-notes.php