手把手编写PHP框架 深入了解MVC运行流程(3)

callHook()的作用就是,从全局变量  G ET[ ′ url ′ ]变量中获取URL,并将其分割成三部分: GET[′url′]变量中获取URL,并将其分割成三部分:controller、action和 action和queryString。 

例如,URL链接为:todo.com/item/view/1/first-item,那么
 •$controller 就是:item
 •$action 就是:view
 •查询字符串Query String就是:array(1, first-item) 

分割完成后,会实例化一个新的控制器:$controller.'Controller'(其中“.”是连字符),并调用其方法 $action。 

3.6 控制器/Controller基类 

接下来的操作就是在 fastphp 中建立程序所需的基类,包括控制器、模型和视图的基类。 

新建控制器基类为 Controller.class.php,控制器的主要功能就是总调度,具体具体内容如下:
 

<?php /** * 控制器基类 */ class Controller { protected $_controller; protected $_action; protected $_view; // 构造函数,初始化属性,并实例化对应模型 function __construct($controller, $action) { $this->_controller = $controller; $this->_action = $action; $this->_view = new View($controller, $action); } // 分配变量 function assign($name, $value) { $this->_view->assign($name, $value); } // 渲染视图 function __destruct() { $this->_view->render(); } }  

Controller 类实现所有控制器、模型和视图(View类)的通信。在执行析构函数时,我们可以调用 render() 来显示视图(view)文件。

3.7 模型Model基类

新建模型基类为 Model.class.php,模型基类 Model.class.php 代码如下:

<?php class Model extends Sql { protected $_model; protected $_table; function __construct() { // 连接数据库 $this->connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME); // 获取模型名称 $this->_model = get_class($this); $this->_model = rtrim($this->_model, 'Model'); // 数据库表名与类名一致 $this->_table = strtolower($this->_model); } function __destruct() { } }

考虑到模型需要对数据库进行处理,所以单独建立一个数据库基类 Sql.class.php,模型基类继承 Sql.class.php,代码如下:

<?php class Sql { protected $_dbHandle; protected $_result; // 连接数据库 public function connect($host, $user, $pass, $dbname) { try { $dsn = sprintf("mysql:host=%s;dbname=%s;charset=utf8", $host, $dbname); $this->_dbHandle = new PDO($dsn, $user, $pass, array(PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC)); } catch (PDOException $e) { exit('错误: ' . $e->getMessage()); } } // 查询所有 public function selectAll() { $sql = sprintf("select * from `%s`", $this->_table); $sth = $this->_dbHandle->prepare($sql); $sth->execute(); return $sth->fetchAll(); } // 根据条件 (id) 查询 public function select($id) { $sql = sprintf("select * from `%s` where `id` = '%s'", $this->_table, $id); $sth = $this->_dbHandle->prepare($sql); $sth->execute(); return $sth->fetch(); } // 根据条件 (id) 删除 public function delete($id) { $sql = sprintf("delete from `%s` where `id` = '%s'", $this->_table, $id); $sth = $this->_dbHandle->prepare($sql); $sth->execute(); return $sth->rowCount(); } // 自定义SQL查询,返回影响的行数 public function query($sql) { $sth = $this->_dbHandle->prepare($sql); $sth->execute(); return $sth->rowCount(); } // 新增数据 public function add($data) { $sql = sprintf("insert into `%s` %s", $this->_table, $this->formatInsert($data)); return $this->query($sql); } // 修改数据 public function update($id, $data) { $sql = sprintf("update `%s` set %s where `id` = '%s'", $this->_table, $this->formatUpdate($data), $id); return $this->query($sql); } // 将数组转换成插入格式的sql语句 private function formatInsert($data) { $fields = array(); $values = array(); foreach ($data as $key => $value) { $fields[] = sprintf("`%s`", $key); $values[] = sprintf("'%s'", $value); } $field = implode(',', $fields); $value = implode(',', $values); return sprintf("(%s) values (%s)", $field, $value); } // 将数组转换成更新格式的sql语句 private function formatUpdate($data) { $fields = array(); foreach ($data as $key => $value) { $fields[] = sprintf("`%s` = '%s'", $key, $value); } return implode(',', $fields); } }

应该说,Sql.class.php 是框架的核心部分。为什么?因为通过它,我们创建了一个 SQL 抽象层,可以大大减少了数据库的编程工作。虽然 PDO 接口本来已经很简洁,但是抽象之后框架的可灵活性更高。 

3.8 视图View类 

视图类 View.class.php 内容如下:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/21b500a090a82a5a42ec3b238dc62c6c.html