ASCII码 ASCII码

PHP中的原生分页,文件上传拦截与链式数据库查询构造器

发布于:2022-02-24 08:49:30  栏目:技术文档

原生分页实现

  • 实现原理,设置每页显示的条数,获取数据库的条数,计算出分页数量,获取数据库中相关数据,并在前端显示,代码如下
  1. //后端获取数据库代码
  2. $pdo = new PDO('mysql:host=localhost;charset=utf8;port=3306;dbname=phpcn', 'root', '', [PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC]);
  3. // 每页的数据量
  4. $pageSize = 8;
  5. // 当前访问的是第几页
  6. $page = $_GET['page'] ?? 1;
  7. // 偏移量offset
  8. $offset = ($page - 1) * $pageSize;
  9. $sql = "SELECT `cou_id`,`title`,`pic`,`info`,`add_time`FROM `mj_course_lists` ORDER BY `cou_id` DESC LIMIT {$offset},{$pageSize}";
  10. $lists = $pdo->query($sql)->fetchAll();
  11. // 获取总页数
  12. $sql1 = "SELECT COUNT(`cou_id`) AS `sum` FROM `mj_course_lists`";
  13. $total = $pdo->query($sql1)->fetch()['sum'];
  14. // var_dump($total);
  15. //总页数
  16. $pages = ceil($total / $pageSize);

前端代码如下

  1. <? require 'pageData.php' ?>
  2. <!DOCTYPE html>
  3. <html lang="en">
  4. <head>
  5. <meta charset="UTF-8">
  6. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  7. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  8. <link rel="stylesheet" href="static/css/style.css">
  9. <title>Document</title>
  10. </head>
  11. <body>
  12. <table>
  13. <caption>课程信息表</caption>
  14. <thead>
  15. <tr>
  16. <td>编号</td>
  17. <td>名称</td>
  18. <td>封面</td>
  19. <td>课程简介</td>
  20. <td>创建时间</td>
  21. <td>操作</td>
  22. </tr>
  23. </thead>
  24. <tbody>
  25. <?php foreach ($lists as $list) : ?>
  26. <tr>
  27. <td><?= $list['cou_id'] ?></td>
  28. <td><?= $list['title'] ?></td>
  29. <td><img style="width:100px" src=" <?= $list['pic'] ?>" alt="课程封面"></td>
  30. <td><?= $list['info'] ?></td>
  31. <td><?= date("Y-m-d H:m:s", $list['add_time']) ?></td>
  32. <td><button>删除</button><button>编辑</button></td>
  33. </tr>
  34. <?php endforeach; ?>
  35. </tbody>
  36. </table>
  37. <!-- 生成分页条 -->
  38. <p>
  39. <? for ($i = 1; $i <= $pages; $i++) : ?>
  40. <? $jump = sprintf('?page=%d', $i) ?>
  41. <? $active = ($i == $page) ? 'active' : '' ?>
  42. <a class="<?= $active ?>" href="<?= $jump ?>"><?= $i ?></a>
  43. <!-- 生成高亮分页条 -->
  44. <? endfor ?>
  45. </p>
  46. </body>
  47. </html>

