您仍然可以將物件轉換為陣列,以取得其所有成員並查看其可見性。範例
<?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 "Using get_object_vars:\n";
$vars = get_object_vars ( $Obj );
print_r ( $vars );
echo "\n\nUsing array cast:\n";
$Arr = (array)$Obj;
print_r ( $Arr );
?>
這會傳回
Using get_object_vars
Array
(
[skin] => 1
)
Using array cast
Array
(
[skin] => 1
[ * meat] => 2
[ Potatoe roots] => 3
)
如您所見,您可以從此轉換取得每個成員的可見性。陣列索引中看起來像是空格的是 '\0' 字元,因此剖析索引的一般規則似乎是
Public 成員:member_name
Protected 成員:\0*\0member_name
Private 成員:\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 "使用 get_object_vars:\n";
$vars = get_object_vars ( $Obj );
print_r ( $vars );
echo "\n\n使用 obj2array 函式:\n";
$Arr = obj2array($Obj);
print_r ( $Arr );
echo "\n\n將所有成員設定為 0。\n";
$Arr['skin']=0;
$Arr['meat']=0;
$Arr['roots']=0;
echo "將陣列轉換為原始類別的實例。\n";
bless ( $Arr, Potatoe );
if ( is_object ($Arr) ) {
echo "\$Arr 現在是一個物件。\n";
if ( $Arr instanceof Potatoe ) {
echo "\$Arr 是 Potatoe 類別的一個實例。\n";
}
}
$Arr->PrintAll();
?>