Show me your privates; just for a second

Discussion of testing theory and practice, including methodologies (such as TDD, BDD, DDD, Agile, XP) and software - anything to do with testing goes here. (Formerly "The Testing Side of Development")

Moderator: General Moderators

User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Post by Ambush Commander »

You could always extend the class and redeclare the property/method public.
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Post by Ollie Saunders »

volka wrote:Yes, but the question remains: why? What is its purpose?
Changing the classes behaviour for testing? Not such a good idea.
Well yes a friend class would be a lot better.
You could always extend the class and redeclare the property/method public.
There would make for quite a lot of classes.
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Post by Ambush Commander »

Using reflection, you could generate them on runtime.
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

This thread just reminded me of a seemingly odd behaviour I noticed a while ago.

Code: Select all

[feyd@home]>php -r "class foo{private $me;function __construct(){$this->me = __CLASS__;var_dump($this->me);}function foome(){var_dump($this->me);}} class bar extends foo{private $me;function __construct(){$this->me = __CLASS__;var_dump($this->me); parent::__construct(); var_dump($this->me);}} $bar = new bar(); $bar->me = 1234; $bar->foome();"
string(3) "bar"
string(3) "foo"
string(3) "bar"
Fatal error: Cannot access private property bar::$me in Command line code on line 1

[feyd@home]>php -r "class foo{private $me;function __construct(){$this->me = __CLASS__;var_dump($this->me);}function foome(){var_dump($this->me);}} class bar extends foo{protected $me;function __construct(){$this->me = __CLASS__;var_dump($this->me); parent::__construct(); var_dump($this->me);}}$bar = new bar(); $bar->me = 1234; $bar->foome();"
string(3) "bar"
string(3) "foo"
string(3) "bar"
Fatal error: Cannot access protected property bar::$me in Command line code on line 1

[feyd@home]>php -r "class foo{private $me;function __construct(){$this->me = __CLASS__;var_dump($this->me);}function foome(){var_dump($this->me);}} class bar extends foo{public $me;function __construct(){$this->me = __CLASS__;var_dump($this->me); parent::__construct(); var_dump($this->me);}} $bar = new bar(); $bar->me = 1234; $bar->foome();"
string(3) "bar"
string(3) "foo"
string(3) "bar"
string(3) "foo"

[feyd@home]>php -r "class foo{protected $me;function __construct(){$this->me = __CLASS__;var_dump($this->me);}function foome(){var_dump($this->me);}} class bar extends foo{private $me;function __construct(){$this->me = __CLASS__;var_dump($this->me); parent::__construct(); var_dump($this->me);}}$bar = new bar(); $bar->me = 1234; $bar->foome();"
Fatal error: Access level to bar::$me must be protected (as in class foo) or weaker in Command line code on line 1

[feyd@home]>php -r "class foo{protected $me;function __construct(){$this->me = __CLASS__;var_dump($this->me);}function foome(){var_dump($this->me);}} class bar extends foo{protected $me;function __construct(){$this->me = __CLASS__;var_dump($this->me); parent::__construct(); var_dump($this->me);}} $bar = new bar(); $bar->me = 1234; $bar->foome();"
string(3) "bar"
string(3) "foo"
string(3) "foo"
Fatal error: Cannot access protected property bar::$me in Command line code on line 1

[feyd@home]>php -r "class foo{protected $me;function __construct(){$this->me = __CLASS__;var_dump($this->me);}function foome(){var_dump($this->me);}} class bar extends foo{public $me;function __construct(){$this->me = __CLASS__;var_dump($this->me); parent::__construct(); var_dump($this->me);}} $bar = new bar(); $bar->me = 1234; $bar->foome();"
string(3) "bar"
string(3) "foo"
string(3) "foo"
int(1234)

[feyd@home]>php -r "class foo{public $me;function __construct(){$this->me = __CLASS__;var_dump($this->me);}function foome(){var_dump($this->me);}} class bar extends foo{private $me;function __construct(){$this->me = __CLASS__;var_dump($this->me); parent::__construct(); var_dump($this->me);}} $bar = new bar(); $bar->me = 1234; $bar->foome();"
Fatal error: Access level to bar::$me must be public (as in class foo) in Command line code on line 1