文件上传后端拦截

  • 1.文件错误拦截
  • 2.文件类型拦截
  • 3.文件来源拦截后端拦截代码如下
  1. <?php
  2. // 获取文件信息$_FILES
  3. // var_dump($_FILES);
  4. $originalFilename = $_FILES['avatar']['name'];
  5. $type = $_FILES['avatar']['type'];
  6. $tmp_name = $_FILES['avatar']['tmp_name'];
  7. $error = $_FILES['avatar']['error'];
  8. $size = $_FILES['avatar']['size'];
  9. switch ($error):
  10. case 0:
  11. echo '<p style="color:green">文件上传成功</p> ';
  12. break;
  13. case 1:
  14. echo '<p style="color:red">文件超过`php.ini`中`upload_max_filesize`值</p>';
  15. break;
  16. case 2:
  17. echo '<p style="color:red">文件大小超过表单中`MAX_FILE_SIZE`指定的值</p>';
  18. break;
  19. case 3:
  20. echo '<p style="color:red">文件只有部分被上传</p>';
  21. break;
  22. case 4:
  23. echo '<p style="color:red">没有文件被上传</p>';
  24. break;
  25. case 6:
  26. echo '<p style="color:red">找不到临时文件夹</p>';
  27. break;
  28. case 6:
  29. echo '<p style="color:red">文件写入失败</p>';
  30. break;
  31. default:
  32. echo '<p style="color:red">系统错误</p>';
  33. break;
  34. endswitch;
  35. // 检查文件格式mine
  36. $exts = ['png', 'jpg', 'jpeg', 'wbmp', 'gif'];
  37. if (!in_array($ext, $exts)) {
  38. echo '非法的文件类型';
  39. }
  40. // 检查大小
  41. // `is_uploaded_file()` | 用来检测文件是否是通过http post方法上传的,而不是系统上的一个文件。作用是防止潜在攻击者通过问题脚本访问并非用于交互的文件
  42. if ($error == 0) {
  43. //移动暂存区的图片到服务器指定的文件目录
  44. $des = 'storage/';
  45. if (!file_exists($des)) {
  46. mkdir($des, 0777, true);
  47. }
  48. // 为了确保同一秒钟两个用户上传的图片名称相同情况下,文件都能上传成功
  49. $arr = explode('.', $originalFilename);
  50. $ext = end($arr); //后缀
  51. $prefix = array_shift($arr);
  52. $newName = date('YmdHms', time()) . md5($prefix) . time() . '.' . $ext;
  53. move_uploaded_file($tmp_name, $des . $newName);
  54. }

链式数据库查询构造器

  • 1.通过事件委托实现
  • 2.事件委托 请求委托 访问类中不存在的成远方法,会被魔术方法拦截,将请求重定向给或者委托给别的对象成员方法类处理。
  • 3.委托比继承更加灵活 父类与子类的关系是固定的,只能单继承,但是请求可以委托给多个对象下列代码实现了,数据库的链式调用
  1. <?php
  2. // 被委托的类 数据库查询构造器
  3. class Query
  4. {
  5. //创建pdo对象的唯一实例
  6. private static $db;
  7. protected $table;
  8. protected $field;
  9. protected $limit;
  10. // private私有的 阻止此类在外部进行实例化
  11. private function __construct()
  12. {
  13. }
  14. static function connect($dsn, $user, $pwd)
  15. {
  16. if (is_null(static::$db)) {
  17. static::$db = new pdo($dsn, $user, $pwd);
  18. }
  19. // return static::$db;
  20. // 返回query实例
  21. return new static;
  22. }
  23. public function table($table)
  24. {
  25. $this->table = $table;
  26. echo `table`;
  27. return $this; //返回本对象 为了实现链式调用
  28. }
  29. public function where($where)
  30. {
  31. }
  32. public function field($field)
  33. {
  34. $this->field = $field;
  35. return $this;
  36. }
  37. public function limit($limit)
  38. {
  39. $this->limit = $limit;
  40. return $this;
  41. }
  42. public function getSql()
  43. {
  44. return sprintf('SELECT %s FROM %s LIMIT %d ', $this->field, $this->table, $this->limit);
  45. }
  46. public function select()
  47. {
  48. return static::$db->query($this->getSql())->fetchAll(PDO::FETCH_ASSOC);
  49. }
  50. }
  51. // 委托方
  52. class Db
  53. {
  54. //魔术方法 $name 表示被拦截的 函数名 $arguments 被拦截的参数
  55. static function __callStatic($name, $arguments)
  56. {
  57. $dsn = 'mysql:host=localhost;dbname=phpcn;charset=utf8;port=3306';
  58. $user = 'root';
  59. $pwd = '';
  60. // 获取到被委托的类Query实例
  61. $q = Query::connect($dsn, $user, $pwd);
  62. var_dump($q);
  63. var_dump($name);
  64. var_dump($arguments);
  65. return call_user_func([$q, $name], ...$arguments);
  66. }
  67. }
  68. // 客户端代码
  69. $res = Db::table('mj_course_cat')->field('cat_id,name')->limit(20)->select();
  70. var_dump($res);
相关推荐
阅读 +