Blogger Information
Blog 35
fans 0
comment 0
visits 16931
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
0817-数据库常用的CURD操作
三九三伏
Original
408 people have browsed it

实例演示常用 的CURD操作,特别是各种常用组合,如fetch+while…

一、预处理参数绑定

PDO预处理
预处理的本质是sql语句的动态绑定
动态绑定就是执行时才绑定真实数据
SELECT * FROM `表名` WHERE `id` > ?
静态绑定,数据直接写到SQL语句中
SELECT * FROM `表名` WHERE `id` > 1

1. 动态绑定方式

1.1 匿名参数+索引数组

  1. namespace pdo_edu;
  2. use PDO;
  3. $db = new PDO('mysql:dbname=phpedu', 'phpedu', 'phpedu');
  4. //匿名参数:?
  5. $sql = 'INSERT `staff` SET `name` = ?, `gender` = ?, `email` = ?;';
  6. $stmt = $db->prepare($sql);
  7. //SQL语句中占位符“?”,用索引数组绑定真实数据
  8. $data = ['admin', 0, 'admin@php.cn'];
  9. $stmt->execute($data);
  10. echo '<hr>';
  11. //打印SQL预处理命令
  12. $stmt->debugDumpParams();
  13. echo '<br>'.$stmt->errorCode().'<br>';
  14. print_r($stmt->errorInfo());
  15. echo '<br>id = '.$db->lastInsertId().'<br>';

1.2 命名参数+关联数组

  1. namespace pdo_edu;
  2. use PDO;
  3. $db = new PDO('mysql:dbname=phpedu', 'phpedu', 'phpedu');
  4. //命名参数:“:xxxx”不用和前面一一对应
  5. $sql = 'INSERT `staff` SET `name` = :xname, `gender` = :pgender, `email` = :demail;';
  6. $stmt = $db->prepare($sql);
  7. //SQL语句中占位符“:xxxx”,用关联数组绑定真实数据
  8. // $data = [':xname' => 'admin', ':pgender' => 0, ':demail' => 'admin@php.cn'];
  9. //去掉冒号也是可以的
  10. $data = ['xname' => 'admin1', 'pgender' => 1, 'demail' => 'admin1@php.cn'];
  11. $stmt->execute($data);
  12. echo '<hr>';
  13. //打印SQL预处理命令
  14. $stmt->debugDumpParams();
  15. echo '<br>'.$stmt->errorCode().'<br>';
  16. print_r($stmt->errorInfo());
  17. echo '<br>id = '.$db->lastInsertId().'<br>';

“匿名参数+索引数组”和“命名参数+关联数组”用哪个好?
用哪个都可以,看个人喜好。

1.3 参数绑定:值绑定 bindValue()

  1. /**
  2. * 为什么要单独设置参数,而不是在execute()时传参?
  3. * execute()默认参数都是字符类型
  4. * 通常数字型字符写入数据表时,会转换成正确类型,不会有问题。
  5. * 但在分页操作时,会导致错误。
  6. * 在参数绑定时,强制类型限制,就很有必要。
  7. */
  8. namespace pdo_edu;
  9. use PDO;
  10. $db = new PDO('mysql:dbname=phpedu', 'phpedu', 'phpedu');
  11. //匿名参数:?
  12. $sql = 'INSERT `staff` SET `name` = ?, `gender` = ?, `email` = ?;';
  13. $stmt = $db->prepare($sql);
  14. //bindValue()值绑定,静态绑定,所有参数有确定值。
  15. // bindValue(key, value, type),匿名占位符,索引从1开始。
  16. // $stmt->bindValue(1, 'admin3', PDO::PARAM_STR);
  17. // $stmt->bindValue(2, 0, PDO::PARAM_INT);
  18. // $stmt->bindValue(3, 'admin3@php.cn', PDO::PARAM_STR);
  19. // 上面是写死的,更灵活应该用数组传参。
  20. list($name, $gender, $email) = ['admin4', 1, 'admin4@php.cn'];
  21. $stmt->bindValue(1, $name, PDO::PARAM_STR);
  22. $stmt->bindValue(2, $gender, PDO::PARAM_INT);
  23. $stmt->bindValue(3, $email, PDO::PARAM_STR);
  24. list($name, $gender, $email) = ['admin5', 0, 'admin5@php.cn'];
  25. $stmt->bindValue(1, $name, PDO::PARAM_STR);
  26. $stmt->bindValue(2, $gender, PDO::PARAM_INT);
  27. $stmt->bindValue(3, $email, PDO::PARAM_STR);
  28. $stmt->execute();
  29. echo '<hr>';
  30. //打印SQL预处理命令
  31. $stmt->debugDumpParams();
  32. echo '<br>'.$stmt->errorCode().'<br>';
  33. print_r($stmt->errorInfo());
  34. echo '<br>id = '.$db->lastInsertId().'<br>';

每插入一条就得绑定一次,也不方便灵活。

