WordPress数据库和网站文件/网络营销是什么?
写在前面
本人开发的框架在2021年年初开发完成,后面没有再做过任何维护和修改。是仅供大家参考交流的学习项目,请勿使用在生产环境,也勿用作商业用途。
框架地址:
https://github.com/yijiebaiyi/fast_framework
整体思路
开发一款web框架,首先要考虑这个框架的整体运行架构,然后具体到那些功能的扩展。那么我开发框架的时候想的是,精简为主,实用为主。主要功能需要包括入口文件、路由解析、异常处理、日志记录、ORM、缓存、类依赖注入。
入口文件
入口文件需要定义全局变量,主要是核心框架文件的所在路径,然后,通过include_once引入框架核心类文件,初始化框架进行初始化操作。
<?phpdefine("FAST_PATH", $_SERVER["DOCUMENT_ROOT"] . DIRECTORY_SEPARATOR . "fast");// 初始化
include_once FAST_PATH . DIRECTORY_SEPARATOR . "App.php";
(new \fast\App())->init();
应用核心类
应用核心类主要是用来注册类的自动加载、加载环境变量文件、注册错误异常以及注册路由。下面是应用初始化init方法。
public function init(){if (false === $this->isInit) {define("DOCUMENT_ROOT", $_SERVER["DOCUMENT_ROOT"]);define("ROOT_PATH", $_SERVER["DOCUMENT_ROOT"]);define("RUNTIME_PATH", $_SERVER["DOCUMENT_ROOT"] . DIRECTORY_SEPARATOR . "runtime");define("APP_PATH", $_SERVER["DOCUMENT_ROOT"]);// 注册自动加载require_once FAST_PATH . DIRECTORY_SEPARATOR . "Autoload.php";(new Autoload())->init();// 注册配置(new Config())->init();// 加载env(new Env())->init();// 注册错误和异常(new Exception())->init();(new Error())->init();(new Shutdown())->init();// 检验运行环境$this->validateEnv();// 注册路由(new Route())->init();$this->isInit = true;}}
上面初始化的方法中,我们需要先判断框架是否已经初始化,如果已经初始化则不需要再进行操作了。init方法中所涉及到的类都在框架核心文件根目录下面,需要注意的是,一定要先注册自动加载,不然使用new 关键字生成对象就会报错。下面是自动加载类的自动加载方法。
public function init(){if (false === $this->isInit) {spl_autoload_register(array($this, 'autoload'));$this->isInit = true;}}/*** @var array 类加载次*/private static array $loadedClassNum = [];/*** 自动加载* @param $name* @throws Exception*/public static function autoload($name): void{if (trim($name) == '') {throw new Exception("No class for loading");}$file = self::formatClassName($name);if (isset(self::$loadedClassNum[$file])) {self::$loadedClassNum[$file]++;return;}if (!$file || !is_file($file)) {return;}// 导入文件include $file;if (empty(self::$loadedClassNum[$file])) {self::$loadedClassNum[$file] = 1;}}/*** 返回全路径* @param $className* @return string*/private static function formatClassName($className): string{return $_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . $className . '.php';}
使用PHP提供的spl_autoload_register自动加载器函数,注册autoload方法实现自动加载,可以看到我们自动加载的类必须都在项目根目录下才可以实现。这是一个简单的约定。
加载配置
我们知道php使用include 导入文件是可以获取到文件的返回值的(如果有的话),所以使用php文件返回一个数组来实现项目的配置文件,框架里面支持默认的config.php文件,以及额外用户可以自定义的配置:extra.php。这个也是我们约定好的。
配置文件示例代码config.php:
<?phpreturn ["Cache" => ["default" => "redis","redis" => ["master" => ["pconnect" => false,"host" => "localhost","port" => 6379,"timeout" => 0,],],],"Log" => ["default" => "file","file" => ["path" => RUNTIME_PATH],]
];
引入配置文件的关键代码:
/*** 加载配置* @param $filename*/private static function addConfig($filename): void{$configArr = include_once($filename);if (is_array($configArr)) {self::$configs = Arr::arrayMergeRecursiveUnique(self::$configs, $configArr);}}/*** 导入配置* @param $paths*/private static function importConfig($paths): void{foreach ($paths as $path) {self::addConfig($path);}}
加载环境变量
环境变量文件,我们默认的就是项目根目录的.env文件。.env文件配置项是标准的*.ini类型配置文件的书写方式,且.env文件里面的配置项不区分大小写,小写配置项最终会被转化成大写。.env文件的加载使用php的函数parse_ini_file来实现:
/*** 加载环境变量定义文件* @param string $file 环境变量定义文件* @return void*/public static function load(string $file): void{$env = parse_ini_file($file, true) ?: [];static::set($env);}
框架支持环境变量的写入、读取和检测。
错误和异常
异常信息抓取到之后,我们将他格式化处理,主要记录异常码、异常文件和所在行号。然后将异常写入日志。(注意,如果是生产模式,需要关闭错误显示)
public static function handler($exception){// 设置http状态码,发送headerif (in_array($exception->getCode(), array_keys(Http::$httpStatus))) {self::$httpCode = $exception->getCode();} else {self::$httpCode = 500;}Http::sendHeader(self::$httpCode);// 异常信息格式化输出$echoExceptionString = "<b>message</b>: {$exception->getMessage()}<br/>" ."<b>code</b>: {$exception->getCode()}<br/>" ."<b>file</b>: {$exception->getFile()}<br/>" ."<b>line</b>: {$exception->getLine()}<br/>";$serverVarDump = Str::dump(false, $_SERVER);$postVarDump = Str::dump(false, $_POST);$filesVarDump = Str::dump(false, $_FILES);$cookieVarDump = Str::dump(false, $_COOKIE);$logExceptionString = "message: {$exception->getMessage()}" . PHP_EOL ."code: {$exception->getCode()}" . PHP_EOL ."file: {$exception->getFile()}" . PHP_EOL ."line: {$exception->getLine()}" . PHP_EOL ."\$_SERVER: {$serverVarDump}" . PHP_EOL ."\$_POST: {$postVarDump}" . PHP_EOL ."\$_COOKIE: {$cookieVarDump}" . PHP_EOL ."\$_FILES: {$filesVarDump}";Log::write($logExceptionString, Log::ERROR);// debug模式将错误输出if (static::isDebugging()) {if (self::$isJson) {echo Json::encode(["message" => $exception->getMessage(), "code" => 0]);App::_end();} else {echo $echoExceptionString;}}}
路由分发
路由的实现思路是:我们根据请求的地址,截取到请求的路径信息(根据PHP全局变量$_SERVER[‘PATH_INFO’]获取),根据路径信息的格式,定位到某个控制器类的某个方法,然后将其触发。实现代码:
public function distribute(){// 解析path_infoif (isset($_SERVER['PATH_INFO'])) {$url = explode('/', trim($_SERVER['PATH_INFO'], "/"));if (count($url) < 3) {$url = array_pad($url, 3, "index");}} else {$url = array_pad([], 3, "index");}// 获取类名和方法名$className = self::formatClassName($url);$actionName = self::formatActionName($url);if (!class_exists($className)) {throw new Exception("the controller is not exist: {$className}", 404);}$class = new $className();if (!is_callable([$class, $actionName])) {throw new Exception("the action is not exist: {$className} -> {$actionName}", 404);}if (!$class instanceof Controller) {throw new Exception("the controller not belongs to fast\\Controller: {$className}", 403);}// 将请求分发$class->$actionName();}
相关文章:

怎么从0到1创建一个PHP框架-1?
写在前面 本人开发的框架在2021年年初开发完成,后面没有再做过任何维护和修改。是仅供大家参考交流的学习项目,请勿使用在生产环境,也勿用作商业用途。 框架地址: https://github.com/yijiebaiyi/fast_framework 整体思路 开发…...

Qt无边框青绿色主题
收费产品,学生党、闹眼子党勿扰 收费金额:500元 1 概述 最近因项目需要,写了一个炫酷的青绿色、无边框界面,和3DSMax的界面有点类似。 2 截图 首先看看3DSMax的界面 不知道大家看出来没,这个ui其实很简单ÿ…...

200 套基于Java开发的Java毕业设计实战项目(含源码+说明文档)
文章目录 简介前言第一部分第二部分部分截图源码咨询 简介 博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝30W、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 前言 对于java方向的毕业设计题目选题…...

Ansible学习笔记7
user模块: user模块用于管理用户账户和用户属性。 如果是windows要换一个win_user模块。 创建用户:present: [rootlocalhost ~]# ansible group1 -m user -a "nameaaa statepresent" 192.168.17.106 | CHANGED > {"ansi…...

Python3 对列表、字典以及二者的嵌套数据(JSON)格式排序
在 Python 中,列表和字典都是基础数据类型,这两种数据类型会通过相互嵌套和多个层级形成复杂的数据类型,类似 JSON 数据格式,对列表和字典排序其实可以类比是对 JSON 排序。 列表排序 列表可以使用 sorted() 函数排序࿱…...

如何在B站进行学习直播
诸神缄默不语-个人CSDN博文目录 会根据我使用的情况进行持续更新 文章目录 1. 电脑 - 哔哩哔哩直播姬1. 软件的基础使用2. 素材1. 摄像头2. 窗口捕捉3. 游戏进程图片文字浏览器多媒体 3. H5插件其他注意事项 2. 手机直播3. iPad直播 1. 电脑 - 哔哩哔哩直播姬 1. 软件的基础使…...

老卫带你学---windows上安装minikube
老卫带你学—windows上安装minikube 1. 下载minikube https://storage.googleapis.com/minikube/releases/latest/minikube-installer.exe2.安装好后,将对应的目录添加env path 3. minikube start --kubernetes-versionv1.23.8 --image-mirror-countrycn...

Neo-reGeorg隧道搭建
目录 Neo-regeorg前言 环境搭建 具体使用 kail安装Neo-reGeorg kail内生成webshell并设置密码 kail与win10连接 windows server内打开服务 kail虚拟机访问windows server以及所在的内网 Neo-regeorg前言 regeorg为reDuh的升级版,主要功能就是把内网服务器的…...

Elasticsearch 7.6 - API高阶操作篇
ES 7.6 - API高阶操作篇 分片和副本索引别名添加别名查询所有别名删除别名使用别名代替索引操作代替插入代替查询 场景实操 滚动索引索引模板创建索引模板查看模板删除模板 场景实操一把索引的生命周期数据迁移APIGEO(地理)API索引准备矩形查询圆形查询多边形查询 自定义分词器…...

软件第三方验收测评介绍
软件第三方验收测试 软件项目验收测试介绍: 软件项目验收测试是部署软件之前的最后一个测试操作,是对系统进行全面的测试,以验证其是否符合合同要求,出具第三方测试报告,为系统验收提供依据。 验收测试的目的是&…...

HarmonyOS—使用Web组件加载页面
页面加载是 Web 组件的基本功能。根据页面加载数据来源可以分为三种常用场景,包括加载网络页面、加载本地页面、加载 HTML 格式的富文本数据。 页面加载过程中,若涉及网络资源获取,需要配置ohos.permission.INTERNET网络访问权限。 加载网络…...

Redis 缓存穿透、击穿、雪崩
一、缓存穿透 1、含义 缓存穿透是指查询一个缓存中和数据库中都不存在的数据,导致每次查询这条数据都会透过缓存,直接查库,最后返回空。 2、解决方案 1)缓存空对象 就是当数据库中查不到数据的时候,我缓存一个空对象…...

设计模式-原型模式详解
文章目录 前言理论基础1. 原型模式定义2. 原型模式角色3. 原型模式工作过程4. 原型模式的优缺点 实战应用1. 原型模式适用场景2. 原型模式实现步骤3. 原型模式与单例模式的区别 原型模式的变体1. 带有原型管理器的原型模式2. 懒汉式单例模式的原型模式实现3. 细粒度原型模式 总…...

大语言模型之七- Llama-2单GPU微调SFT
(T4 16G)模型预训练colab脚本在github主页面。详见Finetuning_LLama_2_0_on_Colab_with_1_GPU.ipynb 在上一篇博客提到两种改进预训练模型性能的方法Retrieval-Augmented Generation (RAG) 或者 finetuning。本篇博客过一下模型微调。 微调:…...

房地产行业专题报告:日本房地产市场借鉴
目录 1. 日本房地产泡沫的形成与崩溃 1.1 背景:实际需求减弱、宽松货币和弱金融监管推动泡沫形成 1.1.1 宏观环境:日本 80 年代起生育率降低,房地产基本面支撑力不足 1.1.2 货币政策:宽松货币政策叠加金融自由化促进泡沫生成 1.1.3 助推因素:企业积极参与土地投机、股…...

Educational Codeforces Round 154 (Rated for Div. 2)
Educational Codeforces Round 154 (Rated for Div. 2) A. Prime Deletion 思路: 因为1到9每个数字都有,所以随便判断也质素即可 代码 #include<bits/stdc.h> using namespace std; #define int long long #define rep(i,a,n) for(int ia;i<…...

elasticsearch批量删除(查询删除)
注:delete by query只适用于低于elasticsearch2.0的版本(不包含2.0)。有两种形式: 1.无请求体 curl -XDELETE localhost:9200/twitter/tweet/_query?quser:kimchy 2.有请求体 使用请求体的时候,请求体中只能使用query查询,不能使用filter curl -XD…...

容器技术Linux Namespaces和Cgroups
对操作系统了解多少,仅仅敲个命令吗 操作系统虚拟化(容器技术)的发展历程 1979 年,UNIX 的第 7 个版本引入了 Chroot 特性。Chroot 现在被认为是第一个操作系统虚拟化(Operating system level virtualization&#x…...

GO语言圣经 第四章习题
练习4.1 编写一个函数,计算两个SHA256哈希码中不同bit的数目。(参考2.6.2节的PopCount函数。) func PopCount(ptr *[32]byte) int {var res intfor i : 0; i < 32; i {x : int(ptr[i])for x ! 0 {res x & 1x >> 1}}return res }练习4.2 编…...

远程连接Ubuntu 22.04
远程连接Ubuntu 22.04 安装openssh-server sudo apt install openssh-server检查服务运行状态 systemctl status sshd重启服务状态 sudo systemctl restart ssh开启防火墙 sudo ufw enable开启ssh传输端口 sudo ufw allow ssh设置开机启动服务 sudo systemctl enable ssh配置服…...

字节前端实习的两道算法题,看看强度如何
最长严格递增子序列 题目描述 给你一个整数数组nums,找到其中最长严格递增子序列的长度。 子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7…...

设计模式—策略模式
目录 一、定义 二、特点 三、优点 四、缺点 五、实例 六.涉及到的知识点 1、一个类里面有哪些东西? 2、类和实例 什么是类? 什么是实例? 什么是实例化? 3、字段和属性 什么是字段? 属性是什么࿱…...

LPDDR4、DDR4
核心信息: 2400Mbps(每秒传输2400*1百万bit) 2400MT/s(百万次/秒) 信号...

ESP32C3 LuatOS RC522①写入数据并读取M1卡
LuatOS RC522官方示例 官方示例没有针对具体开发板,现以ESP32C3开发板为例。 选用的RC522模块 ESP32C3-CORE开发板 注意ESP32C3的 SPI引脚位置,SPI的id2 示例代码 -- LuaTools需要PROJECT和VERSION这两个信息 PROJECT "helloworld" VERSIO…...

MusicBrainz Picard for Mac :音乐文件ID3编辑器
MusicBrainz Picard for Mac是一款macOS平台的音乐文件ID3编辑器,能够帮助我们在Mac电脑上编辑音乐文件的ID3标签信息,包括艺人、专辑等信息,非常快速和简单方便。Picard是下一代MusicBrainz标记应用程序。 这个新的标签概念是面向专辑的&…...

❤ Uniapp使用
❤ Uniapp使用 一、介绍 uni-app官网:https://uniapp.dcloud.io/api/media/image?idpreviewimage 微信小程序官网:https://developers.weixin.qq.com/miniprogram/dev/api/media/image/wx.previewImage.html 二、使用 1、uniapp 实现图片预览 单图预…...

解密Spring事务生效的内部机制
声明式事务和编程式事务对比: 声明式事务: 使用注解或XML配置的方式,在代码中声明事务的属性和行为。通过AOP和代理模式实现,将事务管理与业务逻辑代码解耦。适用于大多数情况,简化了代码,提高了可维护性和…...

大数据时代下的数据安全防护
随着大数据时代的来临,数据安全防护成为了一个重要的问题。在大数据时代,数据的规模和价值都得到了极大的提升,因此数据安全的重要性也变得越来越突出。本文将从数据加密、访问控制、网络安全和人员管理四个方面来介绍大数据时代下的数据安全…...

RabbitMQ-常用命令
RabbitMQ常用命令 3.1 启动停止rabbitMQ命令 # 前台启动Erlang VM 和 RabbitMQ 当窗口关闭或者ctrlc时,使退出了。 rabbitmq-server# 使用系统命令启动 systemctl start rabbitmq-server# 后台启动 rabbitmq-server -detached# 停止rabbitMQ和Erlang VM rabbitmq-…...

Spring中依赖注入的继承bean的细节问题
介绍 有时我们会对一种类型的bean进行继承,在Spring生成bean的时候,返回类型有时是子类类型,有时会父类类型。那么到底在什么情况下用哪种类型呢?肯定有不少人会忽略这点,本篇文章就是把这个细节讲清楚 案例 父类Ba…...