深入瞭解PHP類型戲法 (array)var 強制數組轉換

讓我們看一下,有一個轉換數組的函數:

function object_to_array($object) {
    $arr = (array) $object;
    foreach($arr as $k => $v) {
        unset($arr[$k]);
        $arr[preg_replace('/^.+\0/', '', $k)] = $v;
    }
    return $arr;
}  

爲什麼要加

foreach($arr as $k => $v) {
    unset($arr[$k]);
    $arr[preg_replace('/^.+\0/', '', $k)] = $v;
}

單單 $arr = (Array) $object;就可以轉換成數組了,加上那麼一段代碼是不是多此一舉呢?


剛看到的時候我也很蒙,似乎的確是比較畫蛇添足,唯一有價值的線索信息是其中的正則/^.+\0/,其他的都好理解,關鍵在於\0是個什麼玩意兒。

搜索一番無果,突然想起在直接使用(array)這種方式轉換時,php會在protected和private屬性的鍵上做一些“手腳”,於是寫了demo如下

<?php
class myclass{
    public $a='a';
    private $b='b';
    protected $c='c';
}
$o = new myclass();
print_r((array)$o);
 輸出
Array(
    [a] => a
    [myclassb] => b
    [*c] => c
)


也就是說private屬性前面會加類名,protected前面會加星號。加上那一段代碼後,轉換的結果不一樣,輸出如下
Array(
    [a] => a
    [b] => b
    [c] => c
)


輸出結果是非常”乾淨整潔“的內容,不用說,玄機就在正則中的\0
可以確定的是,\0肯定是一個非法字符,但是\0爲什麼能幹掉前面一大堆的東西,繼續查資料發現:上面所述的myclassb和*c並不是真的”眼見爲實”,他們實際上是\0myclass\0b和\0*\0c,這個\0,是一個asc碼爲0的字符(不懂asc碼的自己去查),也就是說,.+\0這一段正則,正好匹配了php在實際屬性值前面加上的那一段,也就最後生成了”乾淨整潔“的數組。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章