Blogger Information
Blog 29
fans 0
comment 0
visits 19737
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
MVC框架流程中服务容器和门面的应用-PHP培训十期线上班
手机用户1576673622
Original
771 people have browsed it

在php程序设计中,应避免类严重依赖外部对象,降低”代码耦合”, 同时要”共享”依赖的外部对象,不仅如此,还应该降低程序的复杂性,使程序更加容易被访问。通过”注入依赖”、”对象共享”、”服务容器”、”Facade门面技术”等方法的使用,可以实现上述的要求。下面通过一个功能相对完整的MVC的操作来演示。

Model类
  1. <?php
  2. //文件src\MVC\Model.php
  3. namespace src\MVC;
  4. class Model
  5. {
  6. private $connect;
  7. public function __construct()
  8. {
  9. $this->connect = new \PDO('mysql:host=localhost;dbname=phpedu', 'root', 'root');
  10. }
  11. public function getData(): array
  12. {
  13. return $this->connect->query("SELECT * FROM `{$this->table}`")->fetchAll(\PDO::FETCH_ASSOC);
  14. }
  15. public function __set(string $name, $val)
  16. {
  17. $this->{$name} = $val;
  18. }
  19. //查看某个字段的属性
  20. public function getFildsInfo(\Closure $callback = NULL)
  21. {
  22. $stmt = $this->connect->query("SHOW full fields FROM `{$this->table}` " . (($this->fieldsnm) ? " where field='{$this->fieldsnm}';" : NULL));
  23. $fetch = $stmt->fetchAll(\PDO::FETCH_ASSOC);
  24. if (!isset($this->property)) {
  25. return $fetch[0];
  26. }
  27. $res = $fetch[0][$this->property];
  28. if (!$callback) {
  29. return $res;
  30. } else {
  31. return call_user_func_array($callback, [$res]);
  32. }
  33. }
  34. //将备注属性进行替换,备注用query_string的格式书写"性别?0=男&1=女"
  35. public function getProperty($name = NULL)
  36. {
  37. return $this->getFildsInfo(function ($str) use ($name) {
  38. $info = \parse_url($str);
  39. //如果没有query
  40. if ($name === NULL) return $info['path'];
  41. //如果有query
  42. if (isset($info['query'])) {
  43. \parse_str($info['query'], $params);
  44. return $params[$name];
  45. }
  46. });
  47. }
  48. }
View类
  1. <?php
  2. //文件src\MVC\View.php
  3. namespace src\MVC;
  4. class View
  5. {
  6. private $model;
  7. public function __construct(Model $model)
  8. {
  9. $this->model = $model;
  10. }
  11. public function __set(string $name, $val)
  12. {
  13. $this->{$name} = $val;
  14. }
  15. public function fetch()
  16. {
  17. //处理表头
  18. $replacestr = function ($fieldsnm, $property, $value = NULL) {
  19. $this->model->fieldsnm = $fieldsnm;
  20. $this->model->property = $property;
  21. $res = $this->model->getProperty($value);
  22. return (strlen(str_replace(' ', '', $res)) === 0) ? $fieldsnm : $res;
  23. };
  24. $fieldsPro = function ($fieldValue, $field) {
  25. //处理时间戳
  26. if (isset($this->model->timestamp) && in_array($field, $this->model->timestamp)) {
  27. return date('Y年m月d日', $fieldValue);
  28. };
  29. //处理元素备注
  30. if (isset($this->model->default) && in_array($field, $this->model->default)) {
  31. $this->model->fieldsnm = $field;
  32. $this->model->property = 'Comment';
  33. return $this->model->getProperty($fieldValue);
  34. };
  35. return $fieldValue;
  36. };
  37. //样式
  38. $css = <<<DOC
  39. <!DOCTYPE html>
  40. <html lang="en">
  41. <head>
  42. <meta charset="UTF-8">
  43. <link rel="stylesheet" href="{$this->css}" type="text/css"/>
  44. <title>Document</title>
  45. </head>
  46. <body>
  47. DOC;
  48. //数据
  49. $data = $this->model->getData();
  50. //字段
  51. $fields = array_keys($data[0]);
  52. //css样式表
  53. $table .= $css;
  54. $table .= '<table>';
  55. //标题
  56. $table .= '<caption>' . $this->title . '</caption>';
  57. //表头
  58. $table .= '<tr>';
  59. foreach ($fields as $value) {
  60. $table .= '<th>' . $replacestr($value, 'Comment') . '</th>';
  61. }
  62. $table .= '</tr>';
  63. //主体
  64. foreach ($data as $value) {
  65. $table .= '<tr>';
  66. foreach ($fields as $field) {
  67. $table .= '<td>' . $fieldsPro($value[$field], $field) . '</td>';
  68. }
  69. $table .= '</tr>';
  70. }
  71. //结束标志
  72. $table .= '</table>';
  73. $table .= '</body>';
  74. $table .= '</html>';
  75. return $table;
  76. }
  77. }
