这篇就晒晒代码,从入口文件开始。
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);
}
}
}
如此,就实现了基本的框架结构。
833

被折叠的 条评论
为什么被折叠?



