搭建自己的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>
0 0
原创粉丝点击