Blogger Information
Blog 119
fans 3
comment 1
visits 94694
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
php原生分页、查询构造器、文件上传后端注意事项
赵大叔
Original
677 people have browsed it

<!-- 作业内容: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);
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