Is it possible to hide a specific class fields from print_r ?
I though of a solution to this, I don't know if it will work for your needs or how efficient it is but it seems to work.
What I did was changed the variable in the class to a function with a single static variable.
Here's a quick example:
<?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());
?>
Output:
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
)
I built upon Meir's solution to extend it to work with multiple objects of the class. Here is my 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());
?>
You can use simple closure to hide the sensitive data.
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
}
}
Storing the closure rather than value hides the value from everything I can think of. The getter then retrieves the value by invoking the closure. The __debugInfo
method provides some useful but safe representation for developers as var_dump
will show it. Unhandled features like var_export will show 'closure', but not the boud value.
Keep in mind that some tools my try too hard and dig out these data too.
I've got the inspiration from other answers here. — Thank you!
Both print_r() and var_dump() will give you everything.
Various Reflection
classes have a getDocComment()
method to get the /** doc comment */
for classes, methods and properties.
Utilising doc comments to denote what should and should not be output, you can quite easily create a dumping class to achieve what you want.
Yes, but only internally. It's just a matter of not exposing the relevant property in the hash table returned by the get_properties handler.
You can also hide the property behind a __get
handler, but you still have to store the data somewhere and __get
has a performance (and clarity) penalty.
New Magic method __debugInfo() was introduced in PHP 5.6 that will allow you to modify the default behaviour of var_dump() when dumping your objects.
Have a look at the documentation.
Example:
<?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));
?>
Returns:
object(C)#1 (1) {
["propSquared"]=>
int(1764)
}
Although this question is 4 years old, I'm sure someone will find this useful in the future.