首页 > 其他分享 >[持续更新中] 创新实训项目

[持续更新中] 创新实训项目

时间:2024-05-30 17:11:32浏览次数:16  
标签:文件 创新 更新 如下 文件夹 实训 php 方法 路由

DeerOJ的前端框架介绍

Web文件夹下的结构

DeerOJ的前端框架参考了部分 Lavarel 框架,做到兼顾代码的可维护性和可阅读性。具体的维护目录文件结构如下:

注意到web文件夹下的 index.php 这是整个前端程序的 main 程序 ,当服务段收到请求后, 根据 .htaccess 文件指定使用 index.php 文件来生成网页,并把网页数据返回到前端进行渲染呈现。

App文件夹下的结构

网页的生成构造需要一些基本要素,web文件夹下的app文件夹中保存着大量的基本要素。app文件夹下的文件结构如下:

文件夹下包含一些子文件夹和文件,这里选取一些重要的文件来进行解析:

route.php文件

route.php 是整个前端程序的路由, index.php 会把前端发送的路由信息传递给route.php ,文件会根据发送的路由信息,结合 model 文件夹下的 Route.php 调用对应的php程序,从而来实现生成网页(HTML文件)的功能。具体解析如下:

路由模式定义

给出如下代码

这些模式定义了 URL 参数的格式。比如,username 只能包含字母、数字和下划线,长度在 1 到 20 之间;idcontest_id 是数字,长度在 1 到 10 之间;rand_str_id 是一个长度为 20 的字符串,由数字和大小写字母组成。

路由组定义


这个路由组限定了所有路由都在指定域名下可用。UOJConfig::$data['web']['main']['host'] 获取的是配置中的主机名。

具体路由配置


这些路由使用 Route::any 方法配置,表示无论是 GET 还是 POST 请求,都会路由到对应的 PHP 文件。例如,请求根路径 / 会被路由到 index.php 处理,请求 /problems 会被路由到 problem_set.php 处理。

用户相关路由


这些路由处理用户登录、注册、忘记密码、重置密码,以及查看和修改用户信息等操作。

评测相关路由


这些路由处理与评测系统相关的操作,例如提交评测任务、同步评测客户端、下载提交记录、临时文件、题目和评测器等。

config.php文件

config.php 文件是 PHP 应用程序的配置文件,具体用于 Deer Online Judge (DeerOJ) 系统的设置。它定义了应用程序的基本信息、数据库连接、Web 服务器设置、安全配置、邮件配置、评测机配置以及一些开关设置。

基本信息 (profile)


部分参数解释如下:

  • oj-name: 在线评测系统的全称。
  • oj-name-short: 在线评测系统的简称。
  • administrator: 系统管理员的用户名。
  • admin-email: 系统管理员的电子邮件地址。
  • QQ-group: QQ 群的联系方式,当前为空。
  • ICP-license: ICP 备案号,当前为空。

数据库配置 (database)


部分参数解释如下:

  • database: 数据库名称。
  • username: 数据库用户名。
  • password: 数据库用户的密码。
  • host: 数据库服务器的地址。

Web 服务器配置 (web)


部分参数解释如下:

  • domain: 网站的域名,当前为 NULL
  • main: 主站点的协议、主机名和端口。
  • blog: 博客站点的协议、主机名和端口。主机名是通过 UOJContext::httpHost() 获取的。

安全配置 (security)


部分参数解释如下:

  • user.client_salt: 用户密码的盐值,用于增强密码的安全性。
  • cookie.checksum_salt: 用于校验 Cookie 的盐值数组。

邮件配置 (mail)


部分参数解释如下:

  • noreply: 配置 no-reply 邮箱的用户名、密码、SMTP 服务器地址、加密方式和端口。

评测机配置 (judger)和开关设置 (switch)


部分参数解释如下:

  • socket.port: 评测机连接的端口号。
  • socket.password: 评测机连接的密码。
  • web-analytics: 是否启用网站分析,当前为 false(不启用)。
  • blog-domain-mode: 博客域名模式,当前为 3

model文件夹

model文件夹下存储的是一些相关类的php文件,在HTML文件生成的时候,利用这些类能够高效地辅助文件与文件之间的调度转换。文件夹下的内容如下:

这里列举一些重要的类文件:

