您仍然可以将对象强制转换为数组以获取其所有成员并查看其可见性。例如
<?php
class Potatoe {
public $skin;
protected $meat;
private $roots;
function __construct ( $s, $m, $r ) {
$this->skin = $s;
$this->meat = $m;
$this->roots = $r;
}
}
$Obj = new Potatoe ( 1, 2, 3 );
echo "<pre>\n";
echo "使用 get_object_vars:\n";
$vars = get_object_vars ( $Obj );
print_r ( $vars );
echo "\n\n使用数组转换:\n";
$Arr = (array)$Obj;
print_r ( $Arr );
?>
这将返回
使用 get_object_vars
数组
(
[skin] => 1
)
使用数组转换
数组
(
[skin] => 1
[ * meat] => 2
[ Potatoe roots] => 3
)
如您所见,您可以从此转换中获得每个成员的可见性。那些似乎在数组键中使用空格的是 '\0' 字符,因此解析键的一般规则似乎是
公共成员:member_name
受保护的成员:\0*\0member_name
私有成员:\0Class_name\0member_name
我编写了一个 obj2array 函数,它为每个键创建没有可见性的条目,这样您就可以像在对象中一样在数组中处理它们
<?php
function obj2array ( &$Instance ) {
$clone = (array) $Instance;
$rtn = array ();
$rtn['___SOURCE_KEYS_'] = $clone;
while ( list ($key, $value) = each ($clone) ) {
$aux = explode ("\0", $key);
$newkey = $aux[count($aux)-1];
$rtn[$newkey] = &$rtn['___SOURCE_KEYS_'][$key];
}
return $rtn;
}
?>
我还创建了一个 <i>bless</i> 函数,其工作原理类似于 Perl 的 bless,这样您就可以进一步重新转换数组,将其转换为特定类的对象
<?php
function bless ( &$Instance, $Class ) {
if ( ! (is_array ($Instance) ) ) {
return NULL;
}
if ( isset ($Instance['___SOURCE_KEYS_'])) {
$Instance = $Instance['___SOURCE_KEYS_'];
}
$serdata = serialize ( $Instance );
list ($array_params, $array_elems) = explode ('{', $serdata, 2);
list ($array_tag, $array_count) = explode (':', $array_params, 3 );
$serdata = "O:".strlen ($Class).":\"$Class\":$array_count:{".$array_elems;
$Instance = unserialize ( $serdata );
return $Instance;
}
?>
使用这些,您可以执行以下操作
<?php
define("SFCMS_DIR", dirname(__FILE__)."/..");
require_once (SFCMS_DIR."/Misc/bless.php");
class Potatoe {
public $skin;
protected $meat;
private $roots;
function __construct ( $s, $m, $r ) {
$this->skin = $s;
$this->meat = $m;
$this->roots = $r;
}
function PrintAll () {
echo "skin = ".$this->skin."\n";
echo "meat = ".$this->meat."\n";
echo "roots = ".$this->roots."\n";
}
}
$Obj = new Potatoe ( 1, 2, 3 );
echo "<pre>\n";
echo "Using get_object_vars:\n";
$vars = get_object_vars ( $Obj );
print_r ( $vars );
echo "\n\nUsing obj2array func:\n";
$Arr = obj2array($Obj);
print_r ( $Arr );
echo "\n\nSetting all members to 0.\n";
$Arr['skin']=0;
$Arr['meat']=0;
$Arr['roots']=0;
echo "Converting the array into an instance of the original class.\n";
bless ( $Arr, Potatoe );
if ( is_object ($Arr) ) {
echo "\$Arr is now an object.\n";
if ( $Arr instanceof Potatoe ) {
echo "\$Arr is an instance of Potatoe class.\n";
}
}
$Arr->PrintAll();
?>