我的简单PHP框架——LabPHP

2023-05-16

       就我上次提到的  基于MVC设计模式实现简单PHP框架(雏形)-初期 这次列出我实现的LabPHP简易框架,该框架中没有使用任何的模板引擎,所以说要在模板中使用到php变量的话,仍然需要用到php的标签和语法,输出显示变量。但是却大体实现了逻辑与界面的分离。

       该框架的简单同时也因此存在的许多的局限性,如目录结构不能轻易修改,当然除非修改框架内容,介于时间关系我也没有做过多的修改。

       LabPHP框架的目录结构如下:


       项目的目录结构如下:


       入口文件为 index.php

       URL模式为:

       http://serverName/index.php?m=模块名&c=控制器名&a=操作名

       默认模块为Home,默认控制器为Index,默认操作为index。如果需要访问非默认,需要传入参数。

        在Application文件夹可以有多个模块,这里只是列出了两个模块Home模块和Admin模块,默认模块为Home模块,也因为是默认模块,所以在访问非默认模块的情况下,需要在url中传入参数,如 index.php?m=Admin,表明是访问Admin模块的内容。

        当然我们可以添加更多的模块,需要注意的时,模块下的文件夹需要跟上图一致。其中Config.php文件内容为配置文件,Controller文件夹放置自定义的控制器,Model文件夹放置自定义的模型,View文件夹放置模板,其中View文件夹下先创建名为控制器名的文件夹,下面再放置模板。

        访问默认模块Home,入口文件index.php,结果如下:


       访问Admin模块,结果如下:


       LabPHP框架的函数库,如下:

       LabPHP/Common/functions.php

<?php 
	//防止非法字符的输入
	function daddslashes($str) {
		return (!get_magic_quotes_gpc())?addslashes($str):$str;
	}

	/**
	 * 获得当前被访问的模块名
	 * @return [type] 当前模块名
	 */
	function getModuleName() {
		return isset($_GET['m']) ? daddslashes($_GET['m']) : 'Home'; //初始化模块(默认Home模块)
	}

	/**
	 * 获得当前被访问的控制器名
	 * @return [type] 当前控制器名
	 */
	function getControllerName() {
		return isset($_GET['c']) ? daddslashes($_GET['c']) : 'Index'; //初始化控制器
	}

	/**
	 * 获得当前被访问的操作名
	 * @return [type] 当前操作名
	 */
	function getActionName() {
		return isset($_GET['a']) ? daddslashes($_GET['a']) : 'index'; //初始化操作
	}

	function getConfig() {
		$c1 = include('./LabPHP/Conf/convention.php');
		$c2 = include('./Application/' . MODULE_NAME . '/Config/config.php');

		$config = array_merge($c1, $c2);
		return $config;
	}

	/**
	 * 用于调用 $name 控制器的 $method 方法
	 * @param [type] $name   控制器名
	 * @param [type] $method 方法名
	 */
	function C($name, $method) {
		$m = getModuleName();
		require_once('./Application/' . $m . '/Controller/' . $name . 'Controller.class.php');
		$c = $name . 'Controller';
		$ct = new $c();
		$ct->$method();
	}

	/**
	 * 返回对应的Model对象
	 * @param [type] $name Model类的名
	 */
	function M($name) {
		$m = getModuleName();
		require_once('./Application/' . $m . '/Model/' . $name . 'Model.class.php');
		$model = $name.'Model';
		$obj = new $model();
		return $obj;
	}
?>
        LabPHP/Conf/convention.php

<?php 
	return array(
		/* 数据库设置 */
	    'DB_HOST'               =>  '', // 服务器地址
	    'DB_NAME'               =>  '',          // 数据库名
	    'DB_USER'               =>  '',      // 用户名
	    'DB_PWD'                =>  '',          // 密码
	    'DB_PORT'               =>  '',        // 端口

	    /* 模板设置 */
	    'TMPL_TEMPLATE_SUFFIX'  =>  '.html',     // 默认模板文件后缀
	);
?>
       LapPHP/Conf/include.list.php

<?php
	//定义需要提前引入的文件
	$paths = array(
			'Common/functions.php',                  //函数库
			'Libs/LabPHP.class.php',                 //启动引擎
			'Libs/Controller/Controller.class.php',  //基本控制器类
			'Libs/Model/SqlHelper.class.php',        //数据库操作类
			'Libs/Model/Model.class.php',            //基本模型类
		);
