php加载视图,PHP-用MVC搭建一个框架,自动加载视图-2019年10月15日

10月15日:

用MVC搭建一个框架,自动加载视图

使用影片网站后台管理的实战案例, 结合MVC的设计模式,使用php路由机制,搭建一个url驱动运行的CMS应用。

MVC的工作流程程如下:1. 浏览者->发出指令,后台调用控制器处理

2. 控制器->按指令选取一个合适的模型    (动作集)

3. 模型->按照控制器指令选取相应的数据    (功能集)

4. 控制器->按指令选取相应的视图

5. 视图->把第三步取到的数据按用户想要的样子显示出来    (显示集)

实例说明:

现有的案例采用面向过程的编写方法,我将它改写为面向对象的编写模式,用面向对象模式可以更好地组织控制器,和管理目标组(产品族:目前管理的产品有导演、演员和影片)

【1】编写一个Router.php来解析url。所有url采用全动态生成,约定a代表模块,page代表分页 * 入口地址统一为: index.php?a=模块,

例如:index.php?a=login。按照这种约定来来解析出的对应的控制器(login)的相应操作(loginAction);

【2】编写一个自动加载文件AutoLoad.php,实现所有类的动态懒加载;

【3】编写一个入口文件index.php,在此引入url解析的模块 - ->然后在 控制器中 -->派发到model执行 -->返回在controller里 派送到视图模版显示;

【4】编写一个控制器文件controller.php,这里主要是逻辑处理的操作,去请求数据结果 , 然后送去显示;

【5】编写model.php,这里主要实现数据库操作、方法库等与数据资源相关的操作;

【6】view模块中,这里主要功能是把获得的数据资源展示给用户,是PHP与html/js相关的内容混编的。

代码实现:(主要是model和controller两个核心模块代码实现的一部分)namespace controller;

use \model\DB;

class Action {

public static function loginAction() {

return 'login_tpl';

}

public static function logoutAction() {

if (session_destroy()) {

echo "

location.href='/mytest/cms/index.php';

";

}

return '';

}

public static function indexAction() {

self::getData(DB::DIRECTOR_TABLE, 'index');

return 'index_tpl';

}

public static function userAction() {

self::getData(DB::USER_TABLE, 'user');

return 'user_tpl';

}

public static function videoAction() {

self::getData(DB::VIDEO_TABLE, 'video');

return 'video_tpl';

}

private static function getData($table, $flag) {

// 分页

$gpage = isset($_GET['page']) ? $_GET['page'] : 1;

$limit = ($gpage - 1) * DB::NUM_PER_PAGE; //第几页,第一个数据是0开始,0*10=0

$limit = $limit . ',' . DB::NUM_PER_PAGE; //组装limit

// 条件

if ($table === DB::VIDEO_TABLE) {

if (!empty($_GET['va'])) {

if ($_GET['select'] == 1) {

$where = DB::table($table)

->field('tid')

->where(array('name' => $_GET['va']))

->find();

} else {

$where = DB::table($table)

->field('uid')

->where(array('name' => $_GET['va']))

->find();

// $where = find($db,$userTable,'uid',array('name'=>$_GET['va']));

}

} else {

$where = '';

}

// 查询影片

// $video = select($db,$videoTable,'*',$where,'add_time DESC',$limit);

$video = DB::table($table)

->field('*')

->where($where)

->orderBy('add_time', 'DESC')

->limit($limit)

->select();

if ($video) {

foreach ($video as &$v) {

$tname = DB::table($table)

->field('name')

->where(array('tid' => $v['tid']))

->find();

// find($db,$directorTable,'name',array('tid'=>$v['tid']));

$v['tname'] = $tname['name'];

$uname = DB::table($table)

->field('name')

->where(array('uid' => $v['uid']))

->find();

// find($db,$userTable,'name',array('uid'=>$v['uid']));

$v['uname'] = $uname['name'];

}

}

$list['video'] = $video;

// 查询导演,作为参照

$list['director'] = DB::table(DB::DIRECTOR_TABLE)

->field('*')

->where($where)

->select();

// select($db,$directorTable,'*','');

// 查询明星,作为参照

$list['user'] = DB::table(DB::USER_TABLE)

->field('*')

->where($where)

->select();

// select($db,$userTable,'*','');

} else {

if (!empty($_GET['va'])) {

if ($_GET['select'] == 1) {

$where['name'] = $_GET['va'];

} else {

$where['phone'] = $_GET['va'];

}

} else {

$where = '';

}

$list = DB::table($table)

->field('*')

->where($where)

->orderBy('add_time', 'DESC')

->limit($limit)

->select();

}

$count_number = DB::table($table)

->field('*')

->where($where)

->count_number();

if ($count_number > 0) {

$number = ceil($count_number / DB::NUM_PER_PAGE);

$page = '';

for ($p = 1; $p <= $number; $p++) {

$url = '/mytest/cms/index.php?a=' . $flag . '&page=' . $p;

if (!empty($_GET['va'])) {

$url .= '&va=' . $_GET['va'];

if (!empty($_GET['select'])) {

$url .= '&select=' . $_GET['select'];

}

}

if ($p == $gpage) {

$page .= '';

} else {

$page .= '';

}

$page .= $p;

$page .= '';

}

}

DB::$sql_list = $list;

DB::$sql_page = $page;

}

}namespace model;

//定义一个包含数据库连接参数的接口+增删改查

