自定义php框架(篇二)

这篇就晒晒代码,从入口文件开始。

index.php内容如下:

<?php
    //入口文件
    $arr=explode('?',$_SERVER['REQUEST_URI']);
    //区分是实例化控制器还是渲染页面加载css,js文件
    if(count($arr)==1)//加载css,js文件
    {
        $src_js_css=explode('index.php/',$arr[0]);
        include $src_js_css[1];
        exit();
    }
//导入需要加载的文件
    require_once 'start/define.php';
    require_once 'start/Autoload.php';
    require_once 'myclass/MyLog.php';
    require_once 'start/search.php';

依次下面展示导入的文件:

defined.php:

<?php
//$module是app下的模块名,即index或admin
    $arr=explode('?',$_SERVER['REQUEST_URI']);
    $arr2=explode('/',$arr[0]);
    $module=$arr2[count($arr2)-1];
//定义文件夹常量
define('MVC_PATH',str_replace('\\','/',dirname($_SERVER["SCRIPT_FILENAME"])));//$_SERVER['SCRIPT_FILENAME']引用当前脚本的路径,这里是入口文件
define('APP_PATH',MVC_PATH.'/app');
define('MD_PATH',APP_PATH.'/'.$module);
define('APP_CONTROLLER',MD_PATH.'/controller');
define('APP_VIEW',MD_PATH.'/view');
define('APP_MODEL',MD_PATH.'/model');
define('CLASS_PATH',MVC_PATH.'/myclass');
define('START_PATH',MVC_PATH.'/start');
define('SRC_PATH',MVC_PATH.'/src');
define('LOG_PATH',MVC_PATH.'/log');
define('TEMPORARY_PATH',MVC_PATH.'/temporary');
define('CONFIG_PATH',MVC_PATH.'/config');
define('IS_POST',($_SERVER['REQUEST_METHOD']=='POST')?true:false);
define('FRAME_VERSION', '1.1.0'); //框架版本
date_default_timezone_set('Asia/Shanghai'); //设置默认时区

AutoLoad.php:

<?php
/**自动加载类,该类的作用是找不到的类会通过该类找到,但要先实例化自身*/
namespace start;
class Autoload
{
    private static $instance;

    static function getInstance()
    {
        if(!self::$instance)
        {
            self::$instance=new self();
        }
        return self::$instance;
    }
    private function __construct()
    {
        spl_autoload_register([$this,'autoload']);
    }

    function autoload($className)
    {//echo $className;
        $pos=strrpos($className,'\\');//查找最后一个符合条件的对象
        $spaceName=substr($className,0,$pos);
        $name=substr($className,$pos+1);
        $this->mapLoad($spaceName,$name);
    }

    protected function mapLoad($spaceName,$name)
    {
        $path_pre=rtrim(str_replace("\\","/",$spaceName),"/")."/";
        $path_shu=$name.'.php';
        $path=$path_pre.$path_shu;
        if(file_exists($path))
        {
            include $path;
            echo 'o.o';
        }else{
            include CLASS_PATH.'/EmptyController.php';
            \myclass\EmptyController::tellPeople();
        }

    }
}

Mylog.php:

<?php
/**
 * Created by PhpStorm.
 * User: 15961
 * Date: 2018/10/15
 * Time: 18:58
 */

namespace myclass;


class Log
{
    static function write_log($msg)
    {
         $log_name=MVC_PATH.'/log/'.date('Y-m-d').'.txt';
         $mylog=fopen($log_name,'a') or die('日记写入失败');
         fwrite($mylog,$msg);
         fclose($mylog);
    }
}

search/php:

