Skip to content

Commit

Permalink
1) Use get_object_vars instead of ReflectionObject::getProperties whe…
Browse files Browse the repository at this point in the history
…never object contains method __get

2) In some cases method "dump" didn't work properly, because the following code triggers "Notice: Undefined property: Foo::$a", fixed issue:

class Foo
{
    private $a = 'a';

    public function __construct()
    {
        unset($this->a);
    }
}

$obj = new Foo();
$reflectionObj = new ReflectionObject($obj);
$reflectionProp = $reflectionObj->getProperty('a');
$reflectionProp->setAccessible(true);
$reflectionProp->getValue($obj);
  • Loading branch information
bkrukowski committed Apr 21, 2018
1 parent 55ea111 commit 768c3e5
Show file tree
Hide file tree
Showing 4 changed files with 192 additions and 1 deletion.
29 changes: 28 additions & 1 deletion src/Properties/AbstractProperties.php
Expand Up @@ -21,7 +21,34 @@ abstract class AbstractProperties implements PropertiesInterface
protected function getDeclaredProperties()
{
$reflection = new \ReflectionObject($this->object);
$result = array();

return $reflection->getProperties();
if ($reflection->hasMethod('__get')) {
foreach (\array_keys(\get_object_vars($this->object)) as $name) {
$result[] = $reflection->getProperty($name);
}

return $result;
}

foreach ($reflection->getProperties() as $property) {
$continue = false;
\set_error_handler(
function () use (&$continue) {
$continue = true;
},
E_NOTICE
);
$property->setAccessible(true);
$property->getValue($this->object);
\restore_error_handler();
if ($continue) {
continue;
}

$result[] = $property;
}

return $result;
}
}
25 changes: 25 additions & 0 deletions tests/MagicMethods/GetterObject.php
@@ -0,0 +1,25 @@
<?php

/*
* This file is part of the awesomite/var-dumper package.
*
* (c) Bartłomiej Krukowski <bartlomiej@krukowski.me>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Awesomite\VarDumper\MagicMethods;

/**
* @internal
*/
class GetterObject extends RemovedProperty
{
private $c = 'c';

public function __get($name)
{
return $this->$name;
}
}
88 changes: 88 additions & 0 deletions tests/MagicMethods/MagicMethodsTest.php
@@ -0,0 +1,88 @@
<?php

/*
* This file is part of the awesomite/var-dumper package.
*
* (c) Bartłomiej Krukowski <bartlomiej@krukowski.me>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Awesomite\VarDumper\MagicMethods;

use Awesomite\VarDumper\BaseTestCase;
use Awesomite\VarDumper\LightVarDumper;
use Awesomite\VarDumper\Properties\Properties;
use Awesomite\VarDumper\Properties\PropertyInterface;

/**
* @internal
*/
class MagicMethodsTest extends BaseTestCase
{
public function testDump()
{
$dumper = new LightVarDumper();
$object = new RemovedProperty();

$expected
= <<<'EXPECTED'
(2) {
private $a => “a”
private $b => “b”
}
EXPECTED;
$this->assertContains($expected, $dumper->dumpAsString($object));

$object->without('a');
$expected
= <<<'EXPECTED'
(1) {
private $b => “b”
}
EXPECTED;
$this->assertContains($expected, $dumper->dumpAsString($object));

$object->c = 'c';
$expected
= <<<'EXPECTED'
(2) {
private $b => “b”
$c => “c”
}
EXPECTED;
$this->assertContains($expected, $dumper->dumpAsString($object));

$getter = new GetterObject();
$this->assertContains('(0) {}', $dumper->dumpAsString($getter));
}

/**
* @dataProvider providerAbstractProperties
*
* @param $object
* @param string[] $expectedProperties
*/
public function testAbstractProperties($object, array $expectedProperties)
{
$reader = new Properties($object);

$this->assertSame(\count($expectedProperties), \count($reader->getProperties()));
foreach ($reader->getProperties() as $property) {
/** @var PropertyInterface $property */
$this->assertContains($property->getName(), $expectedProperties);
}
}

public function providerAbstractProperties()
{
return array(
array(new RemovedProperty(), array('a', 'b')),
array(new GetterObject(), array()),
array(RemovedProperty::createWithout(array('a')), array('b')),
array(RemovedProperty::createWithout(array('a'))->with('c'), array('b', 'c')),
array(RemovedProperty::createWithout(array('a', 'b')), array()),
);
}
}
51 changes: 51 additions & 0 deletions tests/MagicMethods/RemovedProperty.php
@@ -0,0 +1,51 @@
<?php

/*
* This file is part of the awesomite/var-dumper package.
*
* (c) Bartłomiej Krukowski <bartlomiej@krukowski.me>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Awesomite\VarDumper\MagicMethods;

/**
* @internal
*/
class RemovedProperty
{
private $a = 'a';

private $b = 'b';

public function without($name)
{
unset($this->$name);

return $this;
}

public function with($name, $value = null)
{
$this->$name = $value;

return $this;
}

/**
* @param string[] $props
*
* @return static
*/
public static function createWithout(array $props)
{
$result = new static();
foreach ($props as $prop) {
$result->without($prop);
}

return $result;
}
}

0 comments on commit 768c3e5

Please sign in to comment.