<?php //dsn 数据资源名称,里面内容没有先后顺序,但是数据库类型必须是小写mysql:的 //如果是本地host 可以省略,端口也可以省略,数据库名字和字符集也可以省略 $dsn="mysql:host=localhost;dbname=my_db;port=3306;charset=utf8"; //PDO代表php与数据库连接 $pdo = new PDO($dsn,"root","root"); /** * PDO 操作增删改操作 * @return 成功返回受影响的行数,失败返回false * 如果返回0也表示成功,只是没有受影响的行数 */ //增,受影响1条 // echo $pdo->exec("insert into my_user values (null,'王小虎',123456,'超级管理员')"); //删除,受影响3条 // echo $pdo->exec("delete from my_user where u_name='王小虎'"); //修改,受影响6条 // echo $pdo->exec("update my_user set u_name='张小龙' where u_id >=15 and u_id<=20"); //例子 ,错误信息及错误代码 $info=$pdo->exec("delete from my_user where u_id=10"); if($info===false){ echo "错误代码".$pdo->errorCode()."<br>"; echo "错误信息". $pdo->errorInfo()[2]."<br>"; }elseif($info===0){ echo "没有要删除的数据"; }else{ echo "数据删除成功"; echo "删除了".$info; } ?>
PDO事务
多个SQL语句同时执行?如果有错就回滚,没有错误就同时提交
<?php if(!empty($_GET)){ $out=$_GET['bank_out']; $in=$_GET['bank_in']; $mony=$_GET['mony']; $dsn="mysql:host=localhost;dbname=my_db;port=3306;charset=utf8"; $pdo = new PDO($dsn,"root","root"); $pdo->beginTransaction(); $bank_out=$pdo->exec("update my_bank set mony=mony-$mony where carNo=$out"); $bank_in=$pdo->exec("update my_bank set mony=mony+$mony where carNo=$in"); if($bank_out && $bank_in){ $pdo->commit(); echo "转账成功,转账金额:".$mony; }else{ $pdo->rollBack(); echo "转账失败"; echo "错误信息".$pdo->errorInfo()[2]; } } ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <form action="" method="get"> 转出账号:<input type="text" name="bank_out" id=""><br> 转入账号:<input type="text" name="bank_in" id=""><br> 金额:<input type="text" name="mony" id=""> <br> <input type="submit" value="转账"> </form> </body> </html>
PDOStatement对象
<?php $dsn="mysql:dbname=my_db;port=3306;carset=utf8"; $pdo = new PDO($dsn,"root","root"); //查询操作会返回一个PDOStatement对象结果集 $stmt=$pdo->query("select * from my_user"); //var_dump($stmt); //object(PDOStatement)#2 (1) { ["queryString"]=> string(21) "select * from my_user" } /** * 作用:获取二维数组结果集 * @param static int 默认不写为PDO::FETCH_BOTH 索引数组和关联数组 * PDO::FETCH_ASSOC 关联数组 * PDO::FETCH_NUM 索引数组 * @return 默认返回索引数组和关联数组 */ // $arr=$stmt->fetchAll(PDO::FETCH_NUM); // print_r($arr); /** * 作用:返回一维数组 * 可以使用循环来输出,每次只取出一条记录,并且指针下移 next(); */ // $arr=$stmt->fetch(); // print_r($arr); /** * 作用:获取记录数 * @return int 记录总数 */ echo $stmt->rowCount(); //25 //foreach循环对象,只能是输出对象中的成员属性,但是我们循环的时候,输出了数组数据,说明PDOStatement类实现了迭代器 // foreach( $stmt as $row){ // print_r($row); // }
PDO prepare 预处理,准备要执行的SQL语句并返回一个 PDOStatement 对象,多次执行一种sql语句,多次编译,使用prepare效率更高
1.PDOStatement->bindparam 与bindcvalue
<?php $dsn="mysql:host=localhost;dbname=my_db;port=3306;charset=utf8"; $pdo = new PDO($dsn,"root","root"); //预处理语句,参数占位符使用? 代替,返回一个PDOStatement对象 $stmt=$pdo->prepare("insert into my_bank values (?,?,?)"); //定义数组 $arr=[ [3,10003,500], [4,10004,800] ]; // //执行预处理 // foreach ($arr as $value) { // //方法一:绑定参数 // $stmt->bindParam(1,$value[0]); //占位符从1开始 // $stmt->bindParam(2,$value[1]); // $stmt->bindParam(3,$value[2]); // $stmt->execute(); //执行预处理 执行成功 // } // foreach ($arr as $value) { // //方法二 绑定值 // // $stmt->bindValue(1,$value[0]); //占位符从1开始 // // $stmt->bindValue(2,$value[1]); // // $stmt->bindValue(3,$value[2]); // // $stmt->execute(); //成功 bindparam和bindValue 效果一样的?但是 // // pindParam的参数必须是变量,而bindValue可以是变量也可以是值 // $stmt->bindValue(1,3); // $stmt->bindValue(2,10003); // $stmt->bindValue(3,4000); // $stmt->execute(); // //pindParam的参数必须是变量,而bindValue可以是变量也可以是值 // } foreach($arr as $value){ //方法三:如果预处理参数和数组的值是一致的可以直接写 $stmt->execute($value); }
值的占位符 使用:p1冒号占位
<?php $dsn="mysql:host=localhost;dbname=my_db;port=3306;charset=utf8"; $pdo = new PDO($dsn,"root","root"); //预处理语句,参数占位符使用? 代替,返回一个PDOStatement对象 $stmt=$pdo->prepare("insert into my_bank values (:p1,:p2,:p3)"); //定义数组 $arr=[ ['p1'=>3,'p2'=>10003,'p3'=>500], ['p1'=>4,'p2'=>10004,'p3'=>800] ]; foreach ($arr as $value) { $stmt->bindParam('p1',$value['p1']); $stmt->bindParam('p2',$value['p2']); $stmt->bindParam('p3',$value['p3']); $stmt->execute(); //也是有三种方法 }
PDOException 异常类
此类是好人封装好的,可以自动抛出异常,但是只有实例化的时候才行
<?php $dsn="mysql:host=localhost;dbname=my_db"; //默认情况下,PDOException 只能在实例化PDO的时候,throw异常; try{ $pdo =new PDO($dsn,"root","root"); //只有这句话出错才能抛出异常 $pdo->exec("insert intos my_bank values (null,10005,600)"); //这句话写错,是不会抛出异常的 }catch(PDOException $e){ echo $e->getMessage(); }
设置PDOException 抛出异常的属性,其他错误也可抛出异常
PDO->setAttribute(); 默认是不报错误 参数 1 为属性 PDO::ATTR_ERRMODE ,参数 2 它有三种模式 1. PDO::ERRMODE_EXCEPTION(异常模式) 2.PDO::ERRMODE_WARNING (警告模式) 3.PDO:ERRMODE_SILENT (警告模式);
<?php try{ $dsn="mysql:host=localhost;dbname=my_db"; $pdo =new PDO($dsn,"root","root"); //设置PDOException 异常属性,有了这个属性,其他的错误就可以throw了 $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); echo $pdo->exec("insert into my_bankssss values (null,10005,600)"); //报错了 my_bankssss 没有这个表 }catch(PDOException $e){ echo "代码执行错误".$e->getFile().'<br>'; echo "错误代码".$e->getCode().'<br>'; echo $e->getMessage(); }