?>
       LabPHP/Libs/Controller/Controller.class.php

<?php 
	//基本控制器类 Controller.class.php
	class Controller {
		private static $tplPath = './Application/' . MODULE_NAME . '/View/'; //模板放置的路径
		private static $config; //用户配置+默认配置
		private static $tmpl_suffix; //模板的后缀名
		private $data = array(); //保存注册到模板上的变量

		/**
		 * 获取配置信息(用户配置+默认配置)、模板后缀名
		 */
		function __construct() {
			self::$config = getConfig();
			self::$tmpl_suffix = self::$config['TMPL_TEMPLATE_SUFFIX'];
		}

		/**
		 * 验证变量是否存在,是否为空
		 * @param  [type] $v [需要进行验证的变量]
		 * @return [type]    [true | false]
		 */
		function validate($v) {
			if(!isset($v) || empty($v)) return false;
			return true;
		}

		/**
		 * 重定向
		 * @param  [type] $url [重定向的URL地址,格式为 控制器名/方法名 ]
		 * @param  string $arg [重定向需要传递的参数]
		 * @return [type]      [description]
		 */
		function redirect($url, $arg = '') {
			$args = array();
			$args['m'] = MODULE_NAME != 'Home' ? 'm=' . MODULE_NAME : ''; //当前模块
			$arr = split('/', $url);
			$args['c'] = $arr[0] != 'Index' ? 'c=' . $arr[0] : ''; //控制器名
			$args['a'] = $arr[1] != 'index' ? 'a=' . $arr[1] : ''; //方法名
			$args['arg'] = $arg;

			$to = 'Location: index.php';
			$isFirst = true;
			foreach ($args as $key => $value) {
				if(!empty($value)) {
					if($isFirst) {
						$to .= '?' . $value;
						$isFirst = false;
					} else {
						$to .= '&' . $value;
					}
				}
			}

			header($to);
			exit;
		}

		/**
		 * 注册模板上的变量
		 * @param  [type] $key   [应用在模板上的变量名]
		 * @param  [type] $value [变量对应的值]
		 * @return [type]        [当前对象的引用,提供链式写法]
		 */
		function assign($key, $value) {
			$this->data[$key] = $value;
			return $this;
		}

		/**
		 * 显示page模板
		 * @param  [type] $page [模板的名称:控制器名/方法名(View文件夹下的 以控制器名为文件夹下 的 以方法名为文件名的模板)]
		 * @return [type]       [description]
		 */
		function display($page = CONTROLLER_NAME . '/' . ACTION_NAME) {
			if($this->validate($this->data)) {
				extract($this->data);
			}

			include_once(self::$tplPath . $page . self::$tmpl_suffix);
			//销毁注册过的变量
			if($this->validate($this->data)) {
				foreach ($this->data as $key => $value) {
					unset($$key);
				}
				$this->data = array();
			}

			exit;
		}
	}
?>
       LabPHP/Libs/Model/Model.class.php

<?php 
	//基本模型类 Model.class.php
	class Model {
		private $sqlHelper;

		function __construct() {
			$this->sqlHelper = new SqlHelper();
		}

		/**
		 * 验证变量是否存在,是否为空
		 * @param  [type] $v [需要进行验证的变量]
		 * @return [type]    [true | false]
		 */
		function validate($v) {
			if(!isset($v) || empty($v)) return false;
			return true;
		}

		/**
		 * 执行DQL语句(select语句)
		 * @param  [type] $sql SQL语句
		 * @return [type]      结果集
		 */
		function execute_dql_res($sql) {
			return $this->sqlHelper->execute_dql_res($sql);
		}

		/**
		 * 执行DQL语句(select语句)
		 * @param  [type] $sql SQL语句
		 * @return [type]      以关联数组的形式返回
		 */
		function execute_dql_arr($sql) {
			return $this->sqlHelper->execute_dql_arr($sql);
		}

		/**
		 * 执行DML语句(insert、update、delete语句)
		 * @param  [type] $sql SQL语句
		 * @return [type]      0表示失败;1表示成功;2表示没有行受影响
		 */
		function execute_dml($sql) {
			return $this->sqlHelper->execute_dml($sql);
		}
	}
