批改状态:合格
老师批语:理解流程与原理, 目标, 远比能写代码要强, 因为代码你会很快忘记, 思维方式一直都会影响着你
在php程序设计中,应避免类严重依赖外部对象,降低”代码耦合”, 同时要”共享”依赖的外部对象,不仅如此,还应该降低程序的复杂性,使程序更加容易被访问。通过”注入依赖”、”对象共享”、”服务容器”、”Facade门面技术”等方法的使用,可以实现上述的要求。下面通过一个功能相对完整的MVC的操作来演示。
<?php//文件src\MVC\Model.phpnamespace src\MVC;class Model{private $connect;public function __construct(){$this->connect = new \PDO('mysql:host=localhost;dbname=phpedu', 'root', 'root');}public function getData(): array{return $this->connect->query("SELECT * FROM `{$this->table}`")->fetchAll(\PDO::FETCH_ASSOC);}public function __set(string $name, $val){$this->{$name} = $val;}//查看某个字段的属性public function getFildsInfo(\Closure $callback = NULL){$stmt = $this->connect->query("SHOW full fields FROM `{$this->table}` " . (($this->fieldsnm) ? " where field='{$this->fieldsnm}';" : NULL));$fetch = $stmt->fetchAll(\PDO::FETCH_ASSOC);if (!isset($this->property)) {return $fetch[0];}$res = $fetch[0][$this->property];if (!$callback) {return $res;} else {return call_user_func_array($callback, [$res]);}}//将备注属性进行替换,备注用query_string的格式书写"性别?0=男&1=女"public function getProperty($name = NULL){return $this->getFildsInfo(function ($str) use ($name) {$info = \parse_url($str);//如果没有queryif ($name === NULL) return $info['path'];//如果有queryif (isset($info['query'])) {\parse_str($info['query'], $params);return $params[$name];}});}}
<?php//文件src\MVC\View.phpnamespace src\MVC;class View{private $model;public function __construct(Model $model){$this->model = $model;}public function __set(string $name, $val){$this->{$name} = $val;}public function fetch(){//处理表头$replacestr = function ($fieldsnm, $property, $value = NULL) {$this->model->fieldsnm = $fieldsnm;$this->model->property = $property;$res = $this->model->getProperty($value);return (strlen(str_replace(' ', '', $res)) === 0) ? $fieldsnm : $res;};$fieldsPro = function ($fieldValue, $field) {//处理时间戳if (isset($this->model->timestamp) && in_array($field, $this->model->timestamp)) {return date('Y年m月d日', $fieldValue);};//处理元素备注if (isset($this->model->default) && in_array($field, $this->model->default)) {$this->model->fieldsnm = $field;$this->model->property = 'Comment';return $this->model->getProperty($fieldValue);};return $fieldValue;};//样式$css = <<<DOC<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><link rel="stylesheet" href="{$this->css}" type="text/css"/><title>Document</title></head><body>DOC;//数据$data = $this->model->getData();//字段$fields = array_keys($data[0]);//css样式表$table .= $css;$table .= '<table>';//标题$table .= '<caption>' . $this->title . '</caption>';//表头$table .= '<tr>';foreach ($fields as $value) {$table .= '<th>' . $replacestr($value, 'Comment') . '</th>';}$table .= '</tr>';//主体foreach ($data as $value) {$table .= '<tr>';foreach ($fields as $field) {$table .= '<td>' . $fieldsPro($value[$field], $field) . '</td>';}$table .= '</tr>';}//结束标志$table .= '</table>';$table .= '</body>';$table .= '</html>';return $table;}}
/*文件src\MVC\css.css*/table {border-collapse: collapse; border: 1px solid;text-align: center;}caption {font-size: 1.2rem; margin-bottom: 10px;}tr:first-of-type { background-color:wheat;}td,th {border: 1px solid; padding:5px}
<?php//文件 src\MVC\Container.phpnamespace src\MVC;//对象容器class Container{protected $container=[];public function bind(string $name, \Closure $closure){$this->container[$name]=$closure;}public function make(string $name, $params=[]){return call_user_func_array($this->container[$name], $params);}}
<?php//文件 src\MVC\Facade.phpnamespace src\MVC;//Facade门面类class Facade{protected static $container;protected static $model;public static function initialize(Container $container){static::$container=$container;}public static function getData(){static::$model=static::$container->make('model');static::$model->getData();}public static function fetch(){return static::$container->make('view',[static::$model])->fetch();}}
<?php//文件src\MVC\Controller.phpnamespace src\MVC;//控制器class Controller{public function __construct(Container $container){Facade::initialize($container);}public function index(){//modelFacade::getData();//viewreturn Facade::fetch();}}
<?php//文件src\MVC\AutoLoad.phpnamespace src\MVC;spl_autoload_register(function($class){$prefix=__DIR__;$arr=explode("\\",$class);$file=$prefix."\\". $arr[count($arr)-1] . '.php';$file = str_replace("\\", DIRECTORY_SEPARATOR, $file);file_exists($file) ? require $file : "文件不存在,加载失败";});
<?php//文件src\MVC\Main.phpnamespace src\MVC;//自动加载require 'AutoLoad.php';$container=new Container();$container->bind('model',function(){$model= new Model();$model->table='staffs';//timestamp可添加时间字段集$model->timestamp=['register_time','hiredate'];//default可添加需解析备注Comment的字段集$model->default=['sex'];return $model;});$container->bind('view',function(Model $model){$view= new View($model);$view->title="人员信息表";$view->css='css.css';return $view;});$control=new Controller($container);echo $control->index();
staffs、users结构和内容







Facade门面:是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。该模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体的细节,这样会大大降低应用程序的复杂度,提高了程序的可维护性。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号