ASCII码 ASCII码

php原生分页、查询构造器、文件上传后端注意事项

发布于:2022-02-26 10:13:19  栏目:技术文档

<!-- 作业内容:1请建立数据表并填充多条数据,完成原生分页。2.文件上传后端要做哪些拦截?3.事件委托实战:完成链式数据库查询构造器。 -->

PHP 原生分页

1、php 代码

  1. <?php
  2. // 连接数据库
  3. require 'connect.php';
  4. // 1. 当前的页数/页码
  5. $page = $_GET['p'] ?? 1;
  6. // 2. 每页显示的记录数量
  7. $num = 8;
  8. // 3. 总页数
  9. $sql = "SELECT CEIL(COUNT(`pid`)/{$num}) AS `total` FROM `workplan0921`";
  10. $pages = $pdo->query($sql)->fetch()['total'];
  11. // 4. 偏移量
  12. $offset = $num * ($page - 1);
  13. // 5. 分页数据
  14. $sql = "SELECT * FROM `workplan0921` LIMIT {$num} OFFSET {$offset}";
  15. $plans = $pdo->query($sql)->fetchAll();
  16. // print_r($plans);
  17. ?>
  18. <!doctype html>
  19. <html lang="en">
  20. <head>
  21. <meta charset="UTF-8">
  22. <title>分页显示工作计划</title>
  23. <style>
  24. * {
  25. margin: 0;
  26. padding: 0;
  27. box-sizing: border-box;
  28. color: #555;
  29. }
  30. body {
  31. display: flex;
  32. flex-direction: column;
  33. align-items: center;
  34. }
  35. /*表格样式*/
  36. table {
  37. width: 80%;
  38. border: 1px solid;
  39. border-collapse: collapse;
  40. text-align: center;
  41. }
  42. table caption {
  43. font-size: 1.2rem;
  44. margin: 10px;
  45. }
  46. table td,
  47. table th {
  48. border: 1px solid;
  49. padding: 5px;
  50. }
  51. table tr:hover {
  52. background-color: #eee;
  53. }
  54. table thead tr:only-of-type {
  55. background-color: lightblue;
  56. }
  57. table button {
  58. width: 56px;
  59. height: 26px;
  60. }
  61. table button:last-of-type {
  62. color: red;
  63. }
  64. table button {
  65. /* 光标呈现为指示链接的指针(一只手) */
  66. cursor: pointer;
  67. margin: 0 3px;
  68. }
  69. table button:first-of-type:hover {
  70. background-color: red;
  71. }
  72. table button:last-of-type:hover {
  73. background-color: yellow;
  74. }
  75. /*分页条样式*/
  76. body > p {
  77. display: flex;
  78. }
  79. p > a {
  80. text-decoration: none;
  81. color: #555;
  82. border: 1px solid;
  83. padding: 5px 10px;
  84. margin: 10px 2px;
  85. }
  86. .active {
  87. background-color: red;
  88. color: white;
  89. border: 1px solid red;
  90. }
  91. .show1, .show2 {
  92. display: none;
  93. }
  94. </style>
  95. </head>
  96. <body>
  97. <table>
  98. <caption>重点工作计划进度明细</caption>
  99. <thead>
  100. <tr>
  101. <th>STT</th>
  102. <th>项目</th>
  103. <th>计划</th>
  104. <th>主责人</th>
  105. <th>完成标准</th>
  106. <th>开始时间</th>
  107. <th>结束时间</th>
  108. <th>完成时间</th>
  109. <th>备注</th>
  110. </tr>
  111. </thead>
  112. <tbody>
  113. <?php foreach ($plans as $plan) : ?>
  114. <tr>
  115. <td><?php echo $plan['stt'];?></td>
  116. <td><?php echo $plan['project'];?></td>
  117. <td><?php echo $plan['plan'];?></td>
  118. <td><?php echo $plan['nguoiphtrach'];?></td>
  119. <td><?php echo date('Y-m-d', $plan['starttime']) ?></td>
  120. <td><?php echo date('Y-m-d', $plan['endtime']) ?></td>
  121. <td><?php echo date('Y-m-d', $plan['timehoanthanh']) ?></td>
  122. <td><?php echo $plan['ghichu'];?></td>
  123. </tr>
  124. <?php endforeach; ?>
  125. </tbody>
  126. </table>
  127. <!--分页-->
  128. <p>
  129. <!--设置省略-->
  130. <?php
  131. // 1. 分页条显示7个页码
  132. $showPages = 7;
  133. // 2. 分页条的起始页码
  134. $startPage = 1;
  135. // 3. 分页条的终止页码
  136. $endPage = $pages; // 当前总页数:
  137. // 4. 分页条的偏移量: (当前分页条显示的页码数 - 1) / 2
  138. $offsetPage = ($showPages -1) / 2; // 3
  139. // 只有当前分页条数量 < 总页数, 才有必要显示出省略标记
  140. if ($showPages < $pages) {
  141. // 如果当前页 > 偏移量 + 1 , 应该显示...
  142. if ($page > $offsetPage + 1) {
  143. $startOmit = '...';
  144. }
  145. // 将当前分页条页码重置
  146. if ($page > $offsetPage) {
  147. $startPage = $page - $offsetPage;
  148. $endPage = $page + $offsetPage;
  149. if ($endPage > $pages) {$endPage = $pages;}
  150. } else {
  151. $startPage = 1;
  152. $endPage = $showPages;
  153. }
  154. // 如果当前页 + 偏移量 > 总页数
  155. if ($page + $offsetPage > $pages) {
  156. // 原理, 就是向当前页前面进行借位
  157. // 此时, 新的起点 = 当前位置 - (当前页 + 偏移量 - 原始位置)
  158. $startPage = $startPage - ($page + $offsetPage - $endPage);
  159. }
  160. if ($showPages < $pages && $page + $offsetPage < $pages) $endOmit = '...';
  161. }
  162. ?>
  163. <?php
  164. // 设置当在第一页和最后一页时不显示首页、上一页 或 尾页 下一页
  165. $show1 = ($page == 1) ? 'show1' :null;
  166. $show2 = ($page == $pages) ? 'show2' :null;
  167. ?>
  168. <!--首页-->
  169. <a href="<?php echo $_SERVER['PHP_SELF'] . '?p=1' ?>" class="<?php echo $show1; ?>">首页</a>
  170. <!--上一页-->
  171. <?php
  172. $prev = $page - 1;
  173. // 如果已经第1页,则定在第1页
  174. if ($page == 1) $prev = 1;
  175. ?>
  176. <a href="<?php echo $_SERVER['PHP_SELF'] . '?p =' .$prev ?>" class="<?php echo $show1; ?>">上一页</a>
  177. <!--省略-->
  178. <?php if (isset($startOmit)) : ?> <a href="#"><?php echo $startOmit ?></a> <?php endif ?>
  179. <?php for ($i = $startPage; $i <= $endPage; $i++) : ?>
  180. <?php
  181. $jump = sprintf('%s?p=%s', $_SERVER['PHP_SELF'], $i);
  182. $active = ($i == $page) ? 'active' :null;
  183. ?>
  184. <a href="<?php echo $jump ?>" class="<?php echo $active ?>"><?php echo $i ?></a>
  185. <?php endfor; ?>
  186. <!--省略-->
  187. <?php if (isset($endOmit)) : ?> <a href="#"><?php echo $endOmit ?></a> <?php endif ?>
  188. <!--下一页-->
  189. <?php
  190. $next = $page + 1;
  191. // 如果已经最后一页,则定在最后一页
  192. if ($page == $pages) $next = $pages;
  193. ?>
  194. <a href="<?php echo $_SERVER['PHP_SELF'] . '?p=' .$next ?>" class="<?php echo $show2; ?>">下一页</a>
  195. <!--尾页-->
  196. <a href="<?php echo $_SERVER['PHP_SELF'] . '?p=' .$pages ?>" class="<?php echo $show2; ?>">尾页</a>
  197. </p>
  198. <!--跳转指定页-->
  199. <form name="form" method="get" action="<?php echo $_SERVER['PHP_SELF']; ?>">
  200. <input name="p" type="number" size="3" min="1" max="<?php echo $pages; ?>">
  201. <input type="submit" value="跳转">
  202. <a href="<?php echo $_SERVER['PHP_SELF'] . '?p=' .$_GET['p'] ?>"></a>
  203. </form>
  204. <script>
  205. function delet(id){
  206. if(confirm("是否删除?")){
  207. return "location.href='handle.php?action=delet&id=<?php echo $plans['id'] ?>";
  208. }
  209. return false;
  210. }
  211. </script>
  212. </body>
  213. </html>