<?php
//实例化自动加载类
    $auto=start\Autoload::getInstance();
    //获取当前访问的url问号之后的部分
    $param=$_SERVER['QUERY_STRING'];
    $params=explode('&',$param);
    $_SESSION['url_now']=$params[0].'&'.$params[1];
    //判断是否登陆
    if(empty($_SESSION['user']['id']) &&  $_SESSION['url_now']!='m=login&a=index' &&  $_SESSION['url_now']!='m=login&a=dologin'){
        echo '<script>location.href ="'.$module.'?m=login&a=index"</script>';
        exit();
    }
    //获取控制器和方法
    !$_REQUEST['m']?$m='login':$m=$_REQUEST['m'];
    $m=ucfirst(strtolower($m));//首字母大写
    !$_REQUEST['a']? $a='index':$a=$_REQUEST['a'];
    $controller='app\\'.$module.'\controller'.'\\'.$m;//echo $controller;
    //日志
    $frameConfig=CONFIG_PATH.'/frameConfig.php';
    $mdConfig=CONFIG_PATH.'/'.$module.'Config.php';
    file_exists($mdConfig)?$config=array_merge(require_once $frameConfig,require_once $mdConfig):$config=require_once $frameConfig;
    if($config['DO_LOG'])
      myclass\Log::write_log(date('Y-m-d H:i:s').':'.'m='.$m.'&a='.$a."\r\n");
    //调用控制器和方法
    $obj=new $controller();
    call_user_func([$obj,$a]);//调用一个类里面的方法

 

有了以上这些,框架就可以通过url找到对应的控制器和函数了。要想执行相应的操作,就需要控制器类和视图类了。

Controller.php:

<?php
/**
 * Created by PhpStorm.
 * User: 15961
 * Date: 2018/10/10
 * Time: 14:16
 */
namespace myclass;

use myclass\Log;
use myclass\View;

class Controller
{
    protected $data=[];
    protected static $model;
    protected static $view;
    function __construct()
    {
        $this->controllerInit();
        $this->beforeAction();
        self::$view=View::getInstance();
    }
    //初始化
    public function controllerInit()
    {

    }
    //前置操作
    public function beforeAction()
    {

    }
    public function write_log($msg)
    {
        Log::write_log($msg);
    }


    function p($var)//打印函数
    {
        if(is_bool($var) || is_null($var) || is_array($var))
        {
            var_dump($var);
        }else{
            echo $var;
        }
    }
    //跳转函数,可以带参param,time为暂缓跳转时间
     function go($controller=null,$action=null,$param=[],$time=0)
    {
        if(!$controller || !$action)
        {
            echo '控制器或页面不存在';
            exit();
        }
        $par='';
        if(count($param)>0)
        {
            foreach ($param as $key=>$val)
            {
                $par.='&'.$key.'='.$val;
            }
        }
        if($time>0)
            sleep($time);
        header('location:?m='.$controller.'&a='.$action.$par);
    }

    protected function fetch($view=null)
    {
        self::$view->fetch($view);
    }
    protected function assign($key,$val)
    {
        self::$view->assign($key,$val);
    }
}

其他类可以通过继承来继承属性和方法。

View.php:

<?php
/**
 * Created by PhpStorm.
 * User: 15961
 * Date: 2018/10/18
 * Time: 11:55
 */

namespace myclass;


class View
{
    //模板实例
    protected static $instance;
    // 模板变量
    protected $data = [];
    // 视图输出替换
    protected $replace = [];

    protected function __construct()
    {

    }

    public static function getInstance()
    {
        if(!isset(self::$instance))
        {
            return self::$instance=new self();
        }
        return self::$instance;
    }

    protected function display()
    {

    }

