博客列表 >第15章 0302-文件上传与MVC初步,(实现多文件上传案例,演示MVC与依赖注入的原理)

第15章 0302-文件上传与MVC初步,(实现多文件上传案例,演示MVC与依赖注入的原理)

努力工作--周工--Robin
努力工作--周工--Robin原创
2021年03月12日 08:50:10614浏览

程序运行截图

" class="reference-link">

一、多文件上传,上传类封装,思路总结

  1. 1 上传代码封装为UpLoad.php类文件;
  2. 2 UpLoad.php上传类提供,upLoadFile(文件上传)、checkErrorCode(错误码检测)、checkType(文件类型检测),3个公有方法;
  3. 3 UpLoad.php上传类中,上传文件的命名采用当前时间 + 3位随机数来实现;
  4. 4 在测试文件中,实例化UpLoad.php上传类,并将上传的文件由$_FILES[]超全局变量接收后,传给上传类;

1、多文件上代演示demo.php代码

  1. <?php
  2. spl_autoload_register(function ($name) {
  3. $file = str_replace('\\', DIRECTORY_SEPARATOR, $name) . '.php';
  4. require $file;
  5. });
  6. if (!empty($_POST)) {
  7. $files = $_FILES['file'];
  8. $upload = new UpLoad();
  9. $upload->upLoadFile($files);
  10. }
  11. ?>
  12. <form method="post" enctype="multipart/form-data">
  13. <fieldset>
  14. <legend>多文件上传</legend>
  15. <input type="hidden" name="MAX_FILE_SIZE" value="1000000">
  16. <!-- 添加 multipart name的值写成php数组的格式 -->
  17. <input type="file" multiple name="file[]">
  18. <input type="submit" value="上传">
  19. </fieldset>
  20. </form>

2、封装的UpLoad.php类代码

  1. <?php
  2. class UpLoad
  3. {
  4. private $error; //保存错误信息
  5. public function upLoadFile($files)
  6. {
  7. foreach ($files['error'] as $key => $error) {
  8. if ($this->checkErrorCode($error)) {
  9. //调用文件类型验证函数
  10. if ($this->checkType($files['tmp_name'][$key])) {
  11. // 现在随机文件名样板:20210309033027827,时间正规写法date('Y-m-d H:i:s'),
  12. $randName = date('YmdHis') . '_' . rand(100, 999);
  13. $path = './upload/' . $randName . strrchr($files['name'][$key], '.');
  14. //echo $path, '<br>';
  15. if (move_uploaded_file($files['tmp_name'][$key], $path)) {
  16. echo "<h2 style='color:green'>{$files['name'][$key]}上传成功</h2>";
  17. echo "<img src='{$path}' width='150' />";
  18. }
  19. } else {
  20. echo "<h2 style='color:red'>{$files['name'][$key]}, {$this->errorMsg}...</h2>";
  21. }
  22. } else {
  23. echo "<h2 style='color:red'>{$files['name'][$key]}, {$this->errorMsg}...</h2>";
  24. }
  25. }
  26. }
  27. public function checkErrorCode($ErrorCode): bool
  28. {
  29. if ($ErrorCode != 0) {
  30. switch ($ErrorCode) {
  31. case 1:
  32. $this->errorMsg = '文件超过系统允许的最大值';
  33. return false;
  34. case 2:
  35. $this->errorMsg = '文件大小超过了表单允许的最大值';
  36. return false;
  37. case 3:
  38. $this->errorMsg = '只有部分文件上传';
  39. return false;
  40. case 4:
  41. $this->errorMsg = '没有文件上传';
  42. return false;
  43. case 6:
  44. $this->errorMsg = '找不到临时文件';
  45. return false;
  46. case 7:
  47. $this->errorMsg = '文件写入失败';
  48. return false;
  49. default:
  50. $this->errorMsg = '未知错误';
  51. return false;
  52. }
  53. } else {
  54. return true;
  55. }
  56. }
  57. public function checkType($file): bool
  58. {
  59. //第一步:创建finfo资源
  60. $info = finfo_open(FILEINFO_MIME_TYPE);
  61. //第二步:将finfo资源和文件做比较,识别出文件mime类型
  62. $mime = finfo_file($info, $file);
  63. //第三步,比较是否合法
  64. $allow = array('image/jpeg', 'image/png', 'image/gif'); //允许的类别
  65. if (in_array($mime, $allow)) {
  66. return true;
  67. } else {
  68. $this->errorMsg = '文件类型不合法...';
  69. return false;
  70. }
  71. }
  72. }

