PHP手冊之類型轉(zhuǎn)換的判別

前言

PHP手冊系列文章,會挑選一些手冊中有意思的評論進(jìn)行翻譯
手冊目錄: 語言參考---類型---類型轉(zhuǎn)換的判別
參考詳情

評論

  1. 兩個整數(shù)想除得到的可能是通過自動轉(zhuǎn)換后的float類型結(jié)果,所以你不需要通過整數(shù)加浮點(diǎn)數(shù)來避免結(jié)果截斷取整
$dividend = 2;
$divisor = 3;
$quotient = $dividend/$divisor;
print $quotient; // 0.66666666666667
  1. 將對象類型轉(zhuǎn)換為數(shù)組類型永遠(yuǎn)是心里的痛
class MyClass {
    private $priv = 'priv_value';
    protected $prot = 'prot_value';
    public $pub = 'pub_value';
    public $MyClasspriv ='second_pub_value';
}

$test = new MyClass();
echo '<pre>';
print_r((array) $test);

/* 輸出
Array
(
    [MyClasspriv] => priv_value
    [*prot] => prot_value
    [pub] => pub_value
    [MyClasspriv] => second_pub_value
)
*/

結(jié)果看上去很正常,對象屬性轉(zhuǎn)換為關(guān)聯(lián)數(shù)組,key是屬性,value是值,并且通過在key前面添加*來標(biāo)示其在對象中是protected的訪問等級,但是事實遠(yuǎn)非如此

foreach ((array) $test as $key =>$value) {
    $len = strlen($key);
    echo "{$key} ({$len}) => {$value}<br />";
    for ($i = 0;$i< $len; ++$i) {
        echo ord($key[$i]) .' ';
    }
    echo '<hr />';
}

/*輸出
MyClasspriv (13) => priv_value
0 77 121 67 108 97 115 115 0 112 114 105 118
*prot (7) => prot_value
0 42 0 112 114 111 116
pub (3) => pub_value
112 117 98
MyClasspriv (11) => second_pub_value
77 121 67 108 97 115 115 112 114 105 118
*/

輸出的字符碼顯示 protected屬性轉(zhuǎn)變成key的時候會添加'\0*\0',同時private屬性轉(zhuǎn)變成key的時候會添加'\0'._CLASS.'\0'

  1. ++操作符不會將boolean類型轉(zhuǎn)換程int類型,并且如果一個變量是boolean,值為true,那么對其++之后它還是true
$a = true; 
var_dump(++$a);  // 輸出 bool(true)

4.object 轉(zhuǎn)換到 object是可以的,通過serialize/unserialize操作,詳情見序列化

class my{
    public $m = 1;
    public function test(){
        echo 'he';
    }
}


class yo{
    public $mi = 2;
    public function testi(){
        echo 'hehe';
    }
}

$b = new my();
$a = serialize($b);
echo $a;  //輸出O:2:"my":1:{s:1:"m";i:1;},其中O表示object,O后面的2表示類名的長度,"my"表示類名,1表示變量個數(shù)(包括public,protected,private),s:1:"m"依次表示變量,變量名長度,變量名.所以我們要轉(zhuǎn)換成別的類,不僅要替換掉類名,同時也需要替換掉類名長度
$c = unserialize($a); 

if($c == $b) echo 'succ'; //輸出succ,說明$c和$b是同一個類的實例,并且屬性值都相等,注意$b!==$c

$a = str_replace('my','yo',$a); //新類名長度與舊類名長度一致,所以只需要替換類名部分
echo $a;  //輸出O:2:"yo":1:{s:1:"m";i:1;}
$d = unserialize($a); //新類產(chǎn)生

if($d instanceof yo)echo 'succ' //輸出succ,是yo類的實例

echo $d->m; //1

echo $d->mi; //2

echo $d->test(); //error:undefined method

echo $d->testi(); //hehe   //如此可以知道轉(zhuǎn)換后的類居然保存有舊類的變量屬性,但是不具備舊類的方法屬性,很神奇有木有,其實可以手動修改串O:2:"yo":1:{s:1:"m";i:1;},想添加什么變量都可以,但是注意protected的變量轉(zhuǎn)變成字符串之后會添加'\0*\0',具體見上面的class轉(zhuǎn)換成array

思考:那么舊類中的private和protected變量會不會也傳遞給新類呢,訪問限制等級是否會發(fā)生變化呢,如果舊類中的變量的初始值是另外一個類的實例又會怎樣,如果舊類extends其他類或者implements其他接口又會是怎樣,這個可以自己去實驗,不再一一贅述

  1. 一些更短更快的方法進(jìn)行類型轉(zhuǎn)換
$string='12345.678';
$float=+$string;
$integer=0|$string;
$boolean=!!$string;
  1. 你應(yīng)該意識到不要在對某個目標(biāo)連續(xù)進(jìn)行太多次類型轉(zhuǎn)換,因為這樣很可能意外的將false變成true
if(TRUE === (boolean) (array) (int) FALSE) {
    echo 'ca';
}  // (boolean)array(0) 變成 true了
  1. 從string轉(zhuǎn)換到int或者從int轉(zhuǎn)換到string是最常見的,php可以通過+.和.=來轉(zhuǎn)換
$x = 1;
var_dump($x);// int(1)
$x .= 1;
var_dump($x);// string(2) "11"; also an empty string ("") would cast to string without changing $x

$x = "1";
var_dump($x); // string(1) "1"
$x += 1;
var_dump($x);// int(2); also a zero value (0) would cast to int without changing $x
  1. 提出一段很有意思的代碼
$obj = new stdClass();
$obj->{'4'} = 'id';
$arr = (array) $obj;
var_dump($arr);
foreach ($arr as $key => $value) {
   var_dump($key);
    var_dump($arr[$key]);
}
?>

/*
輸出:
array(1) {
  ["4"]=>
  string(2) "id"
}
string(1) "4"
string(2) "id"
NULL
*/

發(fā)現(xiàn)怎么都讀取不到$arr[$key],應(yīng)該輸出$value的值,并且通過array()構(gòu)造$arr怎么都構(gòu)造不出下面這個數(shù)組

array(1) {
  ["4"]=>
  string(2) "id"
}

希望高手能解釋下這個問題

  1. unset看起來好像用處比較單一,但是如果你想把代碼變得緊湊,你可以在同一行使用變量并且unset它
$hello = 'Hello world';
$hello = (unset) print $hello;
// 等同于
$hello = 'Hello world';
print $hello;
unset($hello);
  1. 僅僅是一些關(guān)于unset的經(jīng)驗之談
$var = 1;
$var_unset = (unset) $var;
$var_ref_unset &= (unset)$var;   //把與&換成或|結(jié)果也一樣
var_dump($var);
var_dump($var_unset);
var_dump($var_ref_unset);

output:
int(1)
NULL
int(0)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,563評論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,694評論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 178,672評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,965評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,690評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,019評論 1 329
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,013評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,188評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,718評論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,438評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,667評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,149評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,845評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,252評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,590評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,384評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內(nèi)容