    //模板渲染
    function fetch($view=null)
    {
        if(isset($_SESSION['user']))
        {//判断访问权限
            $id=$_SESSION['user']['id'];
            $arr_url=['m=page&a=login','m=page&a=home','m=page&a=index','m=login&a=loginout','m=menu&a=elements','m=menu&a=chart','m=menu&a=index','m=index&a=index','m=login&a=index','m=user&a=add','m=user&a=edit'];
            if((!in_array($_SESSION['url_now'],$_SESSION['url'])) && (!in_array($_SESSION['url_now'],$arr_url)))
            {
                header('location:admin?m=index&a=index&uid='.$id);
            }
        }/*else if(!($_REQUEST['m']=='login' && $_REQUEST['a']=='index')){
            header('location:admin?m=login&a=index');
        }*/
        //视图模板加载变量
        extract($this->data);
        //找到路径
        $controller=$_REQUEST['m'];
        $action=$_REQUEST['a'];
        if(!isset($view))
        {
            $file=APP_VIEW.'/'.strtolower($controller).'/'.strtolower($action).'.html';
        }else{
            $arr=explode('.',$view);
            if(count($arr)>1)
            {
                $file=APP_VIEW.'/'.strtolower($controller).'/'.strtolower($view);
            }else{
                $file=APP_VIEW.'/'.strtolower($controller).'/'.strtolower($view).'.html';
            }
        }

        //获取模板源文件,用来替换
        $template_content = file_get_contents($file);
        $pattern = array(
            '/\{\s*\$([a-zA-Z][a-zA-Z0-9_]*)\s*\}/i'
        );
        $replace = array(
            '<?php echo $this->data["${1}"]; ?>'
        );
        //用正则去替换模板源文件中的变量符号
        $res = preg_replace($pattern,$replace,$template_content);
        //编译后文件写入某个目录
        $template_c_path=TEMPORARY_PATH.'/temporary.txt';
        file_put_contents($template_c_path,$res);
        //加载新模板
        include $template_c_path;

    }

    function assign($key,$val)
    {
        if(is_string($key))
        {
            $this->data[$key]=$val;
        }else if(is_array($key)){
            $this->data=array_merge($this->data,$key);
        }

    }

    protected function config()
    {

    }

    public function __set($name, $value)
    {
        $this->data[$name]=$value;
    }

    public function __get($name)
    {
        return $this->data[$name];
    }

    public function __isset($name)
    {
        return isset($this->data[$name]);
    }
}

已经可以展示登陆页面了,为了登录,还需要连接数据库,模型基类DbModel.php如下:

<?php
/**
 * Created by PhpStorm.
 * User: 15961
 * Date: 2018/10/11
 * Time: 18:25
 */

namespace myclass;
class DbModel
{
    protected $host;
    protected $username;
    protected $password;
    protected $dbname;
    protected $charset;
    protected $prefix;
    protected static $config;
    public $link;//连接资源
    protected $tableName;//默认表名,不带前缀
    protected $sql;
    protected $options;//操作数组  所有的查询条件

    protected static $instance;
    static function getInstance()
    {
        self::$config=include 'config/dbConfig.php';
        if(!(self::$instance instanceof self))
        {
            return self::$instance=new self(self::$config);
        }
        return self::$instance;
    }
    private function __construct($config)
    {
        $this->host = $config['host'];
        $this->username = $config['username'];
        $this->password = $config['password'];
        $this->dbname = $config['dbname'];
        $this->charset = $config['charset'];
        $this->prefix = $config['prefix'];
        //连接数据库
        $this->link = $this->connect();
        //初始化操作数组
        $this->initOptions();
    }
    protected function connect()
    {
        $link=mysqli_connect($this->host,$this->username,$this->password);
        if(!$link)
        {
            die('数据库连接失败!');
        }
        //设置数据库名
        $link->select_db($this->dbname);
        //设置字符
        $link->set_charset($this->charset);
        return $link;
    }


    protected function initOptions()
    {
        $arr=['table','field','where','limit','order','having','group'];
        foreach ($arr as $value)
        {
            $this->options[$value]='';
            if($value=='table')
            {
                $this->options['table']=$this->tableName;
            }
        }
    }

    public function table($table)
    {
        if($table)
        {
            $this->options['table']=$this->prefix.$table;
            $this->tableName=$this->prefix.$table;
        }
        return $this;
    }

    function field($field)
    {
        if($field)
        {
            if(is_string($field))
            {
                $this->options['field']=$field;
            }else if(is_array($field))
            {
                $this->options['field']=join(',',$field);
            }

        }
        return $this;
    }

