Edit report at http://bugs.php.net/bug.php?id=52711&edit=1

 ID:                 52711
 Comment by:         rayro at gmx dot de
 Reported by:        vik_ at hotmail dot com
 Summary:            incorrect private property handling in extended
                     class
 Status:             Open
 Type:               Bug
 Package:            Class/Object related
 Operating System:   windows 7
 PHP Version:        5.3.3
 Block user comment: N

 New Comment:

addition to my previous post..



toggling the default value of $var in Foo to null and setting it in the
constructor:

<?php

class Foo {

        #private $var = 'sheep';

        private $var;

        function __construct() {

                $this->var = 'sheep';

        }

...

?>



will effect to the following result:

------------------------------------

called $Foo->var(): 0

called $Foo->var: sheep

existing property: 1

called $Bar->var(): 0

called $Bar->var: sheep

existing property: 

called $Baz->var(): 1 <-----

called $Baz->var:  <-----

existing property: 1

called $Faz->var(): 0

called $Faz->var: cat

existing property: 1


Previous Comments:
------------------------------------------------------------------------
[2010-09-13 23:16:51] rayro at gmx dot de

seems not to be really a bug, as the manual explains the following:

http://de.php.net/manual/en/language.oop5.visibility.php

"Class members declared public can be accessed everywhere. Members
declared protected can be accessed only within the class itself and by
inherited and parent classes. Members declared as private may only be
accessed by the class that defines the member."



BUT



there is something wrong.. It seems somehow __get will be invoked on the
"parents scope" if not redefined...



Test script:

------------

<?php

class Foo {

        private $var = 'sheep';

        function __construct() {

        }

        public function __call($f,$a) {

                return empty($this->{$f});

        }

        public function __get($v) {

                return $this->{$v};

        }

}

class Bar extends Foo {

}

class Baz extends Foo {

        private $var;

        function __construct() {

                $this->var = 'dog';

        }

}

class Faz extends Foo {

        private $var;

        function __construct() {

                $this->var = 'cat';

        }

        function __call($f,$a) {

                return empty($this->{$f});

        }

        function __get($v) {

                return $this->{$v};

        }

}

$test = new Foo();

echo('called $Foo->var(): '.(int)$test->var().PHP_EOL);

echo('called $Foo->var: '.$test->var.PHP_EOL);

echo('existing property: '.property_exists($test,'var').PHP_EOL);

$test = new Bar();

echo('called $Bar->var(): '.(int)$test->var().PHP_EOL);

echo('called $Bar->var: '.$test->var.PHP_EOL);

echo('existing property: '.property_exists($test,'var').PHP_EOL);

$test = new Baz();

echo('called $Baz->var(): '.(int)$test->var().PHP_EOL);

echo('called $Baz->var: '.$test->var.PHP_EOL);

echo('existing property: '.property_exists($test,'var').PHP_EOL);

$test = new Faz();

echo('called $Faz->var(): '.(int)$test->var().PHP_EOL);

echo('called $Faz->var: '.$test->var.PHP_EOL);

echo('existing property: '.property_exists($test,'var').PHP_EOL);

?>



Expected result:

----------------

called $Foo->var(): 0

called $Foo->var: sheep

existing property: 1

called $Bar->var(): 1 <-----

called $Bar->var:  <-----

existing property: 

called $Baz->var(): 0

called $Baz->var: dog <-----

existing property: 1

called $Faz->var(): 0

called $Faz->var: cat

existing property: 1



Actual result:

--------------

called $Foo->var(): 1

called $Foo->var: sheep

existing property: 1

called $Bar->var(): 0

called $Bar->var: sheep

existing property: 

called $Baz->var(): 0

called $Baz->var: sheep

existing property: 1

called $Faz->var(): 0

called $Faz->var: cat

existing property: 1

------------------------------------------------------------------------
[2010-08-26 23:58:23] vik_ at hotmail dot com

Description:
------------
test script $t->priv2 throws 

Notice: Undefined property: test::$priv2 error.





Test script:
---------------
class base {

        private $priv = "private";

        protected $prot = "protected";

        public $pub = "public";

         final public function __get($prop){

                $cv = get_class_vars(__CLASS__); $ccv =
get_class_vars(get_called_class());

                var_dump('GET--------------', $prop, get_called_class(), 
__CLASS__,
$this, $cv, $ccv, isset($this->$prop), property_exists($this, $prop));

                return $this->$prop;

        }

         final public function __set($prop, $value){

                $cv = get_class_vars(__CLASS__); $ccv =
get_class_vars(get_called_class());

                var_dump('SET--------------', $prop, get_called_class(), 
__CLASS__,
$this, $cv, $ccv, isset($this->$prop), property_exists($this, $prop));

                $this->$prop = $value;

        }

}



class test extends base {

        private $priv2 = "private";

        protected $prot2 = "protected";

        public $pub2 = "public";

}



// pub2 and prot2 works.

$t = new test();

echo $t->pub2; echo $t->prot2; echo $t->priv2;

Expected result:
----------------
like base class results:



// it works.

$b = new base();

echo $b->pub; echo $b->prot; echo $b->priv;

Actual result:
--------------
Inconsistent behaviour:

1) $this has 6 properties (pub, prot, priv, pub2, prot2, priv2): good 

2) get_class_vars(get_called_class()) has 5, priv2 missing: wrong

3) isset($this->$prop) returns false in this case: wrong

4) property_exists($this, $prop)) returns true: good



maybe similar bug: #47808


------------------------------------------------------------------------



-- 
Edit this bug report at http://bugs.php.net/bug.php?id=52711&edit=1

Reply via email to