[feyd@home]>php -r "class foo{public $me;function __construct(){$this->me = __CLASS__;var_dump($this->me);}function foome(){var_dump($this->me);}} class bar extends foo{protected $me;function __construct(){$this->me = __CLASS__;var_dump($this->me); parent::__construct(); var_dump($this->me);}} $bar = new bar(); $bar->me = 1234; $bar->foome();"
Fatal error: Access level to bar::$me must be public (as in class foo) in Command line code on line 1

[feyd@home]>php -r "class foo{public $me;function __construct(){$this->me = __CLASS__;var_dump($this->me);}function foome(){var_dump($this->me);}} class bar extends foo{public $me;function __construct(){$this->me = __CLASS__;var_dump($this->me); parent::__construct(); var_dump($this->me);}} $bar = new bar(); $bar->me = 1234; $bar->foome();"
string(3) "bar"
string(3) "foo"
string(3) "foo"
int(1234)
Does anyone else find it odd that with the parent's property being private I can declare any access level to a completely separate, yet exactly named property in the child? I don't remember being able to do that in C++.

What about being able to loosen the access level of a protected parent property? I'd expect to be able to tighten the access level.

Note: I haven't searched the bug list. Their bug system and my searches don't get along too well.

before you ask:

Code: Select all

PHP 5.1.5 (cli) (built: Aug 15 2006 23:54:56)
Copyright (c) 1997-2006 The PHP Group
Zend Engine v2.1.0, Copyright (c) 1998-2006 Zend Technologies
    with Xdebug v2.0.0beta6, Copyright (c) 2002, 2003, 2004, 2005, 2006, by Derick Rethans
User avatar
sweatje
Forum Contributor
Posts: 277
Joined: Wed Jun 29, 2005 10:04 pm
Location: Iowa, USA

Post by sweatje »

I think the moral of this story is don't use or test private attributes or methods ;)
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Post by Ollie Saunders »

269! 269 lines!

Dammit feyd that deobfuscation took ages. Is that some kind of test to see if you have the determination to be worthy of feyd's omniscience. Well turns out I was, I'm gonna read it in a minute. But for the benefit of everyone else:

Code: Select all

<?php
class foo{
    private $me;
    function __construct(){
        $this->me = __CLASS__;
        var_dump($this->me);
    }
    function foome(){
        var_dump($this->me);
    }
} 
class bar extends foo{
    private $me;
    function __construct(){
        $this->me = __CLASS__;
        var_dump($this->me); 
        parent::__construct(); 
        var_dump($this->me);
    }
} 

$bar = new bar(); 
$bar->me = 1234; 
$bar->foome();
?>
string(3) "bar"
string(3) "foo"
string(3) "bar"
Fatal error: Cannot access private property bar::$me in Command line code on line 1

<?php

class foo{
    private $me;
    function __construct(){
        $this->me = __CLASS__;
        var_dump($this->me);
    }
    function foome(){
        var_dump($this->me);
    }
}

class bar extends foo{
    protected $me;
    function __construct(){
        $this->me = __CLASS__;
        var_dump($this->me);
        parent::__construct();
        var_dump($this->me);
    }
}

$bar = new bar(); 
$bar->me = 1234; 
$bar->foome();
?>
string(3) "bar"
string(3) "foo"
string(3) "bar"
Fatal error: Cannot access protected property bar::$me in Command line code on line 1

<?php
class foo{
    private $me;
    function __construct(){
        $this->me = __CLASS__;
        var_dump($this->me);
    }
    function foome(){
        var_dump($this->me);
    }
}

class bar extends foo{
    public $me;
    function __construct(){
        $this->me = __CLASS__;
        var_dump($this->me);
        parent::__construct();
        var_dump($this->me);
    }
}

$bar = new bar(); 
$bar->me = 1234; 
$bar->foome();
?>
string(3) "bar"
string(3) "foo"
string(3) "bar"
string(3) "foo"

<?php
class foo{
    protected $me;
    function __construct(){
        $this->me = __CLASS__;
        var_dump($this->me);
    }
    function foome(){
        var_dump($this->me);
    }
} 

class bar extends foo{
    private $me;
    function __construct(){
        $this->me = __CLASS__;
        var_dump($this->me); 
        parent::__construct(); 
        var_dump($this->me);
    }
}