?>
       LabPHP/Libs/Model/SqlHelper.class.php

<?php 
	//数据库操作类 SqlHelper.class.php
	class SqlHelper {
		private $mysqli;

		private $host; //数据库主机名
		private $user; //数据库用户名
		private $pwd; //数据库密码
		private $db; //数据库名
		private $port; //端口号


		public function __construct() {
			//完成初始化任务
			if(defined('SAE_MYSQL_DB')) { //判断是否是云平台
				$this->host = SAE_MYSQL_HOST_M;
				$this->user = SAE_MYSQL_USER;
				$this->pwd = SAE_MYSQL_PASS;
				$this->db = SAE_MYSQL_DB;
				$this->port = SAE_MYSQL_PORT;
			} else {
				$config = getConfig();
				$this->host = $config['DB_HOST'];
				$this->user = $config['DB_USER'];
				$this->pwd = $config['DB_PWD'];
				$this->port = $config['DB_PORT'];
				$this->db = $config['DB_NAME'];
			}

			$this->mysqli = new MySQLi($this->host, $this->user, $this->pwd, $this->db, $this->port);

			if($this->mysqli->connect_error) {
				die('连接失败 ' . $this->mysqli->connect_error);
			}
			//设置访问数据库的字符集
			//这句话的作用是保证php是以utf8的方式来操作我们的mysql数据库
			$this->mysqli->query("SET NAMES utf8") or die($this->mysqli->error);
		}

		/**
		 * 执行DQL语句(select语句)
		 * @param  [type] $sql SQL语句
		 * @return [type]      结果集
		 */
		public function execute_dql_res($sql) {
			$res = $this->mysqli->query($sql) or die('操作dql失败' . $this->mysqli->error);
			return $res;
		}

		/**
		 * 执行DQL语句(select语句)
		 * @param  [type] $sql SQL语句
		 * @return [type]      以关联数组的形式返回
		 */
		public function execute_dql_arr($sql) {
			$arr = array();
			$res = $this->mysqli->query($sql) or die('操作dql失败' . $this->mysqli->error);

			while($row = $res->fetch_assoc()) {
				$arr[] = $row;
			}

			$res->free_result();
			return $arr;
		}

		/**
		 * 执行DML语句(insert、update、delete语句)
		 * @param  [type] $sql SQL语句
		 * @return [type]      0表示失败;1表示成功;2表示没有行受影响
		 */
		public function execute_dml($sql) {
			$res = $this->mysqli->query($sql)/* or die('操作dml失败' . $this->mysqli->error)*/;

			if(!$res) {
				return 0; //表示失败
			} else {
				if($this->mysqli->affected_rows > 0) {
					return 1; //表示成功
				} else {
					return 2; //表示没有行受到影响
				}
			}
		}

		public function __destruct() {
			$this->mysqli->close();
		}
	}
?>
       LabPHP/Libs/LabPHP.class.php

<?php 
	class LabPHP {
		private static $m; //模块
		private static $c; //控制器
		private static $a; //操作

		/**
		 * 获取HTTP请求的参数-》 模块名、控制器名、操作方法名
		 * @return [type] [description]
		 */
		private static function init() {
			self::$m = isset($_GET['m']) ? daddslashes($_GET['m']) : 'Home'; //初始化模块
			self::$c = isset($_GET['c']) ? daddslashes($_GET['c']) : 'Index'; //初始化控制器
			self::$a = isset($_GET['a']) ? daddslashes($_GET['a']) : 'index'; //初始化操作
		}

		/**
		 * 根据控制器和方法名,创建对应的控制器,调用相应的方法
		 * @return [type] [description]
		 */
		public static function start() {
			self::init();
			C(self::$c, self::$a); //C位于functions.php中,用于调用控制器$c的$a方法
		}
	}
?>
       LabPHP/LabPHP.php

<?php 
	//定义应用的模式——是否为调试模式
	if(!defined('APP_DEBUG') || APP_DEBUG == false) {
		error_reporting(0);	
	}
	
	//启动引擎
	$currentdir = dirname(__FILE__);
	//首先include文件清单
	include_once $currentdir . '/Conf/include.list.php';
	//include必要的文件
	foreach ($paths as $value) {
		include_once $currentdir . '/' . $value;
	}

	//定义当前被访问的模块
	define('MODULE_NAME', getModuleName());
	//定义当前被访问的控制器
	define('CONTROLLER_NAME', getControllerName());
	//定义当前被访问的操作
	define('ACTION_NAME', getActionName());

	LabPHP::start();
