1. PHP Design Bug Still Active in 5.4 Alpha - And Worse

    Today I tested my favorite PHP bug by design in current 5.4.0alpha2. It still works, and that’s the good news.

    php > echo phpversion() . “\n”;
    5.4.0alpha2
    php > $foo = “bar”;
    php > echo $foo[0] . “\n”;
    b
    php > echo $foo[“ouch”] . “\n”;
    b
    php > $bar = array(1,2,3);
    php > echo $bar[0] . “\n”;
    1
    php > echo $bar[“ouch”];
    PHP Notice:  Undefined index: ouch in php shell code on line 1

    Notice: Undefined index: ouch in php shell code on line 1
    php >

    What you see here is the attempt to access a single character of a string using array syntax with an array key that does not exists. Doing this bad thing with a real array at least gives you a notice. Doing it with a string is assumed fine by the interpreter. The magic behind all this is that the string is somehow treated like an array with integer keys and “ouch” is then dynamically casted to an integer and this is 0 in PHP’s strange logic.

    But 5.4.0alpha2 knows how to deepen this mess. While in 5.3.3 you may see this:

    php >  echo $foo[1][0];

    Fatal error: Cannot use string offset as an array in php shell code on line 1

    Call Stack:
     3768.9080     630080   1. {main}() php shell code:0

    now you get this:

    php > echo $foo[1][0] . “\n”;
    a
    php > echo $foo[“ouch”][0] . “\n”;
    b
    php > echo $foo[“ouch”][“ouch”] . “\n”;
    b
    php >

    To name it: you get nonsense, and that’s the bad news.

    Years ago my team has reported this to be a bug in PHP but the PHP guys say that’s a feature. Now they improved that feature. Great!

    So, if you do not want your PHP software to show undesired behavior you have absolutely no idea where it originates from, always ensure to have an array and not a string when you expect an array: use type hinting excessively and always hint for arrays in function declarations. Never try to catch the “E_RECOVERABLE_ERROR”. Set “error_reporting = E_ALL | E_STRICT”. Always ensure you have a string and not an array if you expect a string (use is_string() since you cannot type hint for strings).

    Do yourself a favor and write much more unit tests.

    Alternatively: use strongly typed languages.

Powered by Tumblr; designed by Adam Lloyd and Ingo Schramm.