    function where($where)
    {
        if($where)
        {
            if(is_string($where))
            {
                $this->options['where']=' where '.$where;
            }

        }
        return $this;
    }

    function limit($limit)
    {
        if($limit)
        {
            if(is_string($limit))
            {
                $this->options['limit']=' limit '.$limit;
            }else if(is_array($limit))
            {
                $this->options['limit']=' limit '.join(',',$limit);
            }

        }
        return $this;
    }

    function group($group)
    {
        if(!empty($group))
        {
            $this->options['group']=' group by '.$group;
        }
        return $this;
    }

    function order($order)
    {
        if(is_string($order))
        {
            $this->options['order']=' order by '.$order;
        }else if(is_array($order))
        {
            $this->options['order']=' order by '.$order[0].' '.$order[1];
        }


        return $this;
    }

    function having($having)
    {
        if(!empty($having))
        {
            $this->options['having']=' having '.$having;
        }
        return $this;
    }

    function select()
    {
        $sql="select ".$this->options['field']." from ".$this->options['table'].$this->options['where'];
        $sql.=$this->options['group'].$this->options['having'].$this->options['order'];
        $sql.=$this->options['limit'];
        $this->sql=$sql;
        $this->initOptions();
        $result=mysqli_query($this->link,$sql);
        if($result && mysqli_affected_rows($this->link))
        {
            $data=[];
            while($res=mysqli_fetch_assoc($result))
            {
                $data[]=$res;
            }
            return $data;
        }
    }

    function __get($name)
    {
        if($name=='sql')
        {
            return $this->sql;
        }
    }

    function query($sql)
    {
        $this->initOptions();
        $result=mysqli_query($this->link,$sql);
        if($result && mysqli_affected_rows($this->link))
        {
            $data=[];
            while($res=mysqli_fetch_assoc($result))
            {
                $data[]=$res;
            }
            return json_encode($data);
        }
    }

    function exec($sql,$isInsert=false)
    {
        $this->initOptions();
        $this->sql=$sql;
        $result=mysqli_query($this->link,$sql);
        if($result && mysqli_affected_rows($this->link))
        {
            if($isInsert)
            {
                return mysqli_insert_id($this->link);
            }else
            {
                return mysqli_affected_rows($this->link);
            }
        }else{
            return false;
        }
    }

    function insert($data)
    {
        if(is_array($data))
        {   //处理数组中的数值为字符串的字段
            $data=$this->parseValue($data);
            $keys=array_keys($data);
            $values=array_values($data);
            $sql="insert into ".$this->tableName." (".join(',',$keys)." ) values(".join(',',$values).")";
            return $this->exec($sql,true);
        }
    }

    protected function parseValue($data)
    {
        foreach($data as $key=>$val)
        {
            if(is_string($val))
            {
                $data[$key]="'".$val."'";
            }
        }
        return $data;
    }
    function update($data)
    {   if(is_array($data))
        {
            $data=$this->parseValue($data);
            $new_data=[];
            foreach ($data as $k=>$v)
            {   if($k=='id')
            {
                $id=$v;
            }else{
                $new_data[]=$k.'='.$v;
            }
            }
            $sql="update ".$this->tableName." set ".join(',',$new_data)." where id=".$id;
            $this->exec($sql);
        }

    }

    function delete($id)
    {
        $sql="delete from ".$this->tableName." where id=".$id;
        $this->exec($sql);
    }

    function max($field)
    {
        if($field)
        {
            $this->options['field']=" max(".$field.") as max  ";
        }
        return $this;
    }

    function __destruct()
    {
        $this->link=null;
    }

    function __call($name, $arguments)
    {
        $str=substr(strtolower($name),0,5);
        $field=substr(strtolower($name),5);
        if($str=='getby')
        {
            $result=$this->query("select ".$field." from ".$this->tableName);
            return json_encode($result);
        }
    }
}

如此,就实现了基本的框架结构。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值