mysql_connect - 最原始的,大多數教科書使用的
mysqli - i 代表 Improvement ,提更了相對進階的功能,就 Extension 而言,本身也增加了安全性。
pdo - (PHP Data Object) 則是提供了一個 Abstraction Layer 來操作資料庫
下面範例讀取trade資料庫的salary資料表,範例資料內容:
mysql> desc salary; +-------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | is_traded | tinyint(1) | NO | | NULL | | | ps | varchar(255) | NO | UNI | NULL | | | update_time | datetime | NO | | NULL | | +-------------+--------------+------+-----+---------+----------------+ mysql> select * from salary; +----+-----------+--------+---------------------+ | id | is_traded | ps | update_time | +----+-----------+--------+---------------------+ | 1 | 0 | test11 | 2015-03-02 10:08:16 | | 3 | 1 | test | 2015-03-02 10:08:45 | | 6 | 1 | 456456 | 2015-03-04 11:53:57 | | 7 | 1 | 151656 | 2015-03-04 14:35:40 | +----+-----------+--------+---------------------+
使用mysql_connect
mysql_connect("localhost", "uaername", "password");
mysql_select_db("trade");
$is_traded = 1;
$result = mysql_query("SELECT * FROM `salary` WHERE is_traded = '$is_traded'");
while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
echo $row['ps']."\n";
}
mysql_free_result($result);
缺點:
$is_traded 的地方容易被 SQL Injection。必須使用mysql_escape_string() (備註:5.3.0之後棄用) 以及 mysql_real_escape_string(),但這樣敘述會變得複雜且醜陋,而且如果欄位多了,可以想見會是怎樣的情形...
mysql_connect使用mysql_real_escape_string()避免SQL Injection
mysql_connect("localhost", "root", "123123");
mysql_select_db("trade");
$is_traded = 1;
$query = sprintf("SELECT * FROM `salary` WHERE is_traded ='%s'", mysql_real_escape_string($is_traded));
echo "$query\n";
$result = mysql_query($query);
while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
echo $row['ps']."\n";
}
mysql_free_result($result);
使用mysqli
$mysqli = new mysqli("localhost", "username", "password", "trade");
$is_traded = 1;
$result = $mysqli->query("SELECT * FROM `salary` WHERE is_traded = '$is_traded'");
while ($row = $result->fetch_assoc()) {
echo "result is \$row['id']:{$row['id']}, \$row['is_traded']:{$row['is_traded']}, \$row['ps']:{$row['ps']}, \$row['update_time']:{$row['update_time']}\n";
}
一樣 $is_traded 的地方容易被 SQL Injection。使用mysqli避免SQL Injection
$mysqli = new mysqli("localhost", "root", "123123", "trade");
$stmt = $mysqli->prepare(
"SELECT * FROM `salary` WHERE is_traded =?");
$is_traded = "1'";
$stmt->bind_param( "s", $is_traded);
// "ss' is a format string, each "s" means string
$stmt->execute();
$stmt->bind_result($id, $is_traded, $ps, $update_time);
// then fetch and close the statement
while($stmt->fetch()){
echo "result is \$id:$id, \$is_traded:$is_traded, \$ps:$ps, \$update_time:$update_time\n";
}
缺點:select * 時必須按照順序用bind_result榜定各欄位。因fetch_assoc()不屬於$stmt的函數,所以不能叫他優點:可以Bind Column。多援 Transaction, Multi Query,提供了 Object oriented style
使用PDO
$dsn = "mysql:host=localhost;dbname=trade";
$dbh = new PDO($dsn, "root", "123123");
$sql = "SELECT * FROM `salary` WHERE is_traded =?";
$sth = $dbh->prepare($sql);
$sth->execute(array(1));
while ($result = $sth->fetch(PDO::FETCH_OBJ)) {
print_r($result);
}
$dbh = NULL;
優點:可以回傳欄位名稱的大小寫
但,實務上我們都用framework的DBI( database interface )來連資料庫,如ActiveRecord
參考資料:
http://blog.roga.tw/2010/06/%E6%B7%BA%E8%AB%87-php-mysql-php-mysqli-pdo-%E7%9A%84%E5%B7%AE%E7%95%B0/
Framework寫的好,資料庫連接沒煩惱!
回覆刪除