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 内容如下: