php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #65903 Reference type property unexpectedly converted to value type property
Submitted: 2013-10-15 19:09 UTC Modified: 2018-03-16 23:04 UTC
Votes:3
Avg. Score:4.3 ± 0.9
Reproduced:3 of 3 (100.0%)
Same Version:1 (33.3%)
Same OS:2 (66.7%)
From: veg at tut dot by Assigned:
Status: Open Package: Scripting Engine problem
PHP Version: 5.5.4 OS: Windows 7 Pro SP1 x86
Private report: No CVE-ID: None
 [2013-10-15 19:09 UTC] veg at tut dot by
Description:
------------
I've used a little code snippet to convert property from value type to reference type. It's described here: http://www.php.net/manual/en/language.oop5.cloning.php
It's very useful practice when you want to share some properties between all clones. But it works with some bugs. When you try to read a reference type property of object without clones, this property unexpectedly converted to value type property.

Test script:
---------------
<?php
header('content-type: text/plain; charset=utf-8');

class demo
{
    public $n = 0;
    function __construct() { $this->n =& $this->n; }
    function magic()       { if ($this->n) return; }
    function set($n)       { $this->n = $n; }
}

// Outputs 1 = 1 as expected
$a1 = new demo();
$b1 = clone $a1;
$a1->magic();
$b1->set(1);
echo "{$a1->n} = {$b1->n}\n";

// Outputs 0 = 1 (magic() method is called a little earlier)
$a2 = new demo();
$a2->magic();
$b2 = clone $a2;
$b2->set(1);
echo "{$a2->n} = {$b2->n}\n";

Expected result:
----------------
1 = 1
1 = 1

Actual result:
--------------
1 = 1
0 = 1

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2013-10-15 22:07 UTC] bwoebi@php.net
Some simpler reproduce case (also reproducible with arrays etc.):

root# php -r '$z = (object)["p" => 1]; $z->p = &$z->p; var_dump($z);'
object(stdClass)#1 {
  ["p"]=>
  &long(1) // << here is an &
}
root# php -r '$z = (object)["p" => 1]; $z->p = &$z->p; $z->p; var_dump($z);'
object(stdClass)#1 {
  ["p"]=>
  long(1) // << note that there's no &
}

So it seems that a reference to itself on object properties is removed upon direct read access.

(The problem is that when referencing a variable to itself the refcount isn't incremented and when a temporary variable is being destroyed the refcount is decremented and now equal to 1; so the reference is thought to be unset and then removed. Note that this only is the case for IS_TMP_VAR (IS_CV and IS_VAR are immune against that).)
 [2018-03-16 23:04 UTC] cmb@php.net
JFTR: the behavior has been changed as of PHP 7.0.0, see
<https://3v4l.org/VTJMI> and <https://3v4l.org/oi75J>.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Dec 05 11:01:29 2024 UTC