- GitHub地址:
https://github.com/wing1377/PHP-
入口文件
# index.php
<?php
require './Framework/Core/Framework.class.php';
Framework::run();
?>
框架文件
# Framework/Core/Framework.class.php
<?php
class Framework{
//启动框架
public static function run(){
self::initConst();
self::initConfig();
self::initRoutes();
self::initAutoLoad();
self::initDispatch();
}
//定义路径常量
private static function initConst(){
define('DS', DIRECTORY_SEPARATOR); //定义目录分隔符
define('ROOT_PATH', getcwd().DS); //入口文件所在的目录
define('APP_PATH', ROOT_PATH.'Application'.DS); //application目录
define('CONFIG_PATH', APP_PATH.'Config'.DS);
define('CONTROLLER_PATH', APP_PATH.'Controller'.DS);
define('MODEL_PATH', APP_PATH.'Model'.DS);
define('VIEW_PATH', APP_PATH.'View'.DS);
define('FRAMEWORK_PATH', ROOT_PATH.'Framework'.DS);
define('CORE_PATH', FRAMEWORK_PATH.'Core'.DS);
define('LIB_PATH', FRAMEWORK_PATH.'Lib'.DS);
define('TRAITS_PATH', ROOT_PATH.'Traits'.DS);
}
//引入配置文件
private static function initConfig(){
$GLOBALS['config']=require CONFIG_PATH.'config.php';
}
//确定路由
private static function initRoutes(){
$p=$_GET['p']??$GLOBALS['config']['app']['dp'];
$c=$_GET['c']??$GLOBALS['config']['app']['dc'];
$a=$_GET['a']??$GLOBALS['config']['app']['da'];
$p=ucfirst(strtolower($p));
$c=ucfirst(strtolower($c)); //首字母大写
$a=strtolower($a); //转成小写
define('PLATFROM_NAME', $p); //平台名常量
define('CONTROLLER_NAME', $c); //控制器名常量
define('ACTION_NAME', $a); //方法名常量
define('__URL__', CONTROLLER_PATH.$p.DS); //当前请求控制器的目录地址
define('__VIEW__',VIEW_PATH.$p.DS); //当前视图的目录地址
}
//自动加载类
private static function initAutoLoad(){
spl_autoload_register(function($class_name){
$namespace= dirname($class_name); //命名空间
$class_name= basename($class_name); //类名
if(in_array($namespace, array('Core','Lib'))) //命名空间在Core和Lib下
$path= FRAMEWORK_PATH.$namespace.DS.$class_name.'.class.php';
elseif($namespace=='Model') //文件在Model下
$path=MODEL_PATH.$class_name.'.class.php';
elseif($namespace=='Traits') //文件在Traits下
$path=TRAITS_PATH.$class_name.'.class.php';
else //控制器
$path=CONTROLLER_PATH.PLATFROM_NAME.DS.$class_name.'.class.php';
if(file_exists($path) && is_file($path))
require $path;
});
}
//请求分发
private static function initDispatch(){
$controller_name='Controller\'.PLATFROM_NAME.'\'.CONTROLLER_NAME.'Controller'; //拼接控制器类名
$action_name=ACTION_NAME.'Action'; //拼接方法名
$obj=new $controller_name();
$obj->$action_name();
}
}
?>
配置文件
# Application/Config/config.php
<?php
return array(
//数据库配置
'database'=>array(),
//应用程序配置
'app'=>array(
'dp' => 'Admin', //默认平台
'dc' => 'Products', //默认控制器
'da' => 'list' //默认方法
)
);
?>
基础模型
# Framework/Core/Model.class.php
<?php
namespace Core;
//基础模型
class Model {
protected $mypdo;
private $table; //表名
private $pk; //主键
public function __construct($table=''){
$this->initMyPDO();
$this->initTable($table);
$this->getPrimaryKey();
}
//连接数据库
private function initMyPDO() {
$this->mypdo= MyPDO::getInstance($GLOBALS['config']['database']);
}
//获取表名
private function initTable($table){
if($table!='') //直接给基础模型传递表名
$this->table=$table;
else { //实例化子类模型
$this->table=substr(basename(get_class($this)),0,-5);
}
}
//获取主键
private function getPrimaryKey() {
$rs=$this->mypdo->fetchAll("desc `{$this->table}`");
foreach($rs as $rows){
if($rows['Key']=='PRI'){
$this->pk=$rows['Field'];
break;
}
}
}
//万能的插入
public function insert($data){
$keys=array_keys($data); //获取所有的字段名
$keys=array_map(function($key){ //在所有的字段名上添加反引号
return "`{$key}`";
},$keys);
$keys=implode(',',$keys); //字段名用逗号连接起来
$values=array_values($data); //获取所有的值
$values=array_map(function($value){ //所有的值上添加单引号
return "'{$value}'";
},$values);
$values=implode(',',$values); //值通过逗号连接起来
$sql="insert into `{$this->table}` ($keys) values ($values)";
return $this->mypdo->exec($sql);
}
//万能的更新
public function update($data){
$keys=array_keys($data); //获取所有键
$index=array_search($this->pk,$keys); //返回主键在数组中的下标
unset($keys[$index]); //删除主键
$keys=array_map(function($key) use ($data){
return "`{$key}`='{$data[$key]}'";
},$keys);
$keys=implode(',',$keys);
$sql="update `{$this->table}` set $keys where $this->pk='{$data[$this->pk]}'";
return $this->mypdo->exec($sql);
}
//删除
public function delete($id){
$sql="delete from `{$this->table}` where `{$this->pk}`='$id'";
return $this->mypdo->exec($sql);
}
//查询,返回二维数组
public function select($cond=array()){
$sql="select * from `{$this->table}` where 1";
if(!empty($cond)){
foreach($cond as $k=>$v){
if(is_array($v)){ //条件的值是数组类型
switch($v[0]){ //$v[0]保存的是符号,$v[1]是值
case 'eq': //等于 equal
$op='=';
break;
case 'gt': //大于 greater than
$op='>';
break;
case 'lt':
$op='<';
break;
case 'gte':
case 'egt':
$op='>=';
break;
case 'lte':
case 'elt':
$op='<=';
break;
case 'neq':
$op='<>';
break;
}
$sql.=" and `$k` $op '$v[1]'";
}else{
$sql.=" and `$k`='$v'";
}
}
}
return $this->mypdo->fetchAll($sql);
}
//查询,返回一维数组
public function find($id){
$sql="select * from `{$this->table}` where `{$this->pk}`='$id'";
return $this->mypdo->fetchRow($sql);
}
}
?>
连接PDO数据库
# Framework/Core/MyPDO.class.php
<?php
namespace Core;
class MyPDO{
private $type; //数据库类别
private $host; //主机地址
private $port; //端口号
private $dbname; //数据库名
private $charset; //字符集
private $user; //用户名
private $pwd; //密码
private $pdo; //保存PDO对象
private static $instance;
private function __construct($param) {
$this->initParam($param);
$this->initPDO();
$this->initException();
}
private function __clone() {
}
public static function getInstance($param=array()){
if(!self::$instance instanceof self)
self::$instance=new self($param);
return self::$instance;
}
//初始化参数
private function initParam($param){
$this->type=$param['type']??'mysql';
$this->host=$param['host']??'127.0.0.1';
$this->port=$param['port']??'3306';
$this->dbname=$param['dbname']??'data';
$this->charset=$param['charset']??'utf8';
$this->user=$param['user']??'root';
$this->pwd=$param['pwd']??'';
}
//初始化PDO
private function initPDO(){
try{
$dsn="{$this->type}:host={$this->host};port={$this->port};dbname={$this->dbname};charset={$this->charset}";
$this->pdo=new PDO($dsn, $this->user, $this->pwd);
} catch (PDOException $ex) {
$this->showException($ex);
exit;
}
}
//显示异常
private function showException($ex,$sql=''){
if($sql!=''){
echo 'SQL语句执行失败<br>';
echo '错误的SQL语句是:'.$sql,'<br>';
}
echo '错误编号:'.$ex->getCode(),'<br>';
echo '错误行号:'.$ex->getLine(),'<br>';
echo '错误文件:'.$ex->getFile(),'<br>';
echo '错误信息:'.$ex->getMessage(),'<br>';
}
//设置异常模式
private function initException(){
$this->pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
}
//执行增、删、改操作
public function exec($sql){
try{
return $this->pdo->exec($sql);
} catch (PDOException $ex) {
$this->showException($ex, $sql);
exit;
}
}
//获取自动增长的编号
public function lastInsertId(){
return $this->pdo->lastInsertId();
}
//判断匹配的类型
private function fetchType($type){
switch ($type){
case 'num':
return PDO::FETCH_NUM;
case 'both':
return PDO::FETCH_BOTH;
case 'obj':
return PDO::FETCH_OBJ;
default:
return PDO::FETCH_ASSOC;
}
}
//获取所有数据 ,返回二维数组
public function fetchAll($sql,$type='assoc'){
try{
$stmt=$this->pdo->query($sql); //获取PDOStatement对象
$type= $this->fetchType($type); //获取匹配方法
return $stmt->fetchAll($type);
} catch (Exception $ex) {
$this->showException($ex, $sql);
}
}
//获取一维数组
public function fetchRow($sql,$type='assoc'){
try{
$stmt=$this->pdo->query($sql); //获取PDOStatement对象
$type= $this->fetchType($type); //获取匹配方法
return $stmt->fetch($type);
} catch (Exception $ex) {
$this->showException($ex, $sql);
exit;
}
}
//返回一行一列
public function fetchColumn($sql){
try{
$stmt=$this->pdo->query($sql);
return $stmt->fetchColumn();
} catch (Exception $ex) {
$this->showException($ex, $sql);
exit;
}
}
}
?>
子模型
# Application/Model/ProductsModel.class.php
<?php
namespace Model;
//products模型用来操作products表
class ProductsModel extends CoreModel{
}
?>
子控制器
# Application/Controller/Admin/ProductsController.class.php
<?php
namespace ControllerAdmin;
// 商品模块
use CoreController; //引入基础控制器
class ProductsController extends CoreController {
use TraitsJump;
// 获取商品列表
public function listAction(){
// 实例化数据模型
$model= new ModelProductsModel();
$list= $model->select();
// 加载视图
require __VIEW__.'products_list.html';
}
public function delAction(){
$id= (int)$_GET['proid'];
$model= new ModelProductsModel();
if($model->delete($id)){
$this->success('index.php?p=Admin&c=Products&a=list', '删除成功');
}else{
$this->error('index.php?p=admin&c=Products&a=list', '删除失败');
}
}
public function addAction(){
//执行添加逻辑
if(!empty($_POST)){
$model=new CoreModel('products');
if($model->insert($_POST))
$this->success ('index.php?p=Admin&c=Products&a=list', '插入成功');
else
$this->error ('index.php?p=Admin&c=Products&a=add', '插入失败');
}
//显示添加页面
require __VIEW__.'products_add.html';
}
public function editAction(){
$proid=$_GET['proid']; //需要修改的商品id
$model=new CoreModel('products');
//执行修改逻辑
if(!empty($_POST)){
$_POST['proID']=$proid;
if($model->update($_POST))
$this->success ('index.php?p=Admin&c=Products&a=list', '修改成功');
else
$this->error ('index.php?p=Admin&c=Products&a=edit&proid='.$proid, '修改失败');
}
//显示商品
$info= $model->find($proid);
require __VIEW__.'products_edit.html';
}
}
?>
商品视图
# Application/View/Admin/products_list.html
<!Doctype html>
<html>
<head>
<meta charset="utf-8">
<title>显示商品</title>
</head>
<body>
<table border='1' width='980' bordercolor='#000'>
<a href="index.php?p=Admin&c=Products&a=add">添加商品</a>
<tr>
<th>编号</th>
<th>名称</th>
<th>价格</th>
<th>删除</th>
<th>修改</th>
</tr>
<?php foreach($list as $rows):?>
<tr>
<td><?=$rows['proID']?></td>
<td><?=$rows['proname']?></td>
<td><?=$rows['proprice']?></td>
<td><a href="index.php?p=Admin&c=Products&a=del&proid=<?=$rows['proID']?>" onclick="return confirm('确定要删除吗')">删除</a></td>
<td><a href="index.php?p=Admin&c=Products&a=edit&proid=<?=$rows['proID']?>">修改</a></td>
</tr>
<?php endforeach;?>
</table>
</body>
</html>
添加视图
# Application/View/Admin/products_add.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>添加商品</title>
</head>
<body>
<form method="post" action="">
名称: <input type="text" name="proname"> <br />
价格: <input type="text" name="proprice"> <br />
<input type="submit" value="提交">
</form>
</body>
</html>
更新视图
# Application/View/Admin/products_edit.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form method="post" action="">
名称: <input type="text" name="proname" value='<?=$info['proname']?>'> <br />
价格: <input type="text" name="proprice" value='<?=$info['proprice']?>'> <br />
<!--
<input type="hidden" name="proID" value=<?=$info['proID']?>>
-->
<input type="submit" value="提交">
</form>
</body>
</html>
启动Session
# FrameworkLibSession.class.php
<?php
namespace Lib;
class Session{
private $mypdo;
public function __construct() {
session_set_save_handler(
[$this,'open'],
[$this,'close'],
[$this,'read'],
[$this,'write'],
[$this,'destroy'],
[$this,'gc']
);
session_start();
}
public function open() {
$this->mypdo= CoreMyPDO::getInstance($GLOBALS['config']['database']);
return true;
}
//关闭会话
public function close() {
return true;
}
//读取会话
public function read($sess_id) {
$sql="select sess_value from sess where sess_id='$sess_id'";
return (string)$this->mypdo->fetchColumn($sql);
}
//写入会话
public function write($sess_id,$sess_value) {
$sql="insert into sess values ('$sess_id','$sess_value',unix_timestamp()) on duplicate key update sess_value='$sess_value',sess_time=unix_timestamp()";
return $this->mypdo->exec($sql)!==false;
}
//销毁会话
public function destroy($sess_id) {
$sql="delete from sess where sess_id='$sess_id'";
return $this->mypdo->exec($sql)!==false;
}
//垃圾回收
public function gc($lifetime) {
$expires=time()-$lifetime; //过期时间点
$sql="delete from sess where sess_time<$expires";
return $this->mypdo->exec($sql)!==false;
}
}
?>
基础控制器
# FrameworkCoreController.class.php
<?php
//基础控制器
namespace Core;
class Controller{
public function __construct() {
$this->initSession();
}
//初始化session
private function initSession(){
new LibSession();
}
}
?>