Route.php文件

前文中在实现 route.php 的路由调度过程中有出现使用类Route的情况,实际上就是调用这里的类Route的相关方法去实现的。这个 Route 类是一个简单的路由器,它可以用于处理基于 URI 和 HTTP 方法的请求路由。它支持添加、匹配和分组路由,以及定义参数模式。下面介绍一下部分重要属性和方法:

Route.php文件的部分属性
  • protected static $routes: 存储所有注册的路由。
  • protected static $patterns: 存储所有自定义的参数模式。
  • protected static $groupStack: 存储当前的路由组属性。
match 方法

代码截图如下:

match方法将指定的 HTTP 方法、URI 和处理动作添加到路由中。其中,array_map('strtoupper', (array)$methods) 将方法名转为大写,便于规范匹配。

any 方法

代码截图如下:

any方法支持任意 HTTP 方法的路由,保证前端调用的时候能够保证所有的基本请求方式都能使用。

各种 HTTP 方法的快捷方式

代码截图如下:

将不同的 HTTP 方法打包在 Route类中,方便实现调用。

group 方法和 getGroup 方法

代码截图如下:

group 方法中,定义一个路由组,将传入的属性和当前组的属性合并,然后执行回调函数。其中,array_pop(self::$groupStack) 在执行完回调函数后恢复上一个路由组的属性。
getGroup 方法则是用于获取当前的路由组属性。

addRoute 方法

代码截图如下:

该方法将一个新路由添加到 $routes 数组中,便于后续对路由的检查。

checkRoute 方法

代码截图如下:

该方法检查当前请求是否匹配某个路由,并匹配请求方法。同时,使用定义的参数模式替换 URI 模式中的占位符。然后匹配 URI 和域名,如果匹配成功,将匹配的参数存储到 $_GET 中。

DB.php 文件

在编写代码的过程中,如果直接调用php中与数据库相关的语句,可能会导致代码可阅读性差,结构混乱从而加大了系统的维护成本。故使用 DB.php 来统一管理与数据库相关的交互操作。DB 类是一个封装了 MySQL 数据库操作的静态类,用于简化数据库操作并提高代码的可读性和可维护性。它使用 PHP 的 mysqli 扩展来与 MySQL 数据库进行交互。下面介绍一下部分重要属性和方法:

初始化数据库连接

初始化Init方法的具体代码如下:

该方法初始化与 MySQL 数据库的连接,并存储在全局变量 $uojMySQL 中。并且,使用 mysqli_connect 函数连接数据库,如果连接失败,输出错误信息并终止程序。

SQL 注入防护

escape 方法的具体代码如下:

该方法使用 mysqli_real_escape_string 函数对输入的字符串进行转义,以防止 SQL 注入攻击。

数据提取方法

fench 方法的具体代码如下:

该方法从查询结果集中获取一行作为关联数组或数字数组。

基本数据库操作

基本的增删改的实现,这里仅给出实现代码,代码如下:

数据选择方法

代码如下:

  • select 方法执行查询并返回结果。
  • selectAll 方法返回查询结果中的所有行。
  • selectFirst 方法返回查询结果中的第一行。
  • selectCount 方法返回查询结果的行数。
检查表是否存在

checkTableExists 方法的具体代码如下:

该方法通过尝试查询表中的一行数据来检查表是否存在。

行数和受影响行数

num_rowsaffected_rows 方法的具体代码实现如下:

其中,num_rows 方法返回结果集中行的数量,affected_rows 方法返回上一次查询中受影响的行数。

libs文件夹

index.php 文件初始化的过程中,需要提前准备好一些类和方法,这些类和方法的初始化是调用 libs 文件夹下的大多数 php 文件来实现的。libs文件夹下的文件如下:

其中,uoj-lib.php 文件是进行所有相关初始化的主文件,上级的 index.php 文件会直接调用该文件展开初始化的工作。libs 文件夹下的其他文件和 model 文件夹下的所有类都是通过 uoj-lib.php 文件来完成初始化工作的。

controller文件夹

该文件夹是用来存放控制器文件的,也就是构建HTML文件的主要文件。controller文件夹下的文件如下:

其中, judge 文件夹下的文件负责处理OJ的判题逻辑。比如,评判提交的代码是否AC/WA/TLE/MLE等。
这里以当前文件夹下的 index.php 为例来描述主页的生成。

