The following eval’ed code was caused a lot of misunderstanding: https://eval.in/61309. The code looks like this:
|
|
It outputs this:
2a0
2a1
2a2
2a3
2a4
2a5
2a6
2a7
2a8
2a9
2b0
2b1
2b2
2b3
2b4
2b5
2b6
2b7
2b8
2b9
2c0
2c1
2c2
2c3
2c4
2c5
2c6
2c7
2c8
2c9
2d0
2d1
2d2
2d3
2d4
2d5
2d6
2d7
2d8
2d9
2e0
3
4
5
6
7
8
9
10
11
Most people seeing this will thing “WHAT?!” :) Well, it’s not a bug and this behaviour is 100% correct. And documented.
Problem 1: “2a0++” = “2a1”
This result will only happen if you use the “++” operator. Using +1 won’t work like that.
Why? Because “++” acts on numbers and strings - and when dealing in strings, it acts like Perl.
When $a = "Z"; $a++; $a
will become AA
.
$a = "AA"; $a++;
will become AB
, etc.
This way, $a = "2a0"; $a++;
will become "2a1"
.
Think: alphabet!
In contrast, $a+1
only acts on numbers - so if you try to use it on a string, it will get converted to a number. So
in $a = "a20"; $a = $a+1;
“2a0” will be converted to a number, which will be “2” in this case. And 2 + 1 = 3
Docs: http://php.net/manual/en/language.operators.increment.php:
PHP follows Perl’s convention when dealing with arithmetic operations on character variables and not C’s. For example, in PHP and Perl $a = ‘Z’; $a++; turns $a into ‘AA’, while in C a = ‘Z’; a++; turns a into ‘[’ (ASCII value of ‘Z’ is 90, ASCII value of ‘[’ is 91).
Problem 2: “2e0”++ = 3
The difference between 2a0
and 2e0
is exactly as it seems: the letter “e”. Following the PHP docs:
If the string does not contain any of the characters ‘.’, ’e’, or ‘E’ and the numeric value fits into integer type limits (as defined by PHP_INT_MAX), the string will be evaluated as an integer. In all other cases it will be evaluated as a float.
Source: http://www.php.net/manual/en/language.types.string.php#language.types.string.conversion
So:
"2e0" = 2 x 10⁰ = 2
And 2++ = 3
Conclusion: don’t use weird strings like “2a0” and force them to act like numbers, unless you know what you’re doing!