续言
对于本次更新, 我想说:
本框架由本人挑时间完善, 而我还不是 PHP 大神级的人物, 所以框架漏洞难免, 求大神们指出
本框架的知识点应用都会写在博客里, 大家有什么异议的可以一起讨论, 也希望看博客的也能学习到它们
本次更新, 更新了函数规范上的一些问题, 如将函数尽量的独立化, 每一个函数尽量只单独做好一件事情, 尽量减少函数依赖还对框架的整体优化了一下, 添加了 SQ 全局类, 用以处理全局函数, 变量
再次贴出 GITHUB 地址: Sqier 框架 GITHUB 地址
回调函数
替换了很 low 的类名拼装实例化, 然后拼装方法名的用法, 使用 PHP 的回调函数方式:
原代码:
- $controller_name = 'Controller\\' . self::$c_name;
- $action_name = self::$a_name . 'Action';
- $controller = new $controller_name();
- $controller->$action_name();
修改后代码
- $controller_name = 'Controller\\' . self::$c_name;
- $controller = new $controller_name();
- call_user_func([
- $controller,
- self::$a_name . 'Action'
- ]);
这里介绍一下 PHP 的函数回调应用方式: call_user_func 和 call_user_func_array:
call_user_func (callback $function [, mixed $parameter [, mixed $...]] )
调用第一个参数所提供的用户自定义的函数
返回值: 返回调用函数的结果, 或 FALSE
call_user_func_array()的用法跟 call_user_func 类似, 只不过传入的参数 params 整体为一个数组
另外, call_user_func 系列函数还可以传入在第一个参数里传入匿名参数, 可以很方便的回调某些事件, 这些特性在复杂的框架里应用也十分广泛, 如 yii2 的事件机制里回调函数的使用就是基于此
VIEW 层和 ob 函数
框架在 controller 的基类中定义了 render 方法来渲染页面, 它会调用类 VIEW 的静态函数来分析加载对应页面的模板
- public static
- function display($data, $view_file) {
- if (is_array($data)) {
- extract($data); //extract 函数解析 $data 数组中的变量
- } else {
- // 抛出变量类型异常
- }
- ob_start();
- ob_implicit_flush(0);
- include self: :checkTemplate($view_file); // 自定义 checkTemplate 函数, 分析检查对应的函数模板, 正常返回路径
- $content = ob_get_clean();
- echo $content;
- }
这里重点说一下 ob(output buffering)系列函数, 其作用引用简明代魔法的 ob 作用介绍:
防止在浏览器有输出之后再使用 setcookie, 或者 header,session_start 函数造成的错误其实这样的用法少用为好, 养成良好的代码习惯
捕捉对一些不可获取的函数的输出, 比如 phpinfo 会输出一大堆的 html, 但是我们无法用一个变量例如 $info=phpinfo(); 来捕捉, 这时候 ob 就管用了
对输出的内容进行处理, 例如进行 gzip 压缩, 例如进行简繁转换, 例如进行一些字符串替换
生成静态文件, 其实就是捕捉整页的输出, 然后存成文件, 经常在生成 HTML, 或者整页缓存中使用
它在 ob_start()函数执行后, 打开缓冲区, 将后面的输出内容装进系统的缓冲区, ob_implicit_flush(0)函数来关闭绝对刷送 (echo 等), 最后使用 ob_get_clean() 函数将缓冲区的内容取出来
类 / index.php/Article 常量和全局类
TP 里的 / index.php/Article 等全局常量用着很方便, 可以很简单的实现跳转等操作, 而定义它的函数 createUrl 函数我又想重用, 于是借鉴 YII 的全局类定义方法:
定义基类及详细方法(以后的全局方法会写在这里)
- class BaseSqier {
- // 方法根据传入的 $info 信息, 和当前 URL_MODE 解析返回 URL 字符串
- public static
- function createUrl($info = '') {
- $url_info = explode('/', strtolower($info));
- $controller = isset($url_info[1]) ? $url_info[0] : strtolower(CONTROLLER);
- $action = isset($url_info[1]) ? $url_info[1] : $url_info[0];
- switch (URL_MODE) {
- case URL_COMMON:
- return "/index.php?r=".$controller.'/'.$action;
- case URL_REWRITE:
- return '/'.$controller.'/'.$action;
- }
- }
- }
在启动文件中定义类并继承基类;
- require_once SQ_PATH.'BaseSqier.php';
- class SQ extends BaseSqier{
- }
在全局内都可以直接使用 SQ::createUrl()方法来创建 URL 了这样, 定义 / index.php/Article 常量就很轻松了
用单例模式定义数据库连接基类
- class Db {
- protected static $_instance;
- public static function getInstance() {
- if(!(self::$_instance instanceof self)) {
- self::$_instance = new self();
- }
- return self::$_instance;
- }
- private function __construct() {
- $link = new \mysqli(DB_HOST, DB_USER, DB_PWD, DB_NAME) or die("连接数据库失败, 请检查数据库配置信息!");
- $link->query('set names utf8');
- }
- public function __clone() {
- return self::getInstance();
- }
- }
使用单例模式的核心是:
私有化构造函数, 使无法用 new 来创建对象, 也防止子类继承它并改写其构造函数;
用静态变量存放当前对象, 定义静态方法来返回对象, 如对象还未实例化, 实例化一个, 存入静态变量并返回
构造其__clone 魔术方法, 防止 clone 出一个新的对象;
DB 类的 sql 查询函数
DB 查询函数是一个很复杂的部分, 它是一个自成体系的东西, 像 TP 和 YII 的查询方法都有其独特的地方我这里暂时先借用 TP 的 MODEL 基类, 有时间再慢慢补这个
嗯, 介绍一下像 TP 的查询里的方法联查的实现, 其诀窍在于, 在每个联查方法的最后都用 return this 来返回已处理过的查询对象
后续
yii2 里的数据表和 model 类属性之间的映射很酷 (虽然被深坑过), 前面一直避开的模块(module, 我可以想像得到把它也添加到 URI 时解析的麻烦) 有时间考虑一下
边写边优化
来源: https://www.php1.cn/detail/php-508ec85fcf.html