生成主页的 index.php

DeerOJ的工作原理

服务端收到请求后,会运行 web 文件夹下的 index.php 文件(由同目录下的.htaccess决定)

index.php 文件的内容截图如下:

index.php 会加载所需的函数库和类库,具体如下:

require $_SERVER['DOCUMENT_ROOT'] . '/app/libs/uoj-lib.php';

该句是调用 /app/libs/ 下的php文件,用来调用一些类和方法。

uoj-lib.php 的完整代码如下:

注意到 uoj-lib.php 下有如下代码段:

function requirePHPLib($name) { // uoj php lib
		require $_SERVER['DOCUMENT_ROOT'].'/app/libs/uoj-'.$name.'-lib.php';
	}
	
	requirePHPLib('validate');
	requirePHPLib('query');
	requirePHPLib('rand');
	requirePHPLib('utility');
	requirePHPLib('security');
	requirePHPLib('contest');
	requirePHPLib('html');

可知在代码中调用了同类文件夹的其他 lib.php 文件,这些文件的具体功能大致如下:

  • validate:验证lib,用来验证某些信息是否合法,比如账号密码等
  • query:查询lib,用来调用后台数据库查询相关信息,结合 model 文件夹下的 DB.php 类使用
  • rand:随机lib,用来生成随机数据(随机数、随机文件名等)
  • utility:utility—lib,用来实现一些在web上的功能,比如配置合并,字符串处理等
  • security:安全lib,用来维护账号的安全,比如密码处理,token等
  • contest:比赛lib,用来处理比赛相关的方法集,比如计算rating,更新人数等
  • html:HTMLlib,用来接收网页相关信息、输出html代码等

注意到 uoj-lib.php 下有如下代码段:

	Session::init();
	UOJTime::init();
	DB::init();
	Auth::init();
    	
	if (isset($_GET['locale'])) {
		UOJLocale::setLocale($_GET['locale']);
	}
	UOJLocale::requireModule('basic');

此段均是对 /app/models/ 下的部分类进行初始化,其中:

  • Session:初始化会话层相关的信息
  • UOJTime:初始化时间信息
  • DB:初始化和数据库的连接
  • Auth:初始化登录用户的信息
  • UOJLocale:中英文相关的配置信息

回到web 文件夹下的 index.php 文件,注意到如下代码:

require UOJContext::documentRoot().'/app/route.php';

其中,UOJContext类是用来管理和获取与当前Web请求相关的上下文信息,例如获取服务器环境信息,blog处理等。该句是调用路由文件。路由文件(route file) 去给请求中的网址匹配用于生成响应报文的 PHP 代码,结合 models 下的 Route 使用。 Route 定义了一个简单的路由系统,允许通过静态方法定义和管理路由。通过 match、get、post 等方法,可以方便地为不同的HTTP请求方法定义路由。通过 group 方法,可以对一组路由应用共同的属性。dispatch 方法用于遍历和匹配请求的路由,并执行相应的操作。整个路由系统利用静态属性和方法来管理路由,使其在应用中便于使用和扩展。

index.php 文件中,注意到如下代码:

include UOJContext::documentRoot().'/app/controllers'.call_user_func(function() {
	$route = Route::dispatch();
	$q_pos = strpos($route['action'], '?');
	
	if ($q_pos === false) {
		$path = $route['action'];
	} else {
		parse_str(substr($route['action'], $q_pos + 1), $vars);
		$_GET += $vars;
		$path = substr($route['action'], 0, $q_pos);
	}
	
	if (isset($route['onload'])) {
		call_user_func($route['onload']);
	}
	
	return $path;
});

这里是动态调用库文件,主要是根据用户的网页请求来调用。比如申请主页,会调用 controllersindex.php 文件。

标签:文件,创新,更新,如下,文件夹,实训,php,方法,路由
From: https://www.cnblogs.com/hakurokawashiro/p/18222054

