記錄一下今天遇到的兩隻bug

1、公司的項目起始比較早,一直用的是ThinkPHP3.1.2,即使搭建新項目也還是用它。今天發現在TP的視圖層使用if標籤時有個注意點:輸出內容中的空格會被trim掉

<input type="radio"<if condition="$c1"> disabled</if><if condition="$c2"> checked</if> value="" />
像以上這樣,雖然在disabled和checked前面加了空格,但是實際輸出時可能是這樣的:

<input type="radio"disabledchecked value="" />
是的,我特意爲他們之間保留的空格消失了,很必然這兩個屬性就不存在了,不是我要的效果。所以,遇到這種情況時應該這樣操作:
<input type="radio" <if condition="$c1">disabled</if> <if condition="$c2">checked</if> value="" />
即把空格直接挪到if標籤前面去。

2、一測試崗位同事的身份證號尾數剛好是0,於是他在測試我的程序功能時,將他的身份證尾號改爲X,發現竟然通過了我的身份證檢驗函數,但改爲1-9的其他數字時都能正常報錯,於是我立即反應過來,應該是我的身份證檢驗函數不完善。這是我的PHP同事在網上拿下來用了很久的函數了,打開函數一看,覺得末尾的if ($res != $a[17])似乎並沒有什麼問題

		/**
		 * 根據身份證號碼獲得性別年齡
		 * @param $IDCard
		 * @return mixed
		 */
		function getIDCardInfo($IDCard)
		{
		    $result['error'] = '';
		    $result['sex'] = '';
		    $result['date'] = '';
		    $result['age'] = '';
		    //去除空格
		    $IDCard = str_replace(' ', '', $IDCard);
		
		    if (!preg_match("/^(\d{15}$|^\d{18}$|^\d{17}(\d|X|x))$/", $IDCard)) {
		        $result['error'] = '身份證號碼格式不正確';
		        return $result;
		
		    } else {
		        //如果是15位 第15位單數是男,雙數爲女
		        if (strlen($IDCard) == 15) {
		            //實例130503 670401 001
		            $tyear = intval(substr($IDCard, 6, 2));
		            $tyear = "19" . $tyear;
		            $tmonth = intval(substr($IDCard, 8, 2));
		            $tday = intval(substr($IDCard, 10, 2));
		            $sex = intval(substr($IDCard, 14, 1));
		            if ($sex % 2 == 1) {
		                $result['sex'] = '1';
		            } else {
		                $result['sex'] = '2';
		            }
		            $result['date'] = $tyear . "-" . $tmonth . "-" . $tday;
		            //根據年月算出當前年齡
		            $now = strtotime("now");
		
		            list($year, $month, $day) = explode("-", date("Y-m-d", $now));
		
		            $age = $year - $tyear;
		
		            if ((int)($month . $day) < (int)($tmonth . $tday)) {
		                $age -= 1;
		            }
		
		            $result['age'] = $age;
		
		            //                對年齡進行判斷
		            if ($age > 120 || $age < 18) {
		                $result['error'] = "年齡異常,身份證號碼輸入有誤";
		            }
		
		        } elseif (strlen($IDCard) == 18) {
		            //如果是18位 判斷第17位 ,男性爲單數,女性爲雙數 511381 19890804 1213
		            $tyear = intval("" . substr($IDCard, 6, 4));
		            $tmonth = intval(substr($IDCard, 10, 2));
		            $tday = intval(substr($IDCard, 12, 2));
		            $sex = intval(substr($IDCard, 16, 1));
		            if ($sex % 2 == 1) {
		                $result['sex'] = '1';
		            } else {
		                $result['sex'] = '2';
		            }
		            $result['date'] = $tyear . "-" . $tmonth . "-" . $tday;
		            $now = strtotime("now");
		
		            list($year, $month, $day) = explode("-", date("Y-m-d", $now));
		
		            $age = $year - $tyear;
		
		            if ((int)($month . $day) < (int)($tmonth . $tday)) {
		                $age -= 1;
		            }
		
		            $result['age'] = $age;
		
		            //對年齡進行判斷
		            if ($age > 120 || $age < 18) {
		                $result['error'] = "年齡異常,身份證號碼輸入有誤";
		            }
		
		            //驗證最後一位的驗證碼
		            $a = str_split($IDCard, 1);
		
		            $w = array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2);
		            $c = array(1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2);
		
		            $sum = 0;
		            for ($i = 0; $i < 17; $i++) {
		                $sum = $sum + $a[$i] * $w[$i];
		            }
		            $r = $sum % 11;
		            $res = $c[$r];  //校驗碼
		
		            if ($res != $a[17]) {
		                $result['error']="身份證號碼最後一位校驗碼異常,輸入有誤";
		            }
		        }
		    }
		    return $result;
		}

但是又有所懷疑,於是改成if ((''.$res) != $a[17])把$res變量改成字符形式,終於能夠報錯了。

這個問題是因爲條件兩端數據類型不一致產生的,正是因爲我留意過很多種變量類型不一致的判斷而發生的異常,所以纔會去做這種嘗試,沒想到真的就一次成功了。

可是問題又來了,$a數組的所有元素都應該是字符類型,爲什麼0-9的數字形式字符都能正常判斷,偏偏字符X不能正常判斷呢?仔細看一下代碼,$res取自$c數組,而$c數組裏面的0是數字形式,須知PHP是弱類型語言,當數字與字符作比較時會將字符轉爲數字後再按數字類型進行比較,因此還有一個解法是給$c裏面的0也像X一樣套上引號,like this:

$c = array(1, '0', 'X', 9, 8, 7, 6, 5, 4, 3, 2);
而其他數字套不套引號並不重要,並不影響最終的計算驗證。

如果是我來寫這個函數,我的方式可能是

$c = str_split('10X98765432', 1);
這樣就不會存在上面的問題了。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章