Blogger Information
Blog 17
fans 1
comment 0
visits 14506
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
PHP多文件上传案和MVC简单案例以及MVC的依赖注入和服务容器的原理和实现过程
zl的php学习博客
Original
714 people have browsed it
  1. 写一个实现的多文件上传案例,并将它封装成一个可复用的函数或类 2. 实例演示MVC与依赖注入的原理,以及服务容器对依赖对象的管理的实现过程。。。。

1. 多文件上传案例

文件夹结构

  • upload.php
  • common.php
  • uploads

uplaod.php

  1. <?php
  2. printf('<pre>%s</pre>', print_r($_FILES, true));
  3. if (count($_FILES) > 0) {
  4. include './common.php';
  5. switch ($_GET['t']) {
  6. case 'alone':
  7. echo upload($_FILES['file']);
  8. break;
  9. case 'onebyone':
  10. foreach ($_FILES as $file) {
  11. // echo $file['name'];
  12. echo upload($file);
  13. }
  14. break;
  15. case 'multipart':
  16. $files = [];
  17. foreach ($_FILES['file']['error'] as $key => $value) {
  18. $files[] = [
  19. 'name' => $_FILES['file']['name'][$key],
  20. 'type' => $_FILES['file']['type'][$key],
  21. 'tmp_name' => $_FILES['file']['tmp_name'][$key],
  22. 'error' => $_FILES['file']['error'][$key],
  23. 'size' => $_FILES['file']['size'][$key],
  24. ];
  25. }
  26. foreach ($files as $file) {
  27. // echo $file['name'];
  28. echo upload($file);
  29. }
  30. // var_dump($files);
  31. break;
  32. default:
  33. echo '未知错误';
  34. }
  35. }
  36. ?>
  37. <!DOCTYPE html>
  38. <html lang="en">
  39. <head>
  40. <meta charset="UTF-8">
  41. <title>图片上传</title>
  42. <style>
  43. form {
  44. width: 20em;
  45. margin: 1em auto;
  46. }
  47. fieldset {
  48. margin: 1em;
  49. display: grid;
  50. place-content: flex-start;
  51. }
  52. button[type=button] {
  53. margin-bottom: .5em;
  54. }
  55. </style>
  56. </head>
  57. <body>
  58. <form action="upload.php?t=alone" method="post" enctype="multipart/form-data">
  59. <fieldset>
  60. <label>单文件上传</label>
  61. <input type="hidden" name="MAX_FILE_SIZE" value="10485760">
  62. <input type="file" name="file">
  63. <button>upload</button>
  64. </fieldset>
  65. </form>
  66. <form action="upload.php?t=onebyone" method="post" enctype="multipart/form-data">
  67. <fieldset>
  68. <label>多文件上传: 逐个上传</label>
  69. <input type="hidden" name="MAX_FILE_SIZE" value="10485760">
  70. <input type="file" name="file1">
  71. <button type="button" onclick="oneByOne()">继续添加文件</button>
  72. <button>upload</button>
  73. </fieldset>
  74. </form>
  75. <form action="upload.php?t=multipart" method="post" enctype="multipart/form-data">
  76. <fieldset>
  77. <label>多文件上传: 一次性上传</label>
  78. <input type="hidden" name="MAX_FILE_SIZE" value="10485760">
  79. <input type="file" name="file[]" multiple>
  80. <button>upload</button>
  81. </fieldset>
  82. </form>
  83. <script>
  84. let oneByOneFileNameIndex = 1;
  85. // 动态添加逐个上传的input
  86. function oneByOne() {
  87. const dom = document.querySelector(`input[name=file${oneByOneFileNameIndex}]`);
  88. const input = document.createElement('input');
  89. input.type = 'file'
  90. input.name = 'file' + ++oneByOneFileNameIndex;
  91. dom.insertAdjacentElement('afterend', input);
  92. }
  93. </script>
  94. </body>
  95. </html>

common.php

  1. <?php
  2. /**
  3. * 文件上传
  4. *
  5. * @param array $files: 一个文件的所有数据
  6. * @return string
  7. */
  8. function upload(array $files): string
  9. {
  10. // 获取文件名
  11. $name = $files['name'];
  12. // 获取临时文件的路径
  13. $tmpName = $files['tmp_name'];
  14. // 获取错误信息
  15. $error = $files['error'];
  16. if ($error === 0) {
  17. // 获取文件类型
  18. $type = strstr($files['type'], '/', true);
  19. // 获取文件后缀
  20. $ext = '.' . strtolower(pathinfo($files['name'], PATHINFO_EXTENSION));
  21. if ($type === 'image') {
  22. $path = "uploads/" . md5($name . date('Ymd') . str_pad(mt_rand(1, 9999), 5, '0', STR_PAD_LEFT)) . $ext;
  23. // 检测临时文件的合法性
  24. if (is_uploaded_file($tmpName)) {
  25. // 移动文件
  26. if (move_uploaded_file($tmpName, $path)) {
  27. // 返回成功
  28. return "<span><p style=\"color:green\">{$name}上传成功</p><img src='{$path}' width=250 alt='{$name}' /></span>";
  29. } else {
  30. return '移动文件失败';
  31. }
  32. } else {
  33. return '临时文件不合法';
  34. }
  35. } else {
  36. return '上传类型错误';
  37. }
  38. } else {
  39. return upload_error($error);
  40. }
  41. }
  42. /**
  43. * 文件上传的错误信息集合
  44. *
  45. * @param int $errno: error代码
  46. * @return string
  47. */
  48. function upload_error(int $errno): string
  49. {
  50. switch ($errno) {
  51. case 1:
  52. $msg = '超过的单文件大小';
  53. break;
  54. case 2:
  55. $msg = '超过前端表单限制';
  56. break;
  57. case 3:
  58. $msg = '上传文件不完整';
  59. break;
  60. case 4:
  61. $msg = '没有文件被上传';
  62. break;
  63. case 6:
  64. $msg = '找不到临时目录';
  65. break;
  66. case 7:
  67. $msg = '写入失败,目标目录无写入权限';
  68. break;
  69. default:
  70. exit('未定义错误');
  71. }
  72. return $msg;
  73. }