$bar = new bar(); 
$bar->me = 1234; 
$bar->foome();
?>
Fatal error: Access level to bar::$me must be protected (as in class foo) or weaker in Command line code on line 1

<?php
class foo{
    protected $me;
    function __construct(){
        $this->me = __CLASS__;
        var_dump($this->me);
    }
    function foome(){
        var_dump($this->me);
    }
} 

class bar extends foo{
    protected $me;
    function __construct(){
        $this->me = __CLASS__;
        var_dump($this->me);
        parent::__construct();
        var_dump($this->me);
    }
}

$bar = new bar(); 
$bar->me = 1234; 
$bar->foome();
?>
string(3) "bar"
string(3) "foo"
string(3) "foo"
Fatal error: Cannot access protected property bar::$me in Command line code on line 1

<?php
class foo{
    protected $me;
    function __construct(){
        $this->me = __CLASS__;
        var_dump($this->me);
    }
    function foome(){
        var_dump($this->me);
    }
}

class bar extends foo{
    public $me;
    function __construct(){
        $this->me = __CLASS__;
        var_dump($this->me); 
        parent::__construct(); 
        var_dump($this->me);
    }
} 

$bar = new bar(); 
$bar->me = 1234; 
$bar->foome();
?>
string(3) "bar"
string(3) "foo"
string(3) "foo"
int(1234)

<?php
class foo{
    public $me;
    function __construct(){
        $this->me = __CLASS__;
        var_dump($this->me);
    }
    function foome(){
        var_dump($this->me);    
    }
} 

class bar extends foo{
    private $me;
    function __construct(){
        $this->me = __CLASS__;
        var_dump($this->me);
        parent::__construct();
        var_dump($this->me);
    }
} 

$bar = new bar();
$bar->me = 1234;
$bar->foome();
?>
Fatal error: Access level to bar::$me must be public (as in class foo) in Command line code on line 1

<?php
class foo{
    public $me;
    function __construct(){
        $this->me = __CLASS__;
        var_dump($this->me);
    }
    function foome(){
        var_dump($this->me);
    }
}

class bar extends foo{
    protected $me;
    function __construct(){
        $this->me = __CLASS__;
        var_dump($this->me);
        parent::__construct();
        var_dump($this->me);
    }
} 

$bar = new bar();
$bar->me = 1234;
$bar->foome();
?>
Fatal error: Access level to bar::$me must be public (as in class foo) in Command line code on line 1

<?php
class foo{
    public $me;
    function __construct(){
        $this->me = __CLASS__;
        var_dump($this->me);
    }
    function foome(){
        var_dump($this->me);
    }
}

class bar extends foo{
    public $me;
    function __construct(){
        $this->me = __CLASS__;
        var_dump($this->me);
        parent::__construct();
        var_dump($this->me);
    }
}

$bar = new bar(); 
$bar->me = 1234; 
$bar->foome();
?>
string(3) "bar"
string(3) "foo"
string(3) "foo"
int(1234)
Can somebody either point me to something that will automatically do that job else feyd, could you please make just a little attempt at making your codes readable. I'm asking nicely : )
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

It was a copy from a quick command line.. I wasn't really expecting you, anyone really, to break it out into the code under "normal" coding. .. and you haven't seen obfuscation from me yet. :)
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Post by Ollie Saunders »

I wasn't really expecting you, anyone really, to break it out into the code under "normal" coding
Why post it then?
and you haven't seen obfuscation from me yet.
Don't please, I may have nightmares :P

Anyway I've been looking at that code, and i'm going to need a hint as to what is interesting, I'm sure I could find it, but it would save me a lot of time.
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

Walk the execution of the first snippet. Notice anything odd?
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Post by Ollie Saunders »

Ahh yes. Somewhat of an anticlimax I feel.
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Post by Jenk »

that could pose really painful problems..

also this one for size, though it proves just the same thing:

Code: Select all

<?php

class foo{
    private $me = 1;
    function __construct(){
        var_dump($this->me);
    }
    function foome(){
        var_dump($this->me);
    }
}

class bar extends foo{
    public $me = 2;
    function __construct(){
        var_dump($this->me);
        $this->foome();
        parent::__construct();        
        var_dump($this->me);
    }
}

$bar = new bar();
$bar->me = 1234;
$bar->foome();
?>

Code: Select all

int(2) int(1) int(1) int(2) int(1)
Post Reply