在PHP中把物件當數組使用

巴扎黑
發布: 2023-03-02 15:58:02
原創
2326 人瀏覽過

  我們了解,JAVASCRIPT中,物件的屬性、方法,是可以用陣列的模式來存取的。但通常情況下是不可能的。

        為什麼要這麼做?這是因為,透過這個方式,可以更方便地操作對象,我們可以定義一個類別。而不是定義一個Key Value數組。自然,如果我們還有其它的辦法,一種最簡單的,就是強制轉換成陣列。但,這樣會失去物件中原有的方法。

        不過,SPL中的ArrayObject可以幫助我們以陣列模式存取屬性。但方法仍不能實現。

        ArrayObject類別結構如下(部分方法是在php5,1或php5.2時才加上的):

ArrayObject implements IteratorAggregate , Traversable , ArrayAccess , Serializable , Countable {
/* 常量 */
const integer STD_PROP_LIST = 1 ;
const integer ARRAY_AS_PROPS = 2 ;
/* 方法 */
__construct ([ mixed $input [, int $flags [, string $iterator_class ]]] )
void append ( mixed $value )
void asort ( void )
int count ( void )
array exchangeArray ( mixed $input )
array getArrayCopy ( void )
int getFlags ( void )
ArrayIterator getIterator ( void )
int getIteratorClass ( void )
void ksort ( void )
void natcasesort ( void )
void natsort ( void )
bool offsetExists ( mixed $index )
mixed offsetGet ( mixed $index )
void offsetSet ( mixed $index , mixed $newval )
void offsetUnset ( mixed $index )
public void serialize ( void )
void setFlags ( int $flags )
void setIteratorClass ( string $iterator_class )
void uasort ( callback $cmp_function )
void uksort ( callback $cmp_function )
public void unserialize ( string $serialized )
}
登入後複製

 其中:為什麼我們可以用$obj['name'] 直接存取$obj->name呢? 主要是上面的方法中的三個方法:

        offsetGet 支援$obj['name'] 讀的方式

       rayAccess的函數Current等的預設實作。

        檢視一個範例程式碼:

class test extends ArrayObject{
public $name;
private $age = 21;
public function show(){
print_r(get_object_vars($this));
}
}
class test1{
public $name;
private $age = 21;
public function show(){
print_r(get_object_vars($this));
}
}
$obj=new test();
//使用数组方式读写属性
$obj['name']='hello';
$obj['nick']='mockArray';
echo $obj[&#39;nick&#39;], &#39;</br>&#39;;
var_dump($obj[&#39;show&#39;]);//检测是否可以访问方法:
print_r($obj);//输出对象
$obj->show();//调用方法
$arr=(array)$obj; //强制转换成数组。
print_r($arr);
//$arr->show(); 此行将出错,因为,原有方法全部丢失。
$obj1=new test1(); //创建普通对象
$arr1=(array)$obj1; //强制转换成数组。
print_r($arr1); //隐私完全暴光
登入後複製

  這段程式碼會輸出:

mockArrayNULL

test

(
[name] => hello
    [nick] => mockArray
)
Array
(
    [name] => hello
    [  test1 age] => 21
)

         可以看出,完全可以使用陣列模式存取屬性,但不能存取到方法(成員函數)。

         強制轉換後,即為陣列對象,再無成員函數了。

         當然 offsetGet  offsetSet 這兩種方法,也可依我們的需求進一步改寫。為什麼?因為,如果有一些十分變態的需求之時,就一定有用。例如,我們要將三個陣列用引用的方式包裝到一個物件中,當成一個陣列來存取。這時,就要重寫這兩個函數。當然,同時也要重寫ArrayAccess介面中對應的函數。

         再有,能夠存取到的均是公有屬性。如果是私有的,則存取不到的。即便是強制轉換成數組,也是一樣。但如果沒有繼承ArrayObject,就不同了。這樣的類,一旦強制轉換成數組,其隱私(私有的屬性)也就被暴光了。

         不過我們可以看出,私有屬性轉換成陣列以後,未保留原有屬性名。而是使用了:某個不可列印字元+類別名稱+不可列印字元+屬性名的形式。這個不可印字ASCII是多少沒查,你要有興趣可以查!

相關標籤:
php
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板