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寫的好,資料庫連接沒煩惱!
回覆刪除