Bugs php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login

go to bug id or search bugs for

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-2025 The PHP Group
All rights reserved. Last updated: Fri Oct 17 12:00:01 2025 UTC

AltStyle によって変換されたページ (->オリジナル) /