Mantis - Quercus
Viewing Issue Advanced Details
4324 major always 12-09-10 12:23 03-22-12 13:42
gbruins  
 
normal  
assigned  
open  
none    
none  
0004324: unset() function does not work properly
Per the manual on php.net:
"__unset() is invoked when unset() is used on inaccessible properties"

However __unset() not called on inaccessible object properties.

Here is some code that reproduces the issue:

===================================================

<?php
class PropertyTest {
    /** Location for overloaded data. */
    private $data = array();

    /** Overloading not used on declared properties. */
    public $declared = 1;

    /** Overloading only used on this when accessed outside the class. */
    private $hidden = 2;

    /** As of PHP 5.1.0 */
    public function __unset($name) {
        echo "Unsetting '$name'\n";
        unset($this->data[$name]);
    }
}


$obj = new PropertyTest;

echo "Unsetting visible object property\n\n";
unset($obj->declared);
// should not print anything

echo "\n\nUnsetting invisible object property\n";
unset($obj->hidden);
// should print "Unsetting 'hidden'"
?>

Notes
(0004870)
kdecherf   
12-10-10 03:07   
Seems working on the first call only
(0004871)
gbruins   
12-10-10 08:57   
Correct, the first call, unset($obj->declared), works because $decalared is public, an so a call to __unset() should not happen (and it doesn't...so this works properly).

The second call, unset($obj->hidden), should call the __unset() function because $hidden is private and thus an inaccessible property. This does not happen however.
(0004872)
kdecherf   
12-10-10 09:02   
First call = first access to the page.

unset($obj->hidden) works all the time, What is your Quercus version ?
(0004873)
gbruins   
12-10-10 09:05   
We are running resin-4.0.10

(0004874)
kdecherf   
12-10-10 09:49   
Seems to be fixed in resin-4.0.13 or 4.0.14-snapshot.
But another issue appears with unset($obj->declared);
(0004883)
ttan   
12-17-10 14:56   
Hi,

We can't upgrade to 4.0.13 because many regressions were found doing that. Is it possible to get us a list of the files that changed for the unset issue to be fixed?

Thanks.
(0004885)
gbruins   
12-22-10 17:11   
New discovery. It looks like the __get() and __set() functions work sometimes:

__unset():
This function is always broken...nothing every seems to invoke it under any circumstances

__set() and __get():
These work sometimes:
- In the class below, if you comment out this line, then the __set() and __get() functions are invoked: private $foo = "foo original";
- If you don?t comment out that line, then the functions are not invoked.


What is supposed to happen in every case is that if a member of an object is not publicly accessible, or if it doesn?t exist, then the special ?underscore underscore? functions are invoked. So __unset() doesn?t work any of the time, and __set() and __get() only work sometimes.



Here is a test:
==============================================================

class PropertyTest {
    /** Location for overloaded data. */
    private $data = array();

    /** Overloading not used on declared properties. */
    public $declared = 1;

    /** Overloading only used on this when accessed outside the class. */
    private $hidden = 2;
    
    private $foo = "foo original";

    public function __unset($name) {
        echo "Unsetting '$name'\n";
        unset($this->data[$name]);
    }
    
    public function __set($name, $value) {
      echo "Setting '$name' to '$value' \n";
      $this->data[$name] = $value;
    }
    
    public function __get($name) {
      echo "Getting '$name' \n";
      return $this->data[$name];
    }
}

/////////// TESTING

$obj = new PropertyTest;

// UNSET TEST
unset($obj->declared); // should not print anything because 'declared' is public
unset($obj->hidden); // should print "Unsetting 'hidden'" because 'hidden' is private

// SET TEST
$obj->foo = "foo has been set"; // should print "Setting 'foo' to 'foo has been set"

// GET TEST
$bar = $obj->foo; // should print "Getting 'foo'"