Show me your privates; just for a second
Moderator: General Moderators
- Ollie Saunders
- DevNet Master
- Posts: 3179
- Joined: Tue May 24, 2005 6:01 pm
- Location: UK
Show me your privates; just for a second
Calm down.
I am nighty nine point nine percent sure that the answer to this will be you can't but I'm gonna ask anyway.
I have written a complete class and I want to unit test it. I would like to get access to all the private and protected properties within it for the purpose of the test only, is this possible?
I am nighty nine point nine percent sure that the answer to this will be you can't but I'm gonna ask anyway.
I have written a complete class and I want to unit test it. I would like to get access to all the private and protected properties within it for the purpose of the test only, is this possible?
can be done via reflection.
see http://de2.php.net/reflection
Code: Select all
<?php
class Foo {
private $bar;
public function __construct() {
$this->bar = 4711;
}
}
$foo = new Foo;
$ref = new ReflectionClass('Foo');
$property = $ref->getProperty('bar');
echo $property->getValue($foo);
?>- Ollie Saunders
- DevNet Master
- Posts: 3179
- Joined: Tue May 24, 2005 6:01 pm
- Location: UK
Well I was hoping for something better than reflection but this is actually pretty sweet:
Code: Select all
class OF_UnitTest extends UnitTestCase
{
static function expose($obj, $prop)
{
$reflection = new ReflectionClass($obj);
$prop = $reflection->getProperty($prop);
return $prop->getValue($obj);
}
}- Ollie Saunders
- DevNet Master
- Posts: 3179
- Joined: Tue May 24, 2005 6:01 pm
- Location: UK
O i c
There was a comment on that link sweatje posted saying that PHP's ReflectionProperty should have a makePublic() method, you could then iterate over an entire object pretty easily. Of course what would be really good is a friend class akin to C++.
There was a comment on that link sweatje posted saying that PHP's ReflectionProperty should have a makePublic() method, you could then iterate over an entire object pretty easily. Of course what would be really good is a friend class akin to C++.
- Chris Corbyn
- Breakbeat Nuttzer
- Posts: 13098
- Joined: Wed Mar 24, 2004 7:57 am
- Location: Melbourne, Australia
- Ollie Saunders
- DevNet Master
- Posts: 3179
- Joined: Tue May 24, 2005 6:01 pm
- Location: UK
What for?ole wrote:There was a comment on that link sweatje posted saying that PHP's ReflectionProperty should have a makePublic() method,
Code: Select all
<?php
class Foo {
private $bar1;
private $bar2;
private $barABC;
private $barK;
public function __construct() {
$this->bar1 = rand(1,99);
$this->bar2 = rand(1,99);
$this->barABC = rand(1,99);
$this->barK = rand(1,99);
}
}
$foo = new Foo;
$ref = new ReflectionObject($foo);
$properties = $ref->getProperties();
foreach($properties as $prop) {
echo $prop->getName(), ' : ', $prop->getValue($foo), "<br />\n";
}
?>volka wrote:What for?ole wrote:There was a comment on that link sweatje posted saying that PHP's ReflectionProperty should have a makePublic() method,Code: Select all
<?php class Foo { private $bar1; private $bar2; private $barABC; private $barK; public function __construct() { $this->bar1 = rand(1,99); $this->bar2 = rand(1,99); $this->barABC = rand(1,99); $this->barK = rand(1,99); } } $foo = new Foo; $ref = new ReflectionObject($foo); $properties = $ref->getProperties(); foreach($properties as $prop) { echo $prop->getName(), ' : ', $prop->getValue($foo), "<br />\n"; } ?>
Code: Select all
bar1 :
Fatal error: Uncaught exception 'ReflectionException' with message 'Cannot access non-public member' in Command line code:20Code: Select all
$ php -v
PHP 5.0.3 (cli) (built: Mar 7 2005 22:56:05)
Copyright (c) 1997-2004 The PHP Group
Zend Engine v2.0.3, Copyright (c) 1998-2004 Zend Technologieshm, no problems with
This MBO_0 was obviously not defined when both php versions used by me were compiled.
I don't know what MBO_0 is good for. But it voids the use of reflection in this case
edit #2:
andPHP 5.1.5 (cli) (built: Aug 15 2006 23:54:56)
edit:PHP 5.1.4-pl6-gentoo (cli) (built: Aug 22 2006 01:59:09)
http://cvs.php.net/viewcvs.cgi/php-src/ext/reflection/php_reflection.c?revision=1.164.2.33&view=markup wrote:CVS Tags: php_5_1_3, php_5_1_3RC2, php_5_1_3RC3, php_5_1_4, php_5_1_5, php_5_1_5RC1, php_5_1_6
Code: Select all
/* {{{ proto public mixed ReflectionProperty::getValue([stdclass object])
Returns this property's value */
ZEND_METHOD(reflection_property, getValue)
{
reflection_object *intern;
property_reference *ref;
zval *object;
zval **member= NULL;
METHOD_NOTSTATIC(reflection_property_ptr);
GET_REFLECTION_OBJECT_PTR(ref);
#if MBO_0
if (!(ref->prop->flags & ZEND_ACC_PUBLIC)) {
_DO_THROW("Cannot access non-public member");
/* Returns from this function */
}
#endif
I don't know what MBO_0 is good for. But it voids the use of reflection in this case
edit #2:
http://www.xy1.org/internals@lists.php.net/msg03498.html wrote:> Hi All,
> what this MBO_0 mean?
cvs convention around these parts. rather than #ifdef 0, the person doing
the #ifdef uses his/her cvs user name appended with "_0". in this case the
guilty party appears to be Marcus.
- Ollie Saunders
- DevNet Master
- Posts: 3179
- Joined: Tue May 24, 2005 6:01 pm
- Location: UK
