1

I have recently found a bug, that simple I can't explain. It should not be so hard, because is a very simple problem, but seems that I don't know something about PHP that makes this happend.

Let's take this simple code:

session_start();

$temp = new stdClass;
$temp->id = 1;
$temp->name = "A";

$_SESSION['temp_obj'] = $temp;

$data = new stdClass;
$data->temp = $_SESSION['temp_obj'];
$data->temp->name = 'B';

print_r($_SESSION['temp_obj']);

The output, should say:

stdClass Object ( [id] => 1 [name] => A )

But instead, it says...

stdClass Object ( [id] => 1 [name] => B )

So, the $_SESSION, has been changed, and nothing in the code has a...

$_SESSION['temp_obj'] = $data->temp;

So it shouldn't never overwrite the $_SESSION value. Furthermore, it also overwrites the $temp variable.

I can't see the error.

Cœur
  • 37,241
  • 25
  • 195
  • 267

2 Answers2

0

Objects are pointers and mutable items. They get affected when the original value is affected.

<?php
    header("Content-type: text/plain");
    $a = new stdClass;
    $a->id = "This is A";
    $b = new stdClass;
    $b->id = "This is B";
    $c = $a;
    echo "A: ";
    print_r($a);
    echo "B: ";
    print_r($b);
    echo "C: ";
    print_r($c);
    echo "Let's change A!\n";
    $a->id = "Ha ha ha!";
    echo "A: ";
    print_r($a);
    echo "C: ";
    print_r($c);
?>

Output:

A: stdClass Object (
    [id] => This is A
)
B: stdClass Object (
    [id] => This is B
)
C: stdClass Object (
    [id] => This is A
)
Let's change A!
A: stdClass Object (
    [id] => Ha ha ha!
)
C: stdClass Object (
    [id] => Ha ha ha!
)

See How do I create a copy of an object in PHP? for more info.

Community
  • 1
  • 1
Praveen Kumar Purushothaman
  • 164,888
  • 24
  • 203
  • 252
0

There is nothing weird. These lines in your code:

$temp = new stdClass; 
$_SESSION['temp_obj'] = $temp;
$data->temp = $_SESSION['temp_obj'];

Means that all three of them point to the same object. So if you do this:

 $temp->foo = 'bar'; 

The result is the same as any one of these:

$_SESSION['temp_obj']->foo = 'bar';
$data->temp->foo = 'bar';
Rei
  • 6,263
  • 14
  • 28