二、MVC与依赖注入的原理

  1. 1 此示例制作三个文件,Model.php(模型类)、View.php(视图类)、Controller.php(控制器类);
  2. 2 Model.php(模型类)中,封装了获取数据库数据的方法;
  3. 3 View.php(视图类)中,封装了显示界面;
  4. 4 Controller.php(控制器类)中,封装了服务容器Container类;
  5. 5 服务容器Container类中,提供了bind(绑定数据)、make(读取数据)两个方法;
  6. 6 实例化容器Container类后,给定关键字,通过匿名函数将实便化的模型类、视图类,绑定到实便化的容器类中;
  7. 7 通过实例化Controller.php(控制器类),并通过关键字来获得模型类数据,并渲染到视图类中;
  8. 8 不是很非常能理解容器类的使用和代码意思,不知道我这样理解对不对???

1、Model.php(模型类)代码

  1. <?php
  2. // 模型类
  3. class Model
  4. {
  5. // 获取数据的方法
  6. public function getData()
  7. {
  8. //连接数据库
  9. $pdo = new PDO('mysql:dbname=phpedu', 'root', 'root');
  10. //每页显示员工信息的条目数量
  11. $num = 10;
  12. //目前显示是第几页,默认为第1页
  13. $page = $_GET['p'] ?? 1;
  14. //页面加载的偏移量, 用于分布,给到sql语句使用,select * from `staffs` limit {$offset}, {$num};
  15. $offset = ($page - 1) * $num;
  16. //计算分页数量
  17. //获取分页后总条目数, 使用别名total后,变量$pageNum Array的结果:( [ceil(count(*)/10)] => 8 )
  18. $stmt = $pdo->prepare("select ceil(count(*)/{$num}) as total from `staffs`;");
  19. $stmt->execute();
  20. $pageNum = $stmt->fetch()['total'];
  21. //获取员工数据$staffs,给到table渲染
  22. $stmt = $pdo->prepare("select * from `staffs` limit {$offset}, {$num}");
  23. $stmt->execute();
  24. $staffs = $stmt->fetchAll();
  25. return $staffs;
  26. }
  27. }

2、View.php(视图类)代码

  1. <?php
  2. // 视图
  3. class View
  4. {
  5. // 数据展示
  6. public function fetch($staffs)
  7. {
  8. $table = '<table border="1" cellspacing="0">';
  9. $table .= '<caption>员工信息表</caption>
  10. <tr bgcolor="lightcyan">
  11. <th>id</th>
  12. <th>姓名</th>
  13. <th>性别</th>
  14. <th>工资</th>
  15. <th>邮箱</th>
  16. <th>生日</th>
  17. </tr>';
  18. foreach ($staffs as $staff) {
  19. $table .= '<tr>';
  20. $table .= '<td>' . $staff['sid'] . '</td>';
  21. $table .= '<td>' . $staff['name'] . '</td>';
  22. $table .= '<td>' . $staff['gender'] . '</td>';
  23. $table .= '<td>' . $staff['salary'] . '</td>';
  24. $table .= '<td>' . $staff['email'] . '</td>';
  25. $table .= '<td>' . $staff['birthday'] . '</td>';
  26. $table .= '</tr>';
  27. }
  28. $table .= '</table>';
  29. return $table;
  30. }
  31. }

3、Controller.php(控制器类)代码

  1. <?php
  2. //引入模型类、视图类
  3. require 'Model.php';
  4. require 'View.php';
  5. // 服务容器
  6. class Container {
  7. // 1. 对象容器
  8. private $instances = [];
  9. // 2. 添加对象
  10. public function bind($alias, Closure $process)
  11. {
  12. $this->instances[$alias] = $process;
  13. }
  14. // 3.取出对象
  15. public function make($alias, $params=[]) {
  16. return call_user_func_array($this->instances[$alias], []);
  17. }
  18. }
  19. // 将依赖的外部对象添加到容器中
  20. $container = new Container();
  21. $container->bind('model',function (){return new Model();});
  22. $container->bind('view',function (){return new View();});
  23. class Controller {
  24. // 1. 获取数据, 2. 渲染视图
  25. public function index(Container $container) {
  26. // 1. 获取数据
  27. $data = $container->make('model')->getData();
  28. // 2. 渲染视图
  29. return $container->make('view')->fetch($data);
  30. }
  31. }
  32. // 测试
  33. // 创建控制器对象
  34. $ctrl = new Controller();
  35. echo $ctrl->index($container);
声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议