MySQL数据库PDO教程

1.为什么要使用PDO?

mysql_*函数已经过时,相当一段时间以来,mysql_*函数在其他SQL数据库编程接口方面已经有所差别;它不支持预处理,存储过程,事务等一些现代数据库设计思想,SQL语句字符转义函数 mysql_real_escape_string()  和拼接SQL语句的编程方法已经过时并且很容易出错.最近一段时间里,它缺乏开发者关注,缺少维护将可能导致一些安全问题不能及时修复,或者在适配新版本的MySQL的时候不能正常工作,这成为mysql_*函数面临的另一个问题.PHP社区最近也对mysql_*函数给出不建义使用的建义,也有可能在未来的版本中最终被弃用.

PDO拥有更好的编程接口,你可以使用它写出更加简洁,高效,安全的代码.PDO还为不同的SQL数据库提供了不同的驱动,方便你使用新的数据库而不用再学不同的编程接口.与拼接SQL语句构造查询语句不同,绑定参数可以简洁方便地构造出更加安全的查询 语句,使用绑定参数 的方法在多次相似语句查询 (仅仅某个参数不同)中也可以提高不少性能。PDO在错误处理方面也提供了多种方法。mysql_*函数缺乏一致的处理,与PDO的异常模式相比,或者说没有处理异常,使用PDO,你可以得到一致的错误处理,这将节省您大师的时间来跟踪问题。

在当前的PHP版本中,PDO模块是默认安装启用的,但是在使用PDO前你还需要安装另外两个软件包,一个是pdo_mysql数据库驱动程序 ,别外一个是类似php-mysql的mysql驱动程序 。

2.连接MySQL

2.1. 以前的连接方式

$link = mysql_connect('localhost','user','pass');
mysql_select_db('testdb',$link);
mysql_set_charset('UTF-8',$link);

2.2.新的连接方式

*创建一个PDO对象,参数包括DSN,username,password和一个驱动选项数组(可忽略)。

*DSN其实就是一个告诉PDO该使用哪一种数据库驱动和一些连接信息的字符串,了解更多PDO MYSQL DSN .

$db = new PDO('mysql:host=localhost;dbname=testdb;charset=utf8','username','password', array(PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));

你也可以在创建PDO对象后再通过setAttribute方法设置相应选项。

$db = new PDO('mysql:host=localhost;dbname=testdb;charset=utf8','username','password');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES,false);
3.错误处理

3.1. mysql_*函数的错误处理

//connected to mysql
$result = mysql_query("SELECT * FROM table", $link) or die(mysql_error($link));

OR die() 是个不错的处理方法,但是会因此结束页面,将错误信息呈现到用户面前,这可能是我们不想看到的结果 。

PDO有三种错误处理模式:

1.PDO::ERRMODE_SILENT #和mysql_*函数类似,检查代码并查看$db->errorInfo();获取详细信息。

2.PDO::ERRMODE_WARNING #抛出PHP警告。

3.PDO::ERRMOD_EXCEPTION #抛出PDOException异常,在我认为,这是我们应该使用的模式,这和die(mysql_error());类似,但是它可以捕获并抛出具体异常信息。

3.2. code:

try{
    //connect as appropriate as above
    $db->query('hi'); //invalid query!
}catch(PDOException $ex){
    echo "An Error occured!"; //user friendly message
    some_logging_function($ex->getMessage());
}

注意: 你可以不用立即执行并捕获异常,你可以在任何合适的时候随时捕获。

function getData($db){
    $stmt = $db->query(SELECT * FROM table);
    return $stmt->fetchAll(PDO::FETCH_ASSOC);
}

//then much later

try{
    getData($db);

}catch (PDOException $ex){
    //handle me.
}

如果 你不想使用try/catch来处理异常,就像使用 OR die()那样处理,在production模式下关闭display_error选项即可。

4.简单查询语句(SELECT)

4.1. MYSQL_* 代码

$result = mysql_query('SELECT * FROM table') or die (mysql_error());

$num_rows = mysql_num_rows($result);

while($row = mysql_fetch_assoc($result)){
    echo $row['field'] . '' . $row['field2']; //etc
}

4.2 PDO代码

foreach ($db->query('SELECT * FROM table') as $row ){
    echo $row['field1'] . ' ' . $row['field2']; //etc

}

query() 方法返回一个PDOStatement 对象,你可以通过如下方法获取结果:

$stmt = $db->query('SELECT * FROM table');

while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
    echo $row['field1'] . ' ' . $row['field2']; //etc...
}

或者

$stmt = $db->query('SELECT * FROM table');
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
//use $results

4.3#Fetch Modes

注意fetch() 和 fetchAll() 代码中的PDO::FETCH_ASSOC ,它告诉PDO以关联数组的形式返回 键、值;其它比如PDO::FETCH_NUM模式,则以索引数组返回,默认模式是PDO::FETCH_BOTH 则返回前面两者的集合,既有索引数组,又有关联数组。PDO也可以获取数据返回对象PDO::FETCH_OBJ , PDO::FETCH_CLASS , PDO::FETCH_BOUND,BINDCOLUMN 方法等更多内容,请阅读PDOStatement Fetch documentation

4.4. #获取数据行数(Getting Row Count)

代替mysql_num_rows,你可以使用PDOStatement 对你的rowCount() 方法。

$stmt = $db->query(SELECT * FROM table);
$row_count = $stmt->rowCount();
echo $row_conut . ' rows selected';

注意:官方文档称些函数仅适用于返回 UPDATE , INSERT , DELETE 操作的 affected rows , 而 SELECT 操作,仅对于 PDO_MYSQL驱动,此函数同样适用(谨记),在操作其它数据库的时候尤其注意。

4.5. #获取最后操作ID(Getting Last Insert Id)

mysql_*代码:

$result = mysql_query("INSERT INTO table (firstname,lastname) VALUES('John','Doe')") or die ("Insert Failed " . mysql_error());
$insert_id = mysql_insert_id();

PDO代码:

$result = $db->exec("INSERT INTO table(firstname, lastname) VALUES('John', 'Doe')");
$insertID = $db->lastInsertId();
5.执行INSERT , UPDATE , DELETE操作

5.1. mysql_*代码:

$results = mysql_query("UPDATE table SET field='value'") or die(mysql_error());
$affected_rows = mysql_affected_rows($result);
echo $affected_rows . ' were affected';

5.2. PDO代码:

$affected_rows = $db->exec("UPDATE table SET field='value'");
echo $affected_rows . ' were affected';

DELETE , INSERT  操作同样适用。

6.运行带有查询参数的语句(Running Statements With Parameters)

对于不携带任何参数的查询语句,我们可以使用query方法处理SELECT操作,使用exec方法处理INSERT, UPDATE, DELETE操作,而对于携带查询参数的语句,你应该使用绑定参数的方法来安全的处理这些操作。

6.1.mysql_*代码:

$results = mysql_query(sprintf("SELECT * FROM table WHERE id='%s' AND name='%s'",
        mysql_real_escape_string($id), mysql_real_escape_string($name))) or die(mysql_error());
$rows = array();
while($row = mysql_fetch_assoc($results)){
    $rows[] = $row;
}

6.2.PDO代码:

$stmt = $db->prepare("SELECT * FROM table WHERE id=? AND NAME=?");
$stmt->exec(array($id,$name));
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

 

版权声明:
作者:xiaoniba
链接:https://blog.xiaoniba.com/2016/03/03/mysql%e6%95%b0%e6%8d%ae%e5%ba%93pdo%e6%95%99%e7%a8%8b/
来源:小泥吧的博客
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
< <上一篇
下一篇>>