讓我們看一下,有一個轉換數組的函數:
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在實際屬性值前面加上的那一段,也就最後生成了”乾淨整潔“的數組。