interface iDbconfig {

const TYPE = 'mysql';

const HOST = '127.0.0.1';

const DBNAME = 'test';

const USER_NAME = '*****';

const PASSWORD = '*****';

public function insert($data);

public function update($data);

public function select();

public function find();

public function delete();

public function count_number();

}

//定义Dbset类,实现接口方法

class DbSet implements iDbconfig {

private static $instance = null;

//SQL关键词

protected $table;

private $field;

private $where;

private $limit;

private $orderBy;

//构造函数中自动连接数据库

private function __construct() {

$dsn = iDbconfig::TYPE

. ':host='

. iDbconfig::HOST

. '; dbname='

. iDbconfig::DBNAME;

$user = iDbconfig::USER_NAME;

$password = iDbconfig::PASSWORD;

$pdo = new \PDO($dsn, $user, $password);

}

//禁止克隆

private function __clone() {}

//创建实例

public static function getInstance() {

private static $pdo;

if (is_null(self::$instance)) {

self::$instance = new self();

}

return self::$instance;

}

//SQL 语句关键词处理

public function table($tableName) {

$this->table = $tableName;

return $this;

}

public function field($fields) {

$fieldlist = '';

if (is_array($fields)) {

foreach ($fields as $field) {

$fieldlist .= $field . ', ';

}

} else {

$fieldlist .= $fields;

}

$fieldlist = rtrim(trim($fieldlist), ',');

$this->field = empty($fieldlist) ? '*' : $fieldlist;

return $this;

}

public function where($where) {

$whereList = '';

if (is_array($where)) {

foreach ($where as $k => $v) {

$whereList .= $k . '="' . $v . '" ,';

}

} else {

$whereList .= $where;

}

$whereList = rtrim(trim($whereList), ',');

$this->where = empty($whereList) ? $whereList : ' WHERE ' . $whereList;

return $this;

}

public function limit($limit) {

$this->limit = empty($limit) ? $limit : ' LIMIT ' . $limit;

return $this;

}

public function orderBy($orderBy, $option = 'ASC') {

$sort = in_array($option, ['DESC', 'ASC']) ? $option : 'ASC';

$this->orderBy = empty($orderBy) ? $orderBy : ' ORDER BY ' . $orderBy . ' ' . $sort;

return $this;

}

//----------------以下数据库的增删改查方法---------------------------

public function insert($data) {

$fields = '';

$value = '';

foreach ($data as $key => $v) {

$fields = $fields . ',' . $key;

$value = $value . ',:' . $key;

}

$fields = '(' . ltrim($fields, ',') . ')';

$value = '(' . ltrim($value, ',') . ')';

$sql = 'INSERT INTO '

. $this->table

. ' '

. $fields

. ' VALUES '

. $value;

$stmt = $this->pdo->prepare($sql);

$stmt->execute($data);

return [

'count' => $stmt->rowCount(),

'id' => $this->pdo->lastInsertId(),

];

}

public function update($data) {

$keyArr = array_keys($data);

$set = '';

foreach ($keyArr as $value) {

$set .= $value . '=:' . $value . ',';

}

$set = rtrim($set, ',');

$sql = 'UPDATE '

. $this->table

. ' SET '

. $set

. $this->where;

$stmt = $this->pdo->prepare($sql);

$stmt->execute($data);

return $stmt->rowCount();

}

public function select() {

$sql = 'SELECT '

. $this->field

. ' FROM '

. $this->table

. $this->where

. $this->orderBy

. $this->limit;

$stmt = $this->pdo->prepare($sql);

if ($stmt->execute()) {

// if($stmt->rowCount()>0){

// $stmt->setFetchMode(\PDO::FETCH_ASSOC);

return $stmt->fetchAll(\PDO::FETCH_ASSOC);

// }

} else {

return false;

}

}

public function find() {

$sql = 'SELECT '

. $this->field

. ' FROM '

. $this->table

. $this->where

. $this->orderBy

. $this->limit;

$stmt = $this->pdo->prepare($sql);

$stmt->execute())

return $stmt->fetch(\PDO::FETCH_ASSOC);

}

public function delete() {

$sql = 'DELETE FROM '

. $this->table

. $this->where

. $this->orderBy

. $this->limit;

$stmt = $this->pdo->prepare($sql);

$stmt->execute();

return $stmt->rowCount();

}

public function count_number() {

$sql = 'SELECT count(*) as count_number '

. ' FROM '

. $this->table

. $this->where;

$stmt = $this->pdo->prepare($sql);

if ($stmt->execute()) {

if ($stmt->rowCount() > 0) {

$row = $stmt->fetch(\PDO::FETCH_ASSOC);

$rows = $row['count_number'];

return $rows;

}

} else {

return false;

}

}

}

运行效果展示:

839be1377396f473c354facc8f200d42.png

总结:

1、view视图虽然是用模版完成,但html中嵌入php、js混编,完成起来太繁琐,后期改版维护也不方便,应该有更好的办法;

2、MVC架构中,一个健壮的url地址管理机制是必须的;

3、model的数据转到view中,使用了全局变量,但实际上view中是要引入model中的部分内容的,所以我使用数据库连接类中的静态属性,来传递这个数据。

4、页面中演员、导演和影片的管理动作 可以建立一个工厂模式来实现,后期扩容方便。

通过本次练习,熟悉了MVC结构的使用,离熟练使用还差得很远,需要多多练习。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值