?>


       Application/Home/Config.php      Application/Admin/Config.php

<?php 
	return array(
		//'配置项'=>'配置值'
		/*'DB_HOST' => '', //设置主机
		'DB_USER' => '', //设置用户名
		'DB_PWD' => '', //设置密码
		'DB_PORT' => '', //设置端口号
		'DB_NAME' => '', //设置数据库名*/

		/* 模板设置 */
	    /*'TMPL_TEMPLATE_SUFFIX'  =>  '',     // 默认模板文件后缀*/
	);
?>
       Application/Home/Controller/IndexController.class.php     Application/Admin/Controller/IndexController.class.php

<?php 
	class IndexController extends Controller {		
		function index() {
			echo "<p style='width: 50%; height: 300px; line-height: 300px; padding: 10px 20px; font-family:\"微软雅黑\", \"Microsoft YaHei\"; font-size: 30px; margin: 50px auto; box-shadow: 0 0 3px #ABCDEF; text-align: center; position: relative;'>Hello LabPHP!<span style='line-height: 30px; font-size: 20px; position: absolute; bottom: 20px; right: 20px;'>欢迎使用LapPHP V1.0.0   By DreamBoy<span></p>";
		}
	}
?>

        index.php

<?php 
	// 开启调试模式 建议开发阶段开启 部署阶段注释或者设为false
	define('APP_DEBUG', false);
	require_once './LabPHP/LabPHP.php';
?>










