PDO常用方法详解
来源:互联网 发布:蚁群算法 matlab 三维 编辑:程序博客网 时间:2024/06/05 15:09
PDO 是一个“数据库访问抽象层”,作用是统一各种数据库(MySQL、MSSQL、Oracle、DB2、PostgreSQL……)的访问接口,能轻松的在不同的数据库之间完成切换,使得数据库间的移植容易实现。
开启PDO
在pho.ini中查找php_pdo_yourssqlserverhere.extis把注释去掉就行了,很多集成环境默认是开启的。
可以用class_exitsts(“PDO”); 等方法调试是否开启
PDO对象建立
$dsn = 'mysql:host=localhost;dbname=my_db;port=3306'; //数据源:host主机名称、dbname数据库名称、port:数据库端口$username = 'root'; //数据库用户名$password = 'root'; //数据库密码$pdo = new PDO($dsn, $username, $password);
转义用户输入(的特殊字符)
你可曾听说过(mysqli_)real_escape_string,这是用于确保用户输入安全数据。PDO提供了一个方法叫做quote,这个方法可以把输入字符串中带有引号的地方进行特殊字符转义。
$pdo->quote($input);
预处理语句
尽管exec方法和查询在PHP中仍然被大量使用和支持,但是PHP官网上还是要求大家用预处理语句的方式来替代。为什么呢?主要是因为:它更安全。预处理语句不会直接在实际查询中插入参数,这就避免了许多潜在的SQL注入。
然而出于某种原因,PDO实际上并没有真正的使用预处理,它是在模拟预处理方式,在将语句传给SQL服务器之前会把参数数据插入到语句中,这使得某些系统容易受到SQL注入。
如果你的SQL服务器不真正的支持预处理,我们可以很容易的通过如下方式在PDO初始化时传参来修复这个问题:
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
接下来开始我们的第一个预处理语句吧:
$statement = $pdo->prepare('SELECT * FROM test WHERE id=? AND username=?');$statement = $pdo->prepare('SELECT * FROM test WHERE id=:id AND username=:username');
正如你所见,有两种创建参数的方法,命名(id=:id)的与匿名的(id=?)(不可以同时出现在一个语句中)。然后你可以使用bindValue来敲进你的输入:
$statement->bindValue(1, $id);$statement->bindValue(2, $username);$statement->bindValue(':id', $id);$statement->bindValue(':username', $username);
注意使用命名参数的时候你要包含进冒号(:)。PDO还有一个bindParam方法,可以通过引用绑定数值,也就是说它只在语句执行的时候查找相应数值。
bindParam() 和 bindValue() 非常相似。
唯一的区别就是前者使用一个PHP变量绑定参数,而后者使用一个值。
所以使用bindParam是第二个参数只能用变量名,而不能用变量值,而bindValue至可以使用具体值。
$stm = $pdo->prepare("select * from users where user = :user"); $user = "jack"; //正确 $stm->bindParam(":user",$user); //错误 //$stm->bindParam(":user","jack"); //正确 $stm->bindValue(":user",$user); //正确 $stm->bindValue(":user","jack");
另外在存储过程中,bindParam可以绑定为input/output变量,如下面
$stm = $pdo->prepare("call func(:param1)"); $param1 = "abcd"; $stm->bindParam(":param1",$param1); //正确 $stm->execute();
存储过程执行过后的结果可以直接反应到变量上。
对于那些内存中的大数据块参数,处于性能的考虑,应优先使用前者。
为了避免只使用bindValue带来的代码碎片,你可以用数组给execute方法作为参数,像这样:
$statement->execute(array(1=>$id, 2=>$username));$statement->execute(array(':id'=>$id, ':username'=>$username));
绑定值到变量 详情看官方文档http://php.net/manual/zh/pdostatement.bindcolumn.php
绑定结果集中的列到PHP变量是一种使每行包含的数据在应用程序中立即可用的有效方法。下面的例子演示了 PDO 怎样用多种选项和缺省值绑定和检索列。
<?phpfunction readData($dbh) { $sql = 'SELECT name, colour, calories FROM fruit'; try { $stmt = $dbh->prepare($sql); $stmt->execute(); /* 通过列号绑定 */ $stmt->bindColumn(1, $name); $stmt->bindColumn(2, $colour); /* 通过列名绑定 */ $stmt->bindColumn('calories', $cals); while ($row = $stmt->fetch(PDO::FETCH_BOUND)) { $data = $name . "\t" . $colour . "\t" . $cals . "\n"; print $data; } } catch (PDOException $e) { print $e->getMessage(); }}readData($dbh);?>
事务
一个事务就是执行一组查询,但是并不保存他们的影响到数据库中。这样做的好处是如果你执行了4条相互依赖的插入语句,当有一条失败后,你可以回滚使得其他的数据不能够插入到数据库中,确保相互依赖的字段能够正确的插入。你需要确保你使用的数据库引擎支持事务。
开启事务
你可以很简单的使用beginTransaction()方法开启一个事务:
$pdo->beginTransaction();$pdo->inTransaction(); // true!$pdo->query('SELECT * .....');.......$
然后你可以继续执行你的数据库操作语句,在最后提交事务:
$db->commit();
还有类似MySQLi中的rollBack()方法,但是它并不是回滚所有的类型(例如在MySQL中使用DROP TABLE),这个方法并不是真正的可靠,我建议尽量避免依赖此方法。
其他有用的选项
有几个选项你可以考虑用一下。这些可以作为你的对象初始化时候的第四个参数输入。
$options = array($option1 => $value1, $option[..]);$db = new PDO($dsn, $username, $password, $options);
PDO::ATTR_DEFAULT_FETCH_MODE
你可以选择PDO将返回的是什么类型的结果集,如PDO::FETCH_ASSOC,会允许你使用
你还可以将结果放入一个特定的类(模型),可以通过给每一个单独的查询设置一个读取模式,就像这样:
$query = $db->query(‘SELECT * FROM `foods`‘);$foods = $query->fetchAll(PDO::FETCH_CLASS, ‘Food‘);PDO::ATTR_ERRMODE
- 所有读取模式
上面我们已经解释过这一条了,但喜欢TryCatch的人需要用到:PDO::ERRMODE_EXCEPTION。如果不论什么原因你想抛出PHP警告,就使用PDO::ERRMODE_WARNING。
PDO::ATTR_TIMEOUT
当你为载入时间而着急时,你可以使用此属性来为你的查询指定一个超时时间,单位是秒. 注意,如果超过你设置的时间,缺省会抛出E_WARNING异常, 除非 PDO::ATTR_ERRMODE 被改变.
更多属性信息可以在 PHP官网的属性设置 里查看到.
最后的思考
PDO是一个在PHP中访问你的数据库的很棒的方式,可以认为是最好的方式。除非你拒绝使用面向对象的方法或是太习惯 MySQLi 的方法名称,否则没有理由不使用PDO。
更好的是完全切换到只使用预处理语句,这最终将使你的生活更轻松!
PDO常用方法:
- PDO::query()主要用于有记录结果返回的操作(PDOStatement),特别是select操作。
- PDO::exec()主要是针对没有结果集合返回的操作。如insert,update等操作。返回影响行数。
- PDO::lastInsertId()返回上次插入操作最后一条ID,但要注意:如果用insert into tb(col1,col2) values(v1,v2),(v11,v22)..的方式一次插入多条记录,lastinsertid()返回的只是第一条(v1,v2)插入时的ID,而不是最后一条记录插入的记录ID。
- PDOStatement::fetch()是用来获取一条记录。配合while来遍历。
- PDOStatement::fetchAll()是获取所有记录集到一个中。
- PDOStatement::fetchcolumn([int column_indexnum])用于直接访问列,参数column_indexnum是该列在行中的从0开始- 索引值,但是,这个方法一次只能取得同一行的一列,只要执行一次,就跳到下一行。因此,用于直接访问某一列时较好用,但要遍历多列就用不上。
- PDOStatement::rowcount()适用于当用query(“select …”)方法时,获取记录的条数。也可以用于预处理中。$stmt->rowcount();
- PDOStatement::columncount()适用于当用query(“select …”)方法时,获取记录的列数,不适用于预处理。
注解:
1、选fetch还是fetchall?
小记录集时,用fetchall效率高,减少从数据库检索次数,但对于大结果集,用fetchall则给系统带来很大负担。数据库要向WEB前端传输量太大反而效率低。
2、fetch()或fetchall()有几个参数:
mixed pdostatement::fetch([int fetch_style [,int cursor_orientation [,int cursor_offset]]])
array pdostatement::fetchAll(int fetch_style)
fetch_style参数:
■
■
■
■
fetchAll实例
$sql = 'SELECT * FROM test WHERE id=?';$stmt = $pdo->prepare($sql);$stmt->execute(array(1=>$id));foreach($stmt->fetchAll(PDO::FETCH_ASSOC) as $row){ echo $row['username'].$row['password'];}
fetch实例
$sql = 'SELECT * FROM test WHERE id=?';$stmt = $pdo->prepare($sql);$stmt->execute(array(1=>$id));while($row = $stmt->fetch(PDO::FETCH_ASSOC)){ echo $row['username'].$row['password'];}
fetch每执行一次记录都往下移动一次,所以用while循环遍历结果集。
- PDO常用方法详解
- PDO常用方法
- PDO常用方法
- PDO常用方法
- PDO常用方法及其应用
- php使用PDO方法详解
- PDO进行数据库操作的常用方法
- PHP-PDO对象使用常用方法
- pdo对象的常用方法 lastInsertId(),rowCount()
- PHP-PDO对象使用常用方法
- PDO详解
- PDO详解
- PHP PDO prepare()、execute()和bindParam()方法详解
- PHP PDO prepare()、execute()和bindParam()方法详解
- PHP PDO prepare()、execute()和bindParam()方法详解
- PDO 常用类库
- PDO常用类库
- PDO常用库类
- php excel导出 导入问题 csv格式
- ionic局部刷新
- 【C++】关键字const
- Android系统架构 五层结构
- 今年暑假不AC(贪心)
- PDO常用方法详解
- 206. Reverse Linked List(java)
- XMLHttpRequest cannot load的解决方法
- 全排列的C/C++实现
- JS--第八天
- java 泛型
- LeetCode-26-Remove Duplicates from Sorted Array(消除已排序数组中的重复元素)
- Nginx之location,rewrite,反向代理及负载均衡
- 数据结构——字典(JavaScript)