Code Igniter 2.1的PDO驅動中的一個蛋疼BUG

一天工友碰到問題,插入新數據的時候老是會寫入兩條。他一直懷疑是本身代碼有BUG、又或是數據庫設置錯誤,百思不得其解,而後就和我說了這個奇怪現象,我倆就一塊兒走近科學。php


一段簡單的SQL語句背後究竟隱藏着什麼驚天祕密!html

$this->db->query("INSERT INTO `student` (`name`, `selected`, `score`, `class`) VALUES ('小明', 1, 100, 1)");



這個SQL語句很是簡單,不可能有錯誤。sql

MYSQL表也檢查了,在數據庫客戶端中此語句完美運行,只插入了一條新數據。因而我懷疑是否是CI的query方法有問題。CI的query方法是由不一樣數據庫驅動控制的,工友用的是PDO,因此打開 ./system/database/drivers/pdo/pdo_driver.php,查看_execute這個實現query的方法。數據庫


CI的PDO驅動中負責query的方法fetch

function _execute($sql)
{
	$sql = $this->_prep_query($sql);
	$result_id = $this->conn_id->prepare($sql);
	$result_id->execute();
	
	if (is_object($result_id))
	{
		if (is_numeric(stripos($sql, 'SELECT')))
		{
			$this->affect_rows = count($result_id->fetchAll());
			$result_id->execute();
		}
		else
		{
			$this->affect_rows = $result_id->rowCount();
		}
	}
	else
	{
		$this->affect_rows = 0;
	}
	
	return $result_id;
}



一看代碼,我和個人工友都驚呆了。this


if (is_numeric(stripos($sql, 'SELECT')))
{
	$this->affect_rows = count($result_id->fetchAll());
	$result_id->execute();
}

這麼寫數據庫驅動你家裏人知道嗎?spa

即便說下面那個execute多是出現了GOTO FAIL那種代碼合併的BUG(詳情傳送門:http://www.2cto.com/os/201402/281454.html),那上面那句count又是什麼回事!你寫PDO驅動的時候覺得PDO是產品設計草圖的意思吧?設計


若是有人一時沒有反應過來這個BUG的精髓,我稍微講一下:此代碼會搜索最後執行的SQL語句,只要發現含有字符串「select」(仍是不區分大小寫的哦),就會第二次執行這條SQL。code

工友的表設計中有一個selected字段,因此每次添加都會有兩條……htm


這麼酷炫的BUG拿來寫MYSQL技術博客必定頗有趣。

相關文章
相關標籤/搜索