php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #29848 Non-existent keys evaluate to string
Submitted: 2004-08-26 14:55 UTC Modified: 2004-08-27 21:10 UTC
From: geoff at variosoft dot com Assigned:
Status: Not a bug Package: Arrays related
PHP Version: 4.3.8 OS: Linux
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: geoff at variosoft dot com
New email:
PHP Version: OS:

 

 [2004-08-26 14:55 UTC] geoff at variosoft dot com
Description:
------------
In a multi-dimensional assoc array with a depth of x, an unset key at depth x+1 evaluates unexpectedly to a string when using var_dump() - the 1st char of the array value. 

This means that isset() returns TRUE when testing for the unset key, which makes it hard to test for non-existence.

An unset key with a depth of x+2 works as expected. 

This behaviour has been replicated in 4.3.8 and the 5 previous versions, all on Linux.

Reproduce code:
---------------
$foo['one']['two'] = 'test-value' ;

if( isset( $foo['one']['two']['three'] ) )
{
    print( "Unexpected isset(): evaluated to TRUE<br>" ) ;
}
else
{
    print( "Expected isset(): evaluated to FALSE<br>" ) ;
}

print( 'var_dump() output (expecting NULL):<br>' ) ;
var_dump( $foo['one']['two']['three'] ) ;

Expected result:
----------------
As I am testing for an unset key, I expected isset() to return FALSE, and var_dump() to return NULL.

Actual result:
--------------
In fact, isset() returns TRUE.

var_dump() gives a clue as to what is going on: it returns the first character of the key's value string.

For unset keys of a depth of x + 2, isset() returns FALSE and var_dump() returns NULL, as expected.

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2004-08-27 21:10 UTC] pollita@php.net
This is expected behavior.

Given:
$foo['bar']['baz'] = 'whatever';

Then the follow reference:
$foo['bar']['baz']['bomb']

evaluates as:
$tempvar['bomb']
(with $tempvar representing the string stored in $foo['bar']['baz'])

When accessing a string using [] or {} operators, the portion inside the operators is automatically converted to an integer.  The integer value of any string which does not begin with a numeric portion is always 0.  Hence you have:
$tempvar[0]

Which represents the first character of the variable.

To change this behavior would represent a major BC break.

To handle this type of situation in userspace, just add an extra check:

if (is_array($foo['bar']['baz']) && isset($foo['bar']['baz']['bomb'])) { ... }
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Sun Jun 15 13:01:35 2025 UTC