2、演示图片

PHP 文件上传后端处理

1、判断文件是否上传成功

  1. switch ($error):
  2. case 0:
  3. echo '<p style="color:green">文件上传成功</p> ';
  4. break;
  5. case 1:
  6. echo '<p style="color:red">文件超过`php.ini`中`upload_max_filesize`值</p>';
  7. break;
  8. case 2:
  9. echo '<p style="color:red">文件大小超过表单中`MAX_FILE_SIZE`指定的值</p>';
  10. break;
  11. case 3:
  12. echo '<p style="color:red">文件只有部分被上传</p>';
  13. break;
  14. case 4:
  15. echo '<p style="color:red">没有文件被上传</p>';
  16. break;
  17. case 6:
  18. echo '<p style="color:red">找不到临时文件夹</p>';
  19. break;
  20. case 6:
  21. echo '<p style="color:red">文件写入失败</p>';
  22. break;
  23. default:
  24. echo '<p style="color:red">系统错误</p>';
  25. break;
  26. endswitch;

2、检查文件格式

  1. $exts = ['png', 'jpg', 'jpeg', 'wbmp', 'gif'];
  2. if (!in_array($ext, $exts)) {
  3. echo '非法的文件类型';
  4. }

3、检查大小

  • is_uploaded_file() | 用来检测文件是否是通过 http post 方法上传的,而不是系统上的一个文件。作用是防止潜在攻击者通过问题脚本访问并非用于交互的文件

4、处理文件名问题

  1. if ($error == 0) {
  2. //移动暂存区的图片到服务器指定的文件目录
  3. $des = 'storage/';
  4. if (!file_exists($des)) {
  5. mkdir($des, 0777, true);
  6. }
  7. // 为了确保同一秒钟两个用户上传的图片名称相同情况下,文件都能上传成功
  8. $arr = explode('.', $originalFilename);
  9. $ext = end($arr); //后缀
  10. $prefix = array_shift($arr);
  11. $newName = date('YmdHms', time()) . md5($prefix) . time() . '.' . $ext;
  12. move_uploaded_file($tmp_name, $des . $newName);
  13. }

数据库查询构造器链式调用

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