博客列表 >MVC框架流程中服务容器和门面的应用-PHP培训十期线上班

MVC框架流程中服务容器和门面的应用-PHP培训十期线上班

手机用户1576673622
手机用户1576673622原创
2020年02月22日 20:33:11772浏览

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

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议