Bug #65903 [Opn]: Reference type property unexpectedly converted to value type property
| From: | cmb@php.net | Date: | Fri, 16 Mar 2018 23:04:15 +0000 |
| Subject: | Bug #65903 [Opn]: Reference type property unexpectedly converted to value type property | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-214383@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=65903&edit=1
ID: 65903
Updated by: cmb@php.net
Reported by: veg at tut dot by
Summary: Reference type property unexpectedly converted to
value type property
Status: Open
Type: Bug
Package: Scripting Engine problem
Operating System: Windows 7 Pro SP1 x86
PHP Version: 5.5.4
Block user comment: N
Private report: N
New Comment:
JFTR: the behavior has been changed as of PHP 7.0.0, see
<https://3v4l.org/VTJMI> and <https://3v4l.org/oi75J>.
Previous Comments:
------------------------------------------------------------------------
[2013-10-15 22:07:43] 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).)
------------------------------------------------------------------------
[2013-10-15 19:09:24] 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
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=65903&edit=1