Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP $_SESSION nested array is lost when a foreach() dummy name matches array name

Tags:

php

Can someone please confirm that the following is a bug with PHP 5.2.13: (thank you)

<?php
    session_start();
    if (!is_array($_SESSION["breadcrumb"]["trail"]))
    {
        $_SESSION["breadcrumb"]["trail"][] = "trail";
    } 
    foreach ($_SESSION["breadcrumb"]["trail"] as $breadcrumb)
    {
        echo $breadcrumb;
    }
?>

The above PHP script crashes the 3rd time it is run. The foreach() loop seems to have an (improper) side effect which wipes out the nested $_SESSION array because the internal variable used in the loop matches the name of the nested $_SESSION array. Simply changing the name of the internal foreach() variable to something different fixes the problem.

Note: clear session variables before running script 3 times.

Again, changing "$breadcrumb" to "$the_breadcrumb" fixes the problem. But the foreach() loop should have no side effects. Note: since the scope of $breadcrumb is not the same as the scope of $_SESSION["breadcrumb"], there should be no collision.

Note that doing a print_r() on the array shows the array as (correctly) empty the first time, (correctly) populated the second time, and erroneously set as "Array ( [breadcrumb] => trail )" the third time (the nested array has been wiped out).

The error in the PHP error log from the 3rd run: PHP Fatal error: Cannot use string offset as an array on line 5

The issue is not a problem on PHP 5.3 - only PHP 5.2.13. I could not find any note regarding this issue in the PHP changelog on the PHP site (php.net), and I must use 5.2.13 on my live site, so I'm posting here hoping that someone can confirm. I've also posted a bug report on php.net.

Thanks, Dan Nissenbaum

Expected result:

No PHP 5.2.13 crash on line 5.

Actual result:

PHP 5.2.13 crashes on line 5.

like image 258
Dan Nissenbaum Avatar asked Jan 31 '26 12:01

Dan Nissenbaum


1 Answers

Solved. notJim points out the register_globals php.ini setting. It was set to On. Turn to Off to separate the scope, as expected. Note: register_globals is deprecated as of (at least as far back as) PHP 5.3 - probably further back.

like image 108
Dan Nissenbaum Avatar answered Feb 03 '26 01:02

Dan Nissenbaum