搭建自己的MVC框架
来源:互联网 发布:java springmvc 分页 编辑:程序博客网 时间:2024/05/21 14:55
开始写框架
分析框架执行流程
以TinkPHP为参考
localhost/sc/index.php?c=index&a=user
localhost/sc/index.php/index/user
访问的是:index控制器的user方法
搭建框架核心
路由分析:
/x.php :
//获取地址栏信息并分析//两种方式://普通模式//$_GET['c'];//PATH_INFO模式//$_SERVER['PATH_INFO'];$c = isset($_GET['c'])?$_GET['c']:'';$a = isset($_GET['a'])?$_GET['a']:'';if(empty($c) && empty($a)){ $p = isset($_SERVER['PATH_INFO'])?$_SERVER['PATH_INFO']:''; if(!empty($p)){ $p = trim($p,'/'); list($c,$a) = explode('/',$p); }}if(empty($c) && empty($a)){ $c = 'index'; $a = 'index';}
/x.php
class X{ public static function auto($classname){ if(substr($classname,-10) == 'Controller'){ include APP_PATH.'Controller/'.$classname.'.class.php'; } if(substr($classname,-5)=='Model'){ include APP_PATH.'Model/'.$classname.'class.php'; } }}spl_autoload_register('X::auto');$c .= 'Controller';$controller = new $c();//访问控制器中的方法$controller->$a();
项目入口文件
xm/index.php
define('APP_PATH',__DIR__.'/');include ("../xphp/x.php");
项目的控制器
xm/Controller/indexController.class.php
class indexController{ //控制器中的方法 public function index(){ echo 'my index a'; }}
继承基类
/x.php
define('X_PATH',__DIR__.'/');class app{ public function __construct(){……} public function iserror(){……} public function sd(){……} public function errlog($code,$message,$file,$line){……} public static $map = [ 'Controller' => X_PATH.'Care/Controller.php', 'Model' => X_PATH.'Care/Model.php', ]; public static function auto($classname){ if(isset(self::$map[$classname])){ include self::$map[$classname]; }elseif(substr($classname,-10)=="Controller"){ include APP_PATH.'Controller/'.$classname.'.class.php'; }elseif(substr($classname,-5)=="Model"){ include APP_PATH.'Model/'.$classname.'.class.php'; } }}
基类:
/Care/Controller.php
class Controller{}
/Care/Model.php
class Model{}
控制器:
class indexController extends Controller{ public function index(){ //调用model类,完成数据处理工作 $model = new indexModel(); echo $model->add(1,2); }}
模型:
class indexModel extends Model{ public function add($n,$m){ return $n+$m; }}
Model基类
/Care/Model.php
class Model{ protected $db = ''; protected $table = ''; protected $pk = ''; protected $field = array(); public function __construct() { $conf = [ 'dbtype' => 'mysql', 'host' => 'localhost', 'dbname'=>'test', 'user' => 'root', 'pwd' => '', 'charset' => 'utf8', ]; $dsn = $conf['dbtype'].':host='.$conf['host'].';dbname='.$conf['dbname']; $this->db = new PDO($dsn,$conf['user'],$conf['pwd']); $this->db->query('set names '.$conf['charset']); $this->getTable();//获取表明 $this->parseFields(); } //获取 model名,利用model名得到数据库表名 public function getTable(){ $classname = get_called_class(); $this->table = strtolower(substr($classname,0,-5)); //截取后转小写 } //分析数据表,得到表的基本信息 public function parseFields(){ $sql = 'desc '.$this->table; $tableinfo = $this->db->query($sql); $data = $tableinfo->fetchAll(PDO::FETCH_ASSOC); foreach($data as $k=>$v){ $this->field[] = $v['Field']; if($v['Key']=='PRI'){ $this->pk = $v['Field']; } } } //查找单条数据 public function find($id){ $this->pk;$id;$this->field; $sql = 'select * from '.$this->table.' where '.$this->pk.'=? '; $stm = $this->db->prepare($sql); $stm->execute([$id]); $data = $stm->fetch(PDO::FETCH_ASSOC); return $data; }}
继续强化Model基类(查询)
/Care/Model.php
/* * 单条数据 * return array * */ public function getrow($sql,$parms=[]){ $stm = $this->db->prepare($sql); $stm->execute($parms); $data = $stm->fetch(PDO::FETCH_ASSOC); return $data; } /* * 多条数据 * return array * */ public function getrows($sql,$parms=[]){ $stm = $this->db->prepare($sql); $stm->execute($parms); $data = $stm->fetchAll(PDO::FETCH_ASSOC); return $data; } public function find($id){ $sql = 'select * from '.$this->table.' where '.$this->pk.'=? '; $data = $this->getrow($sql,[$id]); return $data; } public function select(){ $sql = 'select * from '.$this->table.' where id=? and age=? '; $data = $this->getrows($sql,[5,18]); return $data; }
继续强化Model基类(删除)
/Care/Model.php
/* * 删除数据 * return int * */ private function delete($sql,$parms=[]){ $stm = $this->db->prepare($sql); if($stm->execute($parms)){ $data = $stm->rowCount(); }else{ $data = $this->db->errorInfo(); } return $data; } //删除一条数据 public function remove($id){ $sql = 'delete from '.$this->table.' where '.$this->pk.'=?'; return $this->delete($sql,$id); }
继续强化Model基类(添加)
/Care/Model.php
/*执行添加操作*/ private function insert($sql,$parms=[]){ $stm = $this->db->prepare($sql); if($stm->execute($parms)){ $data = $this->db->lastInsertId(); }else{ $data = $this->db->errorInfo(); } return $data; } //添加数据 public function add($data=[]){ $sql = 'insert into '.$this->table .' ('; $sql .= implode(',',array_keys($data)); $sql .= ') values ('; $sql .= substr(str_repeat('?,',count($data)),0,-1).')'; return $this->insert($sql,array_values($data)); }
继续强化Model基类(修改)
/Care/Model.php
//修改操作 public function update($sql,$parms=[]){ $stm = $this->db->prepare($sql); if($stm->execute($parms)){ $conut = $stm->rowCount(); return $conut; }else{ return $this->db->errorInfo(); } } public function save($data=[]){ if(!isset($data[$this->pk])){ throw new Exception('缺少主键',500); } $data_tmp = $data; unset($data_tmp[$this->pk]); $sql = 'update '.$this->table.' set '; foreach($data_tmp as $k=>$v){ $sql .= $k .'= ? ,'; } $sql = substr($sql,0,-1); $sql .= ' where '.$this->pk .'=?'; $data_tmp[$this->pk] = $data[$this->pk]; return $this->update($sql,array_values($data_tmp)); }
魔术方法复习
class T{ //在给不可访问属性赋值时,__set() 会被调用。 //读取不可访问属性的值时,__get() 会被调用。 public function __set($name, $value) { echo $name.'-----'.$value; } public function __get($name) { echo $name; } //在对象中调用一个不可访问方法时,__call() 会被调用。 //用静态方式中调用一个不可访问方法时,__callStatic() 会被调用。 public function __call($name, $arguments) { echo $name.'-------'; var_dump($arguments); } //本身必须是静态 public static function __callStatic($name, $arguments) { echo $name.'-------'; var_dump($arguments); }}$t = new T();$t->name;$t->age = '34';$t->dd('22','44');T::a('1','2');
利用魔术方法,实现类似TP的属性赋值
ThinkPHP/Library/Think/Model.class.php
class T{ private $data = []; public function __set($name, $value) { $this->data[$name] = $value; } public function __get($name) { return isset($this->data[$name])?$this->data[$name]:null; }}$t = new T();//$t->name;$t->age = '34';$t->name = '苍井空';var_dump($t);echo $t->name;
将添加操作修改为ORM方式
/Care/Model.php
//ORM 操作 private $data = []; public function __set($name, $value) { $this->data[$name] = $value; } public function __get($name) { return isset($this->data[$name])?$this->data[$name]:null; } //添加数据 public function add($data=[]){ if(empty($data)){ $data = $this->data; //避免属性值残留 $this->data = []; } $sql = 'insert into '.$this->table .' ('; $sql .= implode(',',array_keys($data)); $sql .= ') values ('; $sql .= substr(str_repeat('?,',count($data)),0,-1).')'; return $this->insert($sql,array_values($data)); }
将修改操作修改为ORM方式
/Care/Model.php
//查找单条数据 public function find($id){ $sql = 'select * from '.$this->table.' where '.$this->pk.'=? '; $data = $this->getrow($sql,[$id]); //属性赋值 $this->data = $data; return $data; } //添加判断 public function save($data=[]){ if(empty($data)){ $data = $this->data; $this->data = []; } if(!isset($data[$this->pk])){ throw new Exception('缺少主键',500); } $data_tmp = $data; unset($data_tmp[$this->pk]); $sql = 'update '.$this->table.' set '; foreach($data_tmp as $k=>$v){ $sql .= $k .'= ? ,'; } $sql = substr($sql,0,-1); $sql .= ' where '.$this->pk .'=?'; $data_tmp[$this->pk] = $data[$this->pk]; return $this->update($sql,array_values($data_tmp)); }
/xm/Controller/indexController.class.php
class indexController extends Controller{ public function index(){ $model = new pdoModel(); $model->find(4); $model->age = $model->age+1; $model->name = 'liya'; echo $model->save(); }}
自己去想能不能将查询删除操作修改为ORM的方式
能:怎么写?
不能:为什么?
field()、where()等方法
- field()
- where()
- group()
- having()
- order()
- limit()
一个select 查询一般有:
select 列1,列2,…列N from 表名 where xxx group by xxx having xxx order xxx limit xxx
为select 添加field()方法
/Care/Model.php
//查询多条数据 public function select(){ $sql = 'select '. $this->option['op'] .' from '.$this->table; $data = $this->getrows($sql); return $data; } /* * field * */ private $option = [ 'op'=>' * ', ]; public function field($option){ if(!empty($option)){ $this->option['op'] = $option; } return $this; }
多种方式测试
/xm/Controller/indexController.class.php
$model = new pdoModel();// $model->field('name');// var_dump($model->select());// var_dump($model->field()->select()); var_dump($model->field('name,age')->select());
为select添加where()方法
/Care/Model.php
private $option = [ 'field'=>' * ', 'where'=> '1', 'v'=>[], ]; public function where($where){ if(!empty($where)){; $where_o = ''; foreach($where as $k=>$v){ $where_o .= ' '.$k.'=? and'; $this->option['v'][] = $v; } $where_o = rtrim($where_o,'and'); $this->option['where'] = $where_o; }else{ $this->option['where'] = 1; } return $this; }
/xm/Controller/indexController.class.php
public function up(){ $pdoMode = new pdoModel();// ->where(['name'=>'cangoshi']) $pdo = $pdoMode->field('name,age')->select(); var_dump($pdo); }
group()、having()、order()、limit()自己尝试写出来
超简单的View层实现
X/lib/Controller.php
class Controller{ private $data = array(); public function copm($file){ $html = file_get_contents($file); $html = str_replace('{$',"<?php echo \$this->data['",$html); $html = str_replace('}',"'];?>",$html); $file_tmp = $file.'.php'; file_put_contents($file_tmp,$html); return $file_tmp; } public function assign($k,$v){ $this->data[$k] = $v; } public function display($file){ $tmp = $this->copm(APP_PATH.'View/'.$file); include($tmp); }}
book/Controller/userController.class.php
public function up(){ $a = 'add'; $this->assign('a',$a); $this->display('a.html');}
book/View/a.html
<body>{$a}</body>
添加工具类
文件上传
X/Tool/Upload.php
class Upload{ public $file = []; public $name = ''; public $dir = ''; public $ext = ''; public function up($name){ if(!isset($_FILES[$name])){ echo 'cuo'; } if($_FILES[$name]['error'] !==0){ echo false; }else{ $this->file = $_FILES[$name]; } $this->createDir(); if(move_uploaded_file($this->file['tmp_name'],$this->dir.'/'.$this->createName().'.'.$this->getExt())){ return [ 'url' => $this->dir.'/'.$this->name.'.'.$this->ext, 'ext' => $this->ext, ]; }else{ return false; } } //创建目录 public function createDir(){ $this->dir = APP_PATH.'upload/'.date('Y-m-d',time()); $path = $this->dir; if(is_dir(($path)) || mkdir($path,0777,true)){ return $this->dir; }else{ throw new Exception('lksdf',90000); } } //获取文件后缀 public function getExt(){ $ext = explode('.',$this->file['name']); return $this->ext = strtolower(end($ext)); } //生成文件名 public function createName($len = 4){ $all = 'abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ123456789'; $str = substr(str_shuffle($all),0,$len); return $this->name = time().$str; } //检查是否允许上传 // 检查文件上传大小}
book/Controller/userController.class.php
public function up(){ if(empty($_FILES)){ $this->display('up.html'); }else { $up = new Upload();// var_dump($_FILES);exit(); var_dump($up->up('pic')); } }
book/View/up.html
<body><form action="" method="post" enctype="multipart/form-data"> <!--<p><input type="text" name="po"></p>--> <p><input type="file" name="pic"></p> <p><input type="submit" value="提交" ></p></form></body>
- 搭建自己的MVC框架
- mvc框架自己搭建
- 使用PHP搭建自己的MVC框架
- 使用PHP搭建自己的MVC框架
- 使用PHP搭建自己的MVC框架
- 使用PHP搭建自己的MVC框架
- 使用php搭建自己的MVC框架
- 使用PHP搭建自己的MVC框架
- 使用PHP搭建自己的MVC框架
- 使用PHP搭建自己的MVC框架
- PHP搭建自己的MVC框架 1
- PHP搭建自己的MVC框架 2
- PHP搭建自己的MVC框架3 入口文件
- PHP搭建自己的MVC框架4 类自动加载
- PHP搭建自己的MVC框架5 路由类
- PHP搭建自己的MVC框架6 控制器
- PHP搭建自己的MVC框架7 模型层
- PHP搭建自己的MVC框架8 视图层
- android学习笔记之-xml pull解析
- Light OJ 1188 Fast Queries(离线树状数组||莫队算法)
- nodejsPath
- uva10453
- Delete Last Element
- 搭建自己的MVC框架
- 杨鑫的C++上机报告
- [GDKOI2016]魔卡少女
- win8.1系统中Sybase PowerBuilder已停止工作的有效解决办法
- mysql 常见错误:Can't create table... errno150原因分析
- PAT-A1009 Product of Polynomials (25)(模拟)
- Mac的MySQL无法启动的原因
- 基数排序
- 【BZOJ3122】【SDOI2013】随机数生成器(快速幂+BSGS)