1.4 参数绑定:引用绑定bindParam()

  1. namespace pdo_edu;
  2. use PDO;
  3. $db = new PDO('mysql:dbname=phpedu', 'phpedu', 'phpedu');
  4. //heredoc
  5. $sql = <<<SQL
  6. INSERT `staff`
  7. SET `name` = ?, `gender` = ?, `email` = ?;
  8. SQL;
  9. $stmt = $db->prepare($sql);
  10. // 引用绑定
  11. $stmt->bindParam(1, $name, PDO::PARAM_STR);
  12. $stmt->bindParam(2, $gender, PDO::PARAM_INT);
  13. $stmt->bindParam(3, $email, PDO::PARAM_STR);
  14. // list($name, $gender, $email) = ['admin6', 1, 'admin6@php.cn'];
  15. // $stmt->execute();
  16. // echo '<hr>';
  17. // 在增加两条条
  18. // list($name, $gender, $email) = ['admin7', 0, 'admin7@php.cn'];
  19. // $stmt->execute();
  20. // echo '<hr>';
  21. // list($name, $gender, $email) = ['admin8', 1, 'admin8@php.cn'];
  22. // $stmt->execute();
  23. // echo '<hr>';
  24. // $stmt->execute();
  25. // echo '<hr>';
  26. // //打印SQL预处理命令
  27. // $stmt->debugDumpParams();
  28. // echo '<br>'.$stmt->errorCode().'<br>';
  29. // print_r($stmt->errorInfo());
  30. // echo '<br>id = '.$db->lastInsertId().'<br>';
  31. // 用循环和二维数组添加多条
  32. $data = [
  33. ['admin9', 0, 'admin9@php.cn'],
  34. ['admin10', 1, 'admin10@php.cn'],
  35. ['admin11', 0, 'admin11@php.cn'],
  36. ];
  37. foreach($data as list($name, $gender, $email)){
  38. $stmt->execute();
  39. echo '<hr>';
  40. //打印SQL预处理命令
  41. $stmt->debugDumpParams();
  42. echo '<br>'.$stmt->errorCode().'<br>';
  43. print_r($stmt->errorInfo());
  44. echo '<br>id = '.$db->lastInsertId().'<br>';
  45. }

1.5 错误处理

  1. namespace pdo_edu;
  2. use PDO;
  3. $db = new PDO('mysql:dbname=phpedu', 'phpedu', 'phpedu');
  4. //heredoc
  5. $sql = <<<SQL
  6. INSERT `staff` SET `name` = ?, `gender` = ?, `email` = ?;
  7. SQL;
  8. $stmt = $db->prepare($sql);
  9. //注释“引用绑定”,引起错误
  10. // $stmt->bindParam(1, $name, PDO::PARAM_STR);
  11. // $stmt->bindParam(2, $gender, PDO::PARAM_INT);
  12. // $stmt->bindParam(3, $email, PDO::PARAM_STR);
  13. $data = [
  14. ['admin12', 0, 'admin12@php.cn'],
  15. //['admin13', 0, 'admin13@php.cn'],
  16. ];
  17. foreach($data as list($name, $gender, $email)){
  18. if($stmt->execute()){
  19. if($stmt->rowCount() > 0){
  20. echo 'sql执行成功,id ='.$db->lastInsertId().'<br>';
  21. echo '<hr>';
  22. }else{
  23. echo '执行失败';
  24. print_r($stmt->errorInfo());
  25. }
  26. }else{
  27. echo 'sql执行失败';
  28. print_r($stmt->errorInfo());
  29. }
  30. }

Tips

  1. else:应用于开发调试阶段,生产环境中应将错误信息集中写到日志文件中。
  2. sql执行失败很常见,通常是语法错误,例如字段名写错等。
  3. 新增失败通常是权限问题,如没有插入权限或者当前表被锁定只读等,磁盘满也有可能。

1.6 更新

  1. namespace pdo_edu;
  2. use PDO;
  3. $db = new PDO('mysql:dbname=phpedu', 'phpedu', 'phpedu');
  4. //heredoc
  5. $sql = <<<SQL
  6. UPDATE `staff` SET `name` = ?, `gender` = ?, `email` = ?
  7. WHERE `id`= ?;
  8. SQL;
  9. // !!!!最高提示:禁止无条件更新,生产环境必须杜绝。
  10. // stripos()忽略大小写
  11. if (false === stripos($sql, 'where'))
  12. {
  13. exit('禁止无条件更新!');
  14. }
  15. $stmt = $db->prepare($sql);
  16. $stmt->bindParam(1, $name, PDO::PARAM_STR);
  17. $stmt->bindParam(2, $gender, PDO::PARAM_INT);
  18. $stmt->bindParam(3, $email, PDO::PARAM_STR);
  19. $stmt->bindParam(4, $id, PDO::PARAM_INT);
  20. $data = [
  21. ['admin8', 0, 'admin8@php.cn', 8],
  22. ];
  23. foreach($data as list($name, $gender, $email, $id)){
  24. if($stmt->execute()){
  25. if($stmt->rowCount() > 0){
  26. echo '成功更新了'.$stmt->rowCount().'条记录<br>';
  27. echo '<hr>';
  28. }else{
  29. echo '更新重复:没有记录被更新!<br>';
  30. print_r($stmt->errorInfo());
  31. $stmt->debugDumpParams();
  32. }
  33. }else{
  34. echo 'sql执行失败';
  35. print_r($stmt->errorInfo());
  36. }
  37. }

成功时,

重复的更新将被拦截,

  1. ....
  2. //不写条件WHERE测试
  3. $sql = <<<SQL
  4. UPDATE `staff` SET `name` = ?, `gender` = ?, `email` = ?
  5. ;
  6. SQL;
  7. // 最高提示:禁止无条件更新,生产环境必须杜绝。
  8. // stripos()忽略大小写
  9. if (false === stripos($sql, 'where'))
  10. {
  11. exit('禁止无条件更新!');
  12. }
  13. ....

1.7 删除

  1. namespace pdo_edu;
  2. use PDO;
  3. $db = new PDO('mysql:dbname=phpedu', 'phpedu', 'phpedu');
  4. //heredoc
  5. $sql = <<<SQL
  6. DELETE FROM `staff`
  7. WHERE `id`= ?;
  8. SQL;
  9. // 最高提示:禁止无条件删除,生产环境必须杜绝。
  10. // stripos()忽略大小写
  11. if (false === stripos($sql, 'where'))
  12. {
  13. exit('禁止无条件删除!');
  14. }
  15. $stmt = $db->prepare($sql);
  16. $stmt->bindParam(1, $id, PDO::PARAM_INT);
  17. $data = [
  18. [11],
  19. [10],
  20. ];
  21. foreach($data as list($id)){
  22. echo $id.'<br>';
  23. if($stmt->execute()){
  24. if($stmt->rowCount() > 0){
  25. echo '成功删除了'.$stmt->rowCount().'条记录<br>';
  26. echo '<hr>';
  27. }else{
  28. echo '重复删除:没有记录被删除!<br>';
  29. print_r($stmt->errorInfo());
  30. // $stmt->debugDumpParams();
  31. }
  32. }else{
  33. echo 'sql执行失败';
  34. print_r($stmt->errorInfo());
  35. }
  36. }

1.8 查询

1.8.1 fetch + while

  1. // 查询 fetch + while
  2. namespace pdo_edu;
  3. use PDO;
  4. $db = new PDO('mysql:dbname=phpedu', 'phpedu', 'phpedu');
  5. //heredoc
  6. $sql = <<<SQL
  7. SELECT `id`, `name`, `email` FROM `staff`
  8. LIMIT ?;
  9. SQL;
  10. $stmt = $db->prepare($sql);
  11. // $num = 5;
  12. // $stmt->bindParam(1, $num, PDO::PARAM_INT);
  13. $stmt->bindValue(1, 5, PDO::PARAM_INT);
  14. if($stmt->execute()){
  15. // fetch()逐条获取,指针自动后移指向下一条,失败返回false,成功返回记录。
  16. // $staff = $stmt->fetch(PDO::FETCH_ASSOC);
  17. // if($staff)
  18. // {
  19. // printf('<pre>%s</pre><br>',print_r($staff, true));
  20. // }else
  21. // {
  22. // echo '没有查询到数据!<br>';
  23. // }
  24. while($staff = $stmt->fetch(PDO::FETCH_ASSOC))
  25. {
  26. printf('<pre>%s</pre><br>',print_r($staff, true));
  27. }
  28. }else{
  29. echo 'sql执行失败';
  30. print_r($stmt->errorInfo());
  31. $stmt->debugDumpParams();
  32. }

1.8.2 fetchall

  1. // 查询 fetchall
  2. namespace pdo_edu;
  3. use PDO;
  4. $db = new PDO('mysql:dbname=phpedu', 'phpedu', 'phpedu');
  5. //heredoc
  6. $sql = <<<SQL
  7. SELECT `id`, `name`, `email` FROM `staff`
  8. LIMIT ?;
  9. SQL;
  10. $stmt = $db->prepare($sql);
  11. // $num = 5;
  12. // $stmt->bindParam(1, $num, PDO::PARAM_INT);
  13. $stmt->bindValue(1, 4, PDO::PARAM_INT);
  14. if($stmt->execute()){
  15. // fetchall()获取全部记录。
  16. while($staffs = $stmt->fetchAll(PDO::FETCH_ASSOC))
  17. {
  18. foreach($staffs as
  19. $staff){
  20. printf('<pre>%s</pre><br>',print_r($staff, true));
  21. }
  22. }
  23. }else{
  24. echo 'sql执行失败';
  25. print_r($stmt->errorInfo());
  26. $stmt->debugDumpParams();
  27. }

Correcting teacher:PHPzPHPz

Correction status:qualified

Teacher's comments:
Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments
Author's latest blog post