mysql_connect - 最原始的,大多數教科書使用的
mysqli - i 代表 Improvement ,提更了相對進階的功能,就 Extension 而言,本身也增加了安全性。
pdo - (PHP Data Object) 則是提供了一個 Abstraction Layer 來操作資料庫
下面範例讀取trade資料庫的salary資料表,範例資料內容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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
1 2 3 4 5 6 7 8 9 10 11 | 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
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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
1 2 3 4 5 6 | $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" ; } |
使用mysqli避免SQL Injection
1 2 3 4 5 6 7 8 9 10 11 12 13 | $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" ; } |
優點:可以Bind Column。多援 Transaction, Multi Query,提供了 Object oriented style
使用PDO
1 2 3 4 5 6 7 8 9 10 11 12 13 | $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寫的好,資料庫連接沒煩惱!
回覆刪除