批改状态:合格
老师批语:理解了容器的概念, 写一个服务容器就简单了, 但是实际的服务容器, 比这个复杂多了,有对象, 有数组, 有闭包, 有函数, 有类, 有请求数据,甚至代码片断, 反射结果 等, 但思想是不变的
Model.php
<?phpnamespace home;require 'Db.php';class Model extends Db{}
Db.php
<?phpnamespace home;//数据库操作类class Db{public static $link = null;//保存pdo连接public static $sql = null;//保存语句//使用构造函数连接数据库public function __construct($dsn,$username,$password){try{self::$link = new \PDO($dsn,$username,$password);if(empty(self::$link)){echo '数据库连接失败';}}catch(\Exception $e){echo $e->getMessage();}}//新增数据public static function add(string $table,array $data){$val = array_values($data);$keys = array_map(function($item){return $item = '`'.$item.'`=?';},array_keys($data));$fields = implode(",",$keys);//预处理sql语句,使用占位符$sql = "insert {$table} set {$fields}";$stmt = self::$link->prepare($sql);//执行查询语句$stmt->execute($val);if($stmt->rowCount()===1){return self::$link->lastInsertId();//获取新增的主键ID}else{return $stmt->errorInfo();}}//查询数据public static function find(string $sql){//预处理sql语句$stmt = self::$link->prepare($sql);//执行查询语句$stmt->execute();return $stmt->fetchAll(\PDO::FETCH_ASSOC);}//更新数据public static function update(string $table,string $where,array $data){$val = array_values($data);$keys = array_map(function($item){return $item = '`'.$item.'`=?';},array_keys($data));$fields = implode(",",$keys);//预处理sql语句,使用占位符self::$sql = "update `{$table}` SET {$fields} {$where}";$stmt = self::$link->prepare(self::$sql);//执行查询语句$stmt->execute($val);if($stmt->rowCount()){return $stmt->rowCount();//返回受影响的记录数}else{return $stmt->errorInfo();}}//删除数据public static function delete($table,$where){$sql = "DELETE FROM `{$table}` {$where}";self::$sql=$sql;$stmt = self::$link->prepare($sql);$stmt->execute();if($stmt->rowCount()){return $stmt->rowCount();//返回受影响的记录数}else{return $stmt->errorInfo();}}}
<?phpnamespace home;class View{public function fetch($data){include 'goods.php';}}
goods.php
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>商品信息维护</title><style>body {display: flex;flex-flow: column nowrap;align-items: center;}form {display: flex;flex-flow: row wrap;}form>section {margin: 10px;display: flex;flex-flow: row nowrap;}table {margin-top: 30px;width: 1000px;font-family: verdana, arial, sans-serif;font-size: 11px;color: #333333;border-width: 1px;border-color: #666666;border-collapse: collapse;}table>thead {background-color: #80ff80;}table th {border-width: 1px;padding: 8px;border-style: solid;border-color: #666666;}table td {border-width: 1px;padding: 8px;border-style: solid;border-color: #666666;background-color: #ffffff;text-align: center;}tfoot>tr,tfoot>tr>td {width: initial;}</style></head><body><hr><hr><form action="<?php echo $_SERVER['PHP_SELF'] ?>" class="queryterms" method="POST"><section><label for="goodsname">商品名称:</label><input type="text" name="goodsname" id="goodsname"value="<?php if(isset($_SESSION['goodsname'])) echo $_SESSION['goodsname']?>"></section><section><label for="goodsmodel">商品型号:</label><input type="text" name="goodsmodel" id="goodsmodel"value="<?php if(isset($_SESSION['goodsmodel'])) echo $_SESSION['goodsmodel']?>"></section><section><button>查询</button></section></form><div><table><thead><tr><th>ID</th><th>名称</th><th>型号</th><th>价格</th><th>数量</th><th>状态</th><th>操作</th></tr></thead><tbody><?php foreach($data as $val):?><tr><td><?php echo $val['id'] ?></td><td><?php echo $val['name']?></td><td><?php echo $val['model']?></td><td><?php echo $val['price']?></td><td><?php echo $val['number']?></td><td><?php echo $val['status']?></td><td><a href="handle.php?act=edit&id=<?php echo $val['id'] ?>">编辑</a> <a href="handle.php?act=delete&id=<?php echo $val['id'] ?>">删除</a></td></tr><?php endforeach; ?></tbody><tfoot><tr><td colspan="7"><?php if(isset($page))echo $page; ?></td></tr></tfoot></table></div></body></html>
<?phpnamespace home;require 'Model.php';require 'View.php';//.直接在方法内实例化外部类使用class Controller{public function index($dsn,$username,$password){$data = (new Model($dsn,$username,$password))::find('select * from goods limit 2');return (new View)->fetch($data);}}$ctrl = new Controller;$ctrl->index($dsn,$username,$password);
至此,就完成了一个最简单的mvc框架,Model类负责处理数据、view输出展示数据,controller类负责接收处理请求和返回数据
效果图:

<?phpnamespace home;require 'Db.php';class Model extends Db{public function __construct(){if(file_exists('config.php')){include 'config.php';}try{self::$link = new \PDO($dsn,$username,$password);if(empty(self::$link)){echo '数据库连接失败';}}catch(\Exception $e){echo $e->getMessage();}}}
// 在参数中传入外部类的实例class Controller{public function index(Model $model,view $view){$data = $model::find('select * from goods limit 2,3');return $view->fetch($data);}}$ctrl = new Controller;$ctrl->index(new Model,new View);
效果图:

通过参数传递类实例的方式,成功把模型和视图类的实例创建放到了客户端,代码涉及改造量也大大降低。但是依赖的类很多时,要一个个的创建类的实例,也比较麻烦
服务容器:
<?phpnamespace home;//服务容器类class Container{public $binds = [];//绑定服务到容器public function bind($alias,\Closure $process){$this->binds[$alias] = $process;}//使用public function make($alias,array $param=[]){return call_user_func_array($this->binds[$alias],$param);}}
容器依赖:
class Controller3{public function index(Container $container){//从容器中取得model和view类的对象实例$data = $container->make('Model')::find('select * from goods limit 6,5');return $container->make('View')->fetch($data);}}$container = new Container;//注册服务,绑定类到容器中$container->bind('Model',function(){return new Model();});$container->bind('View',function(){return new View;});$container->bind('controller',function(){return new Controller3;});//使用服务$container->make('controller')->index($container);
效果图:

服务容器就像一个全局变量,把所有服务类放到容器中,使用时根据注册的名字即可直接获得实例
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号