2.

  1. MVC:
  2. M-模型(数据库相关的操作),
  3. V-视图(页面,html),
  4. C-控制器(功能:1.获取数据 2.选择视图)
  5. 依赖注入: 简单那来说就是为了解决对象之间的耦合(`在一个类中调用其他类的实例`),例2.1:
  6. 方法: 在类的外部实例化其他类, 然后以参数的方式传入.例:2.2:
  7. 服务容器: 将外部依赖(需要引用的外部类实例)进行统一的管理.例2.3

2.1

  1. <?php
  2. namespace test;
  3. require './Model.php';
  4. require './View.php';
  5. // 服务容器
  6. class Conn
  7. // 控制器
  8. class Controller
  9. {
  10. public function index(): string
  11. {
  12. return (new View())->fetch((new \test\Model())->select()['data']);
  13. }
  14. }

2.2

  1. <?php
  2. namespace test;
  3. require './Model.php';
  4. require './View.php';
  5. // 控制器
  6. class Controller
  7. {
  8. // public function index(): string
  9. // {
  10. // return (new View())->fetch((new \test\Model())->select()['data']);
  11. // }
  12. protected $model;
  13. protected $view;
  14. public function __construct($model,$view) {
  15. $this->model = $model;
  16. $this->view = $view;
  17. }
  18. public function index(): string
  19. {
  20. return $this->view->fetch($this->model->select()['data']);
  21. }
  22. }
  23. $model = new Model();
  24. $view = new View();
  25. $controller = new Controller($model, $view);
  26. echo $controller->index();

2.3

  1. <?php
  2. namespace test;
  3. require './Model.php';
  4. require './View.php';
  5. // 服务容器
  6. class Container
  7. {
  8. // 对象容器
  9. protected $instanles = [];
  10. // 写入对象
  11. public function bind($alias, \Closure $process)
  12. {
  13. $this->instanles[$alias] = $process;;
  14. }
  15. // 取出对象
  16. public function make($alias, $params = [])
  17. {
  18. return call_user_func_array($this->instanles[$alias], $params);
  19. }
  20. }
  21. // 控制器
  22. class Controller
  23. {
  24. /*服务容器*/
  25. public function index(Container $instanles)
  26. {
  27. return $instanles->make('view')->fetch($instanles->make('model')->select()['data']);
  28. }
  29. }

3. MVC简单案例(数据来源: https://www.php.cn/blog/detail/26509.html)

文件夹结构

  • Model.php
  • View.php
  • Controller.php
  • index.php

Model.php

  1. <?php
  2. namespace mvc_demo;
  3. use PDO;
  4. // 模型类
  5. class Model
  6. {
  7. // 获取数据
  8. public function getData()
  9. {
  10. $pdo = new PDO('mysql:dbname=phpedu', 'root', 'root');
  11. $stmt = $pdo->prepare('select * from staffs limit 10');
  12. $stmt->execute();
  13. return $stmt->fetchAll(PDO::FETCH_ASSOC);
  14. }
  15. }

View.php

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

Controller.php

  1. <?php
  2. namespace test;
  3. require './Model.php';
  4. require './View.php';
  5. // 服务容器
  6. class Container
  7. {
  8. // 对象容器
  9. protected $instanles = [];
  10. // 写入对象
  11. public function bind($alias, \Closure $process)
  12. {
  13. $this->instanles[$alias] = $process;;
  14. }
  15. // 取出对象
  16. public function make($alias, $params = [])
  17. {
  18. return call_user_func_array($this->instanles[$alias], $params);
  19. }
  20. }
  21. // 控制器
  22. class Controller
  23. {
  24. // public function index(): string
  25. // {
  26. // return (new View())->fetch((new \test\Model())->select()['data']);
  27. // }
  28. /*依赖注入*/
  29. // protected $model;
  30. // protected $view;
  31. //
  32. // public function __construct($model, $view)
  33. // {
  34. // $this->model = $model;
  35. // $this->view = $view;
  36. // }
  37. //
  38. // public function index(): string
  39. // {
  40. // return $this->view->fetch($this->model->select()['data']);
  41. // }
  42. /*服务容器*/
  43. public function index(Container $instanles)
  44. {
  45. return $instanles->make('view')->fetch($instanles->make('model')->select()['data']);
  46. }
  47. }

index.php

  1. <?php
  2. /*服务容器*/
  3. require './Controller.php';
  4. $container = new \test\Container();
  5. $container->bind('model', function (){return new \test\Model();});
  6. $container->bind('view', function (){return new \test\View();});
  7. $table = new \test\Controller();
  8. ?>
  9. <!DOCTYPE html>
  10. <html lang="en">
  11. <head>
  12. <meta charset="utf-8">
  13. <title>mvc</title>
  14. </head>
  15. <body>
  16. <?php echo $table->index($container);?>
  17. </body>
  18. </html>
Correcting teacher:天蓬老师天蓬老师

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