The story of one typo or strtr() replacing wrong characters
Recently there was a question on Russian Stack Overflow, from a guy claiming that strtr()
works incorrectly. They even provided some proof-codes:
$value = 'B1000'; // here we have zeros $converter = array('-'> ''); // delete all dashes $tr = strtr($value, $converter); echo $tr; // outputs 'B1111' - all 0s got replaced with 1s
another example:
$value = 'B1000'; // we have zeros $converter = array('-'> '_'); // replace all dashes to underscores $tr = strtr($value, $converter); echo $tr; // outputs 'B1' - all zeros are gone
Although this problem was caused by a simple typo, I found it rather amusing, given the unexpected results, and I felt that it could be an interesting example showing how the type juggling works in PHP. Let's see:
- All right, we just forgot the
=
character in the array definition, making it>
"Greater than" operator instead of=>
array value assignment operator. - As a result we've got an
'-' > ''
expression ('-' > '_'
in the second example) that returns a boolean value - It's all right for PHP to compare strings, based on the characters' codes:
- for the first example, an empty string is always less than a non-empty one, and therefore
'-' > ''
returnstrue
- in the second example, the code for dash character is 45 whereas underscore is 95, which makes
'-' > '_'
equal to45 > 95
equal tofalse
.
- for the first example, an empty string is always less than a non-empty one, and therefore
- If we omit the key in the array definition, it is generated automatically, starting from 0. Therefore in the end the arrays would look like:
- in the first case
array (0 => true)
- and in the second
array (0 => false)
- in the first case
- to use a value in the string manipulations, PHP will cast it to a string
- when PHP casts a boolean to a string,
true
becomes1
andfalse
becomes just an empty string
So now you can tell that replacements went according to the following rules
['0' => '1']
in the first case['0' => '']
in the second
and naturally, we just got 0s replaced to 1s as well as 0s removed!
It is worth to mention that such a case is also a good example as to why debugging is so important. The essential part of debugging process is called tracing which stands for running our program line by line, checking all the intermediate values. Tracing a code with a good IDE is fun, but of course one could always do it manually. In the present case it's just takes adding a debugging output for the replacement array (i.e. var_dump($converter)
) to make one see the real cause and to make them stop blaming the honest function of strtr()
!
Add a comment
Please refrain from sending spam or advertising of any sort.
Messages with hyperlinks will be pending for moderator's review.
Markdown is now supported:
>
before and an empty line after for a quote