View类用到的css文件
  1. /*文件src\MVC\css.css*/
  2. table {border-collapse: collapse; border: 1px solid;text-align: center;}
  3. caption {font-size: 1.2rem; margin-bottom: 10px;}
  4. tr:first-of-type { background-color:wheat;}
  5. td,th {border: 1px solid; padding:5px}
Container对象容器
  1. <?php
  2. //文件 src\MVC\Container.php
  3. namespace src\MVC;
  4. //对象容器
  5. class Container
  6. {
  7. protected $container=[];
  8. public function bind(string $name, \Closure $closure)
  9. {
  10. $this->container[$name]=$closure;
  11. }
  12. public function make(string $name, $params=[])
  13. {
  14. return call_user_func_array($this->container[$name], $params);
  15. }
  16. }
Facade门面类
  1. <?php
  2. //文件 src\MVC\Facade.php
  3. namespace src\MVC;
  4. //Facade门面类
  5. class Facade
  6. {
  7. protected static $container;
  8. protected static $model;
  9. public static function initialize(Container $container)
  10. {
  11. static::$container=$container;
  12. }
  13. public static function getData()
  14. {
  15. static::$model=static::$container->make('model');
  16. static::$model->getData();
  17. }
  18. public static function fetch()
  19. {
  20. return static::$container->make('view',[static::$model])->fetch();
  21. }
  22. }
Controller 控制器
  1. <?php
  2. //文件src\MVC\Controller.php
  3. namespace src\MVC;
  4. //控制器
  5. class Controller
  6. {
  7. public function __construct(Container $container)
  8. {
  9. Facade::initialize($container);
  10. }
  11. public function index()
  12. {
  13. //model
  14. Facade::getData();
  15. //view
  16. return Facade::fetch();
  17. }
  18. }
自动加载类
  1. <?php
  2. //文件src\MVC\AutoLoad.php
  3. namespace src\MVC;
  4. spl_autoload_register(function($class)
  5. {
  6. $prefix=__DIR__;
  7. $arr=explode("\\",$class);
  8. $file=$prefix."\\". $arr[count($arr)-1] . '.php';
  9. $file = str_replace("\\", DIRECTORY_SEPARATOR, $file);
  10. file_exists($file) ? require $file : "文件不存在,加载失败";
  11. });
调用类
  1. <?php
  2. //文件src\MVC\Main.php
  3. namespace src\MVC;
  4. //自动加载
  5. require 'AutoLoad.php';
  6. $container=new Container();
  7. $container->bind('model',function(){
  8. $model= new Model();
  9. $model->table='staffs';
  10. //timestamp可添加时间字段集
  11. $model->timestamp=['register_time','hiredate'];
  12. //default可添加需解析备注Comment的字段集
  13. $model->default=['sex'];
  14. return $model;
  15. });
  16. $container->bind('view',function(Model $model){
  17. $view= new View($model);
  18. $view->title="人员信息表";
  19. $view->css='css.css';
  20. return $view;
  21. });
  22. $control=new Controller($container);
  23. echo $control->index();
结果
1. 使用的数据表staffsusers结构和内容




2. 运行结果




总结

Facade门面:是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。该模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体的细节,这样会大大降低应用程序的复杂度,提高了程序的可维护性。

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