开发者

How to make PHP error when using an non-integer key for array-accessing a string

开发者 https://www.devze.com 2023-04-06 00:44 出处:网络
In PHP, you can access characters in a string with the array syntax: $foo = \'abc\'; echo $foo[2]; // echos \'c\'

In PHP, you can access characters in a string with the array syntax:

$foo = 'abc';
echo $foo[2]; // echos 'c'

I recently spent way too long debugging why $foo['id'] wasn't giving me the expected result. It turned out that $foo was a string instead of an associative array. PHP seemed to be casting 'id' to the integer 0, without giving any notice:

$foo = 'abc';
echo $foo['id']; // echos 'a', without notice

PHP throws a nice warning when you do this with real arrays:

$foo = array('a', 'b', 'c');
$echo $foo['id']; // Notice:  Undefined index: id in php shell code on line 1
开发者_高级运维

How can I make (or why can't) PHP throw an "Undefined index" notice instead of casting a string index to 0?


Unfortunately, there's nothing you can do, short of patching PHP.

However, if you do want to patch PHP, this is a possible patch (against trunk):

Index: Zend/zend_execute.c
===================================================================
--- Zend/zend_execute.c (revision 316974)
+++ Zend/zend_execute.c (working copy)
@@ -1268,7 +1268,7 @@
                                                case IS_DOUBLE:
                                                case IS_NULL:
                                                case IS_BOOL:
-                                                       /* do nothing */
+                                                       zend_error(E_NOTICE, "String offset is not an integer");
                                                        break;
                                                default:
                                                        zend_error(E_WARNING, "Illegal offset type");

Then:

$ ~/php/php-t/bin/php -d error_reporting=-1 -r '$a="foo"; echo $a["bar"];'

Notice: String offset is not an integer in Command line code on line 1
f


because [0] is ALWAYS the first character, if it's a string. You can check array with

if (is_array($array_or_string)){
    //it's an arra
}


This is a "feature":

Writing to an out of range offset pads the string with spaces. Non-integer types are converted to integer. Illegal offset type emits E_NOTICE. Negative offset emits E_NOTICE in write but reads empty string. Only the first character of an assigned string is used. Assigning empty string assigns NULL byte.

And the string 'id' converts to integer zero:

The value is given by the initial portion of the string. If the string starts with valid numeric data, this will be the value used. Otherwise, the value will be 0 (zero). Valid numeric data is an optional sign, followed by one or more digits (optionally containing a decimal point), followed by an optional exponent. The exponent is an 'e' or 'E' followed by one or more digits.

You can't change this. Sorry!


PHP 5.4 now shows an error!

$foo = 'abc';
echo $foo['id'];
PHP Warning:  Illegal string offset 'id' in php shell code on line 1
PHP Stack trace:
PHP   1. {main}() php shell code:0
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号