本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我的简单PHP框架——LabPHP 的相关文章

  • PDO SQLSRV 和 PDO MySQL 在获取 int 或 float 时返回字符串

    当您获取时 PDO MS SQL Server 和 PDO MySQL 都会返回一个字符串数组 即使列的 SQL 类型本应是数字类型 例如 int 或 float 我设法解决了这个问题 但我想了解为什么它们一开始就这样设计 是不是因为PDO
  • 使用 php 获取当前月份的最后 3 个月

    我想获取当前月份最近 3 个月的名称 例如当前月份是八月 所以 我想要六月 七月 八月这样的数据 我已经尝试过这段代码echo date F strtotime 3 months 它只返回六月 如何使用 php 获取当前月份的最后 3 个月
  • 使用 php 在多维数组中按键排序[重复]

    这个问题在这里已经有答案了 可能的重复 在 PHP 中对多维数组进行排序 https stackoverflow com questions 2059255 sorting multidimensional array in php 如何在
  • 第三个下拉菜单不从数据库填充

    我有以下 Index php
  • 为什么验证不起作用并跳转到另一个页面?

    我写了一个customer display php来验证数据 到目前为止只有名字 但无论名字字段是否为空 网页都会跳转到customer search php并且没有更改数据库中的信息 为什么
  • 使用先前的反向引用作为命名捕获组的名称

    有没有办法使用对先前捕获组的反向引用作为捕获组的名称命名捕获组 这可能不可能 如果不可能 那么这就是一个有效的答案 下列 data description some description preg match data matches p
  • Magento - 检查 cms 页面

    我想通过 php 检查页面是否是 Magento 中的 cms page 我需要不同的 cms 页面面包屑 所以我尝试在一个条件下做到这一点 但我不知道如何或在哪里查看 到目前为止 这是我的 breadcrumbs phtml p some
  • 语法错误,第 288 行出现意外的“endif”(T_ENDIF)[关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 我一直在离线处理我的 WordPress 网站的此代码错误 解析错误 语法错误 homez 541 photoher marie
  • 使用 XSLT 将 XML 转换为 SQL

    由于我无法控制的原因 我将获得一个 XML 文件和一个 XSLT 文件 该文件可以将 XML 文件转换为 SQL 代码或错误 现在让我们假设我们可以信任提供 XML 文件的人不会在 XML 中包含危险的构造 我什至不知道是否应该使用 Sim
  • 为什么我的 if 语句没有按我预期的方式工作?

    我正在尝试实现以下目标 我向我的 SQL 数据库询问使用SELECT FROM subjects 这样做之后我要求使用数组mysqli fetch assoc 在那之前一切都很好 现在的问题是 当我尝试在每个循环中修改 genero 的值
  • 强制 Composer 下载 git repo 而不是 zip

    我对作曲家有一些问题 require php gt 5 3 2 kriswallsmith buzz 0 7 Repo https github com kriswallsmith Buzz tree v0 7 https github c
  • phpunit测试调用其他需要mock的类方法的方法

    我正在尝试创建一个非常标准的单元测试 在其中调用一个方法并断言它的响应 但是我正在测试的方法调用同一类中的另一个方法 该方法做了一些繁重的工作 我想模拟该方法 但仍按原样执行我正在测试的方法 仅使用从调用另一种方法返回的模拟值 我简化了示例
  • Sonata DateTimePickerType 类默认日期显示错误的日期时间格式

    我陷入困境 我不知道如何使用 sonata DateTimePickerType 类正确设置默认日期和时间 我尝试了不同的方法 但到目前为止 没有一种方法没有帮助 在下面的截图中 help 键显示正确的日期和时间 但是当我使用 dp 默认日
  • MVC 模式中的验证层

    验证模型将使用的数据的最佳位置在哪里 例如 考虑登记表 我们有一些来自注册表的数据 那么验证这些数据的最佳位置在哪里 我们应该通过 if 语句或特殊的验证器类来检查每个数据 这意味着大量的编码 所以我想了解在哪里可以做到这一点 在控制器中
  • 从数据库填充复选框

    我有两个表 第一个由与名称关联的 id 组成 1 汽车 2 火车 3 普通 ETC 第二个表由两个字段 user id 和第一个表中的 id 组成 例如 1 1 2 1 3 当用户转到该页面时 我试图重新填充选定的复选框 首先 您查询数据库
  • URL 中的 %2F 中断并且未引用所需的 .php 文件 [重复]

    这个问题在这里已经有答案了 我需要将 作为变量作为 URL 的一部分传递 我的结构如下所示 www domain com listings page 1 city Burnaby South type Townhome bedroom 2
  • Laravel leftJoin 仅右表的最后一条记录

    我是 Laravel 的新手 我有两张桌子 1 产品 2 价格 products id product int p key name varchar prices id price int p key id product int
  • 如何使用 PHP 对字符串进行 rot13 处理?

    我有一个很大的 php 代码 我想手动对其进行编码和解码 我的问题是 php 代码里面有很多单引号和双引号 因此我在使用时出现错误str rot13 功能如下 那么正确的语法是什么以及如何使用下面的函数进行编码 str rot13 That
  • 如何在laravel中注册后自动登录

    我在 laravel 中注册用户时遇到问题 user假设是包含所有数组元素的数组 同时自动登录以下代码结果false 数据库中保存的密码是hash make password user id this gt user model gt ad
  • 使用 php-ews(Exchange Web 服务)在特定日期后获取电子邮件

    在我的 PHP 脚本中 我需要弄清楚如何检索指定消息 ID 之后或特定日期之后的所有电子邮件 两者都可以 我只需要检索自上次抓取收件箱以来的新电子邮件 这个收件箱每天收到数千封电子邮件 而且我在 30 天内无法删除任何电子邮件 对于初始导入

随机推荐

  • CSS3让登陆面板旋转起来

    这里只考虑chrome的兼容 LoginRotate html lt DOCTYPE html gt lt html lang 61 34 en 34 gt lt head gt lt meta charset 61 34 UTF 8 34
  • CSS3 卡片翻转(transform)

    这里只考虑chrome的兼容 card1 html lt DOCTYPE html gt lt html lang 61 34 en 34 gt lt head gt lt meta charset 61 34 UTF 8 34 gt lt
  • 他们的CSS3 3D正方体

    摘自 xff1a 程旭元 所分享的程序 效果图如下 xff1a cube html lt DOCTYPE html gt lt html lang 61 34 zh CN 34 gt lt head gt lt title gt 3D正方体
  • html自定义复选框

    自定义复选框的素材 xff1a icon check circle png icon checked png checkbox html xff08 为了方便起见 xff0c 这里使用到了jQuery xff09 lt DOCTYPE ht
  • CSS3的基本介绍

    知识点记录 xff1a 1 圆角效果 border radius 如 xff1a border radius 10px 所有角都使用半径为10px 的圆角 border radius 5px 4px 3px 2px 四个半径值分别是左上角
  • CSS3选择器(上)

    1 属性选择器 E att 61 val 选择匹配元素 E xff0c 且 E元素定义了属性 att xff0c 其属性值以 val开头的任何字符串 E att 61 val 选择匹配元素 E xff0c 且 E元素定义了属性 att xf
  • CSS3实现曲线阴影和翘边阴影

    效果图如下 xff1a index html lt DOCTYPE html gt lt html lang 61 34 en 34 gt lt head gt lt meta charset 61 34 UTF 8 34 gt lt ti
  • THINKPHP 数据操作方法

    一 ThinkPHP Insert 添加数据 ThinkPHP 内置的 add 方法用于向数据表添加数据 xff0c 相当于 SQL 中的 INSERT INTO 行为 添加数据 add 方法是 CURD xff08 Create Upda
  • PHP文件上传的实现及其介绍

    关于实现及介绍在程序注释中 提交文件的页面 xff1a xff08 可以分别提交到doAction php doAction1 php doAction2 php进行测试 xff09 upload php lt doctype html g
  • PHP单文件上传的过程化函数封装

    提交文件的页面 xff1a upload php lt doctype html gt lt html lang 61 34 en 34 gt lt head gt lt meta charset 61 34 UTF 8 34 gt lt
  • PHP的单个文件上传、多个单文件上传、多文件上传

    单文件上传 upload1 php lt doctype html gt lt html lang 61 34 en 34 gt lt head gt lt meta charset 61 34 UTF 8 34 gt lt title g
  • PHP实现单文件上传、多个单文件上传、多文件上传的过程化封装

    上回提到 PHP的单个文件上传 多个单文件上传 多文件上传 这里给出 三种方式的统一实现 下面先给出各种方式的文件提交页面 xff1a 单个文件上传 upload1 php lt doctype html gt lt html lang 6
  • PHP的单文件上传类

    提交单文件的页面 upload php lt doctype html gt lt html lang 61 34 en 34 gt lt head gt lt meta charset 61 34 UTF 8 34 gt lt title
  • PHP的多文件上传类

    提交表单的页面 upload php lt doctype html gt lt html lang 61 34 en 34 gt lt head gt lt meta charset 61 34 UTF 8 34 gt lt title
  • Nginx负载均衡配置实例详解

    转载自 xff1a http www php100 com html program nginx 2013 0905 5525 html 负载均衡是我们大流量网站要做的一个东西 xff0c 下面我来给大家介绍在Nginx服务器上进行负载均衡
  • 基于Bootstrap使用jQuery实现简单可编辑表格

    editTable js 提供编辑表格当前行 添加一行 删除当前行的操作 xff0c 其中可以设置参数 xff0c 如 xff1a operatePos 用于设置放置操作的列 xff0c 从0开始 xff0c 1表示以最后一列作为放置操作的
  • ThinkPHP 大D方法思想下的JDBC操作数据库D类

    这里我封装出来的D 类 xff0c 是根据 ThinkPHP 中的 D 方法中做出来的 xff0c 其中有些出入的地方 xff0c 我进行了一些个性化的修正 xff0c 如 xff1a ThinkPHP 中操作数据库时 xff0c 需要在配
  • 基于MVC设计模式实现简单PHP框架(雏形)-初期

    xff08 记住 xff1a 这里只是提供思考的过程 xff09 其实这里只是一个我们课的Web实验 课程设计题目统计系统 xff0c 在做实验的过程中起初只是想往MVC靠拢而已 xff0c 却不知不觉地 实现 了基于MVC的简单框架的雏形
  • Rocketmq入门介绍

    目录 一 Rocketmq优势 二 Rocketmq与其他MQ对比 三 MQ基本概念 四 RocketMQ的4个组件 五 集群部署结构 工作流程 xff1a 模块功能特性 xff1a Nameserver Broker 生产者 Produc
  • 我的简单PHP框架——LabPHP

    就我上次提到的 基于MVC设计模式实现简单PHP框架 xff08 雏形 xff09 初期 这次列出我实现的LabPHP简易框架 xff0c 该框架中没有使用任何的模板引擎 xff0c 所以说要在模板中使用到php变量的话 xff0c 仍然需