相关文章

  • 深入探索汇编语言的顶尖级应用领域,包括多核并行处理、物联网和嵌入式系统、高性能计算
    汇编语言初级应用的大纲:1.汇编语言概述介绍汇编语言的基本概念和作用。解释汇编语言与高级语言的区别。简要说明汇编语言的历史和发展。2.汇编语言基础讲解汇编语言的基本语法和结构。介绍汇编语言中的指令、寄存器、内存等概念。解释汇编语言程序的组成部分,如数据段......
  • 监听浏览器更新URL参数,实现伪SPA单页面应用
    在老的jqury项目中通常实现SPA一般都采用hash值变化来进行监听,但是有的项目中我们也想采用改变URL参数来进行监听,一般我们使用window.history.pushState方法来改变url参数;为了在使用window.history.pushState或window.history.replaceState后能够检测到浏览器的后退按钮操作,......
  • 【持续更新】创新实训
    项目简介随着互联网+的生态模式和人工智能的产业化发展,程序设计已成为计算机专业乃至工科学生的必备技能之一。学生学习程序设计,不仅能提高代码水平能力,学会如何写代码,如何写好代码,而且能锻炼学生在今后面对项目开发等实际应用场景时解决问题的能力。因此,很多同学在刚刚接触到编......
  • 是否有办法区分 Mac App Store 应用程序的重新安装和更新?
    我正在开发一款电子应用,并将其发布到MacAppStore。我的主要目标是在应用卸载(和重新安装)时清除应用创建的用户数据,而不是在更新时。但是这在MacOS上是不可能实现的,因为在MacOS上卸载只是将应用文件夹拖入垃圾箱,而垃圾箱是无法干预的。因此,我转而尝试在应用从全新安装中首次......
  • 对于一个页面的两个更新方法,我们到底该写成一个通用的还是两个单独的?
    如果一个页面有两个更新方法的话,分别是通过不同的功能点点击过去的,比如分别更新一个页面的上半部分内容(业务实体A),一个是只是更新其中的发票信息的(发票实体B),虽然在一个页面,但是也不应该写成一个更新请求这种的因为两个更新没什么关联的关系,而且更新的是实体不是一个,所以就可以整成......
  • 开源AI智能名片商城系统小程序:构建企业敏捷性与创新力的新引擎
    摘要:在数字化时代,企业正面临前所未有的市场变革。客户需求日新月异,市场竞争日趋激烈。为了在这场变革中立足,企业必须寻求新的解决方案,以提升自身的敏捷性和创新力。开源AI智能名片商城系统小程序,作为一种新兴的技术工具,正以其独特的优势,助力企业迅速响应市场变化,推动产品和服......
  • YOLOv10全网最新创新点改进系列:融合空间信息关注机制(SimAM)于YOLOv10网络,在通道之间和
    YOLOv10全网最新创新点改进系列:融合空间信息关注机制(SimAM)于YOLOv10网络,在通道之间和空间位置之间建立更加准确的关联,助力YOLOv10有效涨点!!!所有改进代码均经过实验测试跑通!此项目不低于30种改进!自己排列组合2-4种后,考虑位置不同后可排列组合上千万种!改进不重样!!专注AI学术,......
  • YOLOv10最新创新点改进系列:融合最新顶会提出的HCANet网络中卷积和注意力融合模块(CAFM
    YOLOv10全网最新创新点改进系列:融合最新顶会提出的HCANet网络中卷积和注意力融合模块(CAFM),有效提升小目标检测性能,大幅度拉升目标检测效果!遥遥领先!YOLOv10全网最新创新点改进系列:融合最新顶会提出的HCANet网络中卷积和注意力融合模块(CAFM-2024年4月开源),有效提升小目标检......
  • lua语言:模块热更新方案
    我们知道,lua通过package模块来管理模块的搜索和加载,当使用require首次成功加载一个模块后,模块(Table)会被存储在package.loaded中,之后的require行为会直接获取到已加载的模块缓存。如何在程序执行时,将对模块文件的修改热更新到程序中,同时确保运行时状态的正常。这是项目开发中常见......
  • MySQL约束条件,非空空约束(not nullnull),主键约束PK(primary key),外键约束FK(foreign key
    ⅠMySQL约束条件【一】什么是约束条件约束条件:限制表中的数据,保证添加到数据表中的数据准确和可靠性!凡是不符合约束的数据,插入时就会失败!约束条件在创建表时可以使用,也可以修改表的时候添加约束条件【二】约束条件概览null和notnull为空和不为空限制整数类型必须大......