隐藏print_r或var_dump中的特定类字段

时间:2010-07-09 20:29:12

标签: php

是否可以隐藏print_r中的特定类字段?

<?php

class DataManager {
    public $data = array();
}

class Data {
    public $manager;
    public $data = array();

    public function Data ($m, $d) {
        $this->manager = $m;
        $this->data = $d;
    }
}

$manager = new DataManager();

for ($a = 0; $a < 10; $a++) {
    $manager->data[] = new Data($manager, 'Test ' . md5($a));
}

echo '<pre>';
print_r($manager);

?>

这会打印

  

DataManager对象(       [data] =&gt;排列           (               [0] =&gt;数据对象                   (                       [manager] =&gt; DataManager对象 RECURSION                       [data] =&gt;测试cfcd208495d565ef66e7dff9f98764da                   )

        [1] => Data Object
            (
                [manager] => DataManager Object  *RECURSION*
                [data] => Test c4ca4238a0b923820dcc509a6f75849b
            )    .......

是否有可能以某种方式改变输出行为,以便打印出来像这样?与DocComment / ** @hidden ** /

一样
  

DataManager对象(       [data] =&gt;排列           (               [0] =&gt;数据对象                   (                       [data] =&gt;测试cfcd208495d565ef66e7dff9f98764da                   )

        [1] => Data Object
            (
                [data] => Test c4ca4238a0b923820dcc509a6f75849b
            )

如果没有,是否有某种PHP库可能使用反射并以某种方式绕过东西?

由于

6 个答案:

答案 0 :(得分:21)

PHP 5.6 中引入了新的Magic方法__debugInfo(),允许您在转储对象时修改var_dump()的默认行为。

查看documentation

示例:

<?php
class C {
    private $prop;

    public function __construct($val) {
        $this->prop = $val;
    }

    public function __debugInfo() {
        return [
            'propSquared' => $this->prop ** 2,
        ];
    }
}

var_dump(new C(42));
?>

<强>返回:

object(C)#1 (1) {
  ["propSquared"]=>
  int(1764)
}

虽然这个问题已经有4年了,但我相信将来会有人发现这个问题很有用。

答案 1 :(得分:2)

print_r()和var_dump()都会为您提供一切。

各种Reflection类都有getDocComment()方法来获取类,方法和属性的/** doc comment */

利用doc注释来表示应该输出什么,不应该输出什么,你可以很容易地创建一个转储类来实现你想要的。

答案 2 :(得分:0)

是的,但仅限于内部。这只是不公开get_properties处理程序返回的哈希表中的相关属性的问题。

您还可以隐藏__get处理程序后面的属性,但您仍然需要将数据存储在某处,__get会有性能(和清晰度)惩罚。

答案 3 :(得分:0)

我虽然解决了这个问题,但我不知道它是否适合您的需求或效率如何,但似乎有效。

我所做的是将类中的变量更改为具有单个静态变量的函数。

这是一个简单的例子:

<?php
header('Content-type: text');
class myClass {
    public $visibleVar;

    function hiddenVar($set_to_new_val=null){
        static $theVariable;

        if(is_null($set_to_new_val))
            return $theVariable;

        $theVariable = $set_to_new_val;
    }
}

$test = new myClass;

$test->visibleVar = range(1,5);
print_r($test);
print_r($test->visibleVar);


$test->hiddenVar(range(100,105));
print_r($test);
print_r($test->hiddenVar());

?>

输出:

myClass Object
(
    [visibleVar] => Array
        (
            [0] => 1
            [1] => 2
            [2] => 3
            [3] => 4
            [4] => 5
        )

)
Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
    [4] => 5
)
myClass Object
(
    [visibleVar] => Array
        (
            [0] => 1
            [1] => 2
            [2] => 3
            [3] => 4
            [4] => 5
        )

)
Array
(
    [0] => 100
    [1] => 101
    [2] => 102
    [3] => 103
    [4] => 104
    [5] => 105
)

答案 4 :(得分:0)

我构建在Meir's solution上以扩展它以使用该类的多个对象。这是我的解决方案:

<?php
header('Content-type: text');
class myClass {
    public $visibleVar;
    private static $hiddenVarMap = array();
    private $hiddenVarKey;

    function hiddenVar($set_to_new_val=null){
        if(empty($this->hiddenVarKey) {
           $this->hiddenVarKey = sha1(rand());
        }
        if(!empty($set_to_new_val)){
           self::$hiddenVarMap[$this->hiddenVarKey] = $set_to_new_val;
        }

        return self::$hiddenVarMap[$this->hiddenVarKey];
    }
}

$test = new myClass;

$test->visibleVar = range(1,5);
print_r($test);
print_r($test->visibleVar);


$test->hiddenVar(range(100,105));
print_r($test);
print_r($test->hiddenVar());

?>

答案 5 :(得分:0)

您可以使用简单的闭包来隐藏敏感数据。

class PrivateValue {
    private $val;
    public function __construct($val) {
        $this->val = function() use ($val) { return $val; };
    }
    public function getValue() {
        return ($this->val)();
    }
    public fucntion __debugInfo() {
         return [ 'val' => '***' ]; // TODO
    }
}

存储闭包而非价值隐藏了我能想到的一切的价值。然后getter通过调用闭包来检索值。 __debugInfo方法为开发人员提供了一些有用但安全的表示,因为var_dump会显示它。 var_export等未处理的功能将显示'closure',但不显示boud值。

请记住,我尝试过一些工具,并且也要挖掘这些数据。

我从其他答案中得到灵感。 - 谢谢!