PHP開發人員基本上都會犯錯的運算詳解

來源:互聯網
上載者:User
一.前言

最近老碰到一些因為php做數學運算,發生不痛不癢的小問題。

千裡之堤,潰於蟻穴。加個類型轉換,so easy解決了,我覺得不能就這麼放過去。

尤其是用php做財務運算或者寫介面運算與強語言對接的同學,可得多加註意。

事情不大,細節決定成敗,仔細研究後門道確實挺多,自己也好好補了一課。

你真的知道php是弱類型語言嗎?

前段時間展開過針對php核心的研究,對php變數底層儲存結構做了細緻的瞭解,但是對不同類型數值的運算過程不甚明白,變數類型的轉變過程。

其實就是我們智能的PHP【類型自動轉換】的問題,這也是PHP作為弱類型語言強大的地方,索性完整研究一下做個總結。

(下邊有5個案例,都是很簡單的運算,但你可不一定能說得出其中緣由)

二.過程分析

案例一

先看看我碰到的問題(簡化過),也就是我要寫這篇部落格的導火索。

  $a = '1.11';  $b = '0.11';  var_dump($a);//string(4) "1.11"   var_dump($b);//string(4) "0.11"   $re = $a - $b;  var_dump($re);//float(1)

注意:發生了兩個變化。
1.字串相減,變成浮點型
2.被減數都是兩位小數,結果為沒有小數【這也是發生bug的地方,app因為顯示時需要小數點後兩位】
同理,當為字串無小數數字相減,結果為int

 $a = '11';  $b = '1';  var_dump($a);//string(4) "11"   var_dump($b);//string(4) "1"   $re = $a - $b;  var_dump($re);//int(10)

結論:
1.在PHP底層運算的過程中,會自動進行類型轉換,小數的轉換成float,整數轉換成int。
2.需要對數字有小數點後幾位限制的,記得處理一下。number_format();

已經開了頭,那再來聊聊這個類型轉換的事兒唄。

案例二
問:下面是true還是false

    var_dump(0123 == 123);      var_dump('0123' == 123);      var_dump('0123' === 123);

答案是什麼呢??
false;true;false
分析:
相信第三個大家很容易猜出時false,因為===時強判斷嘛加入了類型的比較
這裡有兩個需要注意的點。一方面是0開的頭整形數字PHP底層會認為是八進位;另一方面是sting轉換成int時會把前邊的0去掉
var_dump(0123 == 123);// false,PHP會預設把0123當作8進位來處理,實際轉化為10進位就是83,顯然這不是相等的。
var_dump('0123' == 123);// true這裡php會非常有趣的將’0123’轉換成一個數字而且預設去掉了前面的0也就是123==123
var_dump('0123' === 123);// false很顯然上面的問題已經說過了數字和字串類型不一致。
結論:
1. 0開頭的整形數字PHP會當作八進位來處理
2. 同案例一的結論1,字串在運算時會自動做類型轉換,而且會把前邊的0去掉


案例三
下面$x的結果是多少:

      $x = NULL;      if ('0xFF' == 255) {          $x = (int)'0xFF';      }      $x = ?

答案是什麼呢??
$x=0而不是255
注意點:
首先'oxFF' == 255我們好判斷,會進行轉換將16進位數字轉換成10進位數字,0xff = 255。PHP使用is_numeric_string 判斷字串是否包含十六進位數字然後進行轉換。
但是$x = (int)'0xFF';是否也會變成255呢?顯然不是,將一個字串進行強制類型轉換實際上用的是convert_to_long,它實際上是將字串從左向右進行轉換,遇到非數字字元則停止。因此0xFF到x就停止了。所以$x=0
結論:
1.0開頭的整形數字PHP會當作十六進位來處理
2. string->int的過程,是將字串從左向右進行轉換,遇到非數字字元則停止。

案例四
經過下面的運算 $x的值應該是多少?

  $x = 3 + "15%" + "$25"

答案是什麼呢?? 18
注意點:其實就是前邊的所提到的點。3+15+0=18(0時因為從左往右取數字嘛,遇到非數字停止,沒有當然為0)
案例五(無關類型轉換,但也很有意思)

 $a = true && false;  var_dump($a);  $a = true and false;  var_dump($a);

答案是什麼呢??
false;true

為什麼呢?是對運算子優先順序的一個理解,哈哈,提醒到這裡自己去查查吧~

案例六

  $arr = array(0,1,2,3);  foreach ($arr as $key => $value) {}  var_dump(current($arr));//最後指標停留在數組結尾,取不到值了輸出false  $arr = array(0,1,2,3);  foreach ($arr as $key => $value) {   //$arr其實是進行了一次傳值,用的是$arr_copy         $arr[$key] = $value;//進行了改值,則發生分離現象  }  var_dump(current($arr));//輸出1

輸出false 與 1;(PHP5.6環境下,php7已經做了修改);

那這個又是為什麼呢?【和PHP核心有關,變數分離改變】

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.