入门指南


>i 本文档的最新修订日期是: > **2020-08-10** # 前言 ## 版本说明 当前文档对应的框架版本是 `4.0.2` ,如果与您使用的框架版本不符,则有可能本文档的部分或全部内容将 `不适用` 于您正在使用的框架。 在 `4.x` 中,我们进行了大范围的调整,因此与 `2.x` 版本不兼容。如果您正在使用 `2.x` 版本,请参看 **`升级`** 章节中的内容。 ## 综述 感谢您了解84PHP开源框架! >d 请注意,一定不要以使用 `MVC` 模式开发框架的使用经验来理解84PHP。 此框架是一款力求在 `性能指标``简洁度` 之间达到平衡的开发框架,同时尽可能的在减少开发者使用框架时所花费的时间,为此我们引入了诸多新颖的设计理念: * 高内聚的可插拔模块设计 * 简洁的文件结构 * 快捷语法模式 * 完善详细的报错信息 随着技术趋势的改变,前后端分离已经成为了主流的技术架构。在4.X版本中,我们更侧重于面向前后端分离的架构进行演进,因此做了大量调整。 ## 运行环境 运行环境为 `PHP7+` 。 ## 性能&安全性 84PHP在编写之初,最关注的就是防注入、XSS、CSRF等安全问题,在不使用参数绑定的前提下(参数绑定降低开发效率),我们完美实现了安全防护。 而另一方面,我们始终认为“代码量是运行效率的重要标准”,虽然代码量少不一定意味着运行效率就高,但臃肿的代码一定是运行效率低的。 在每一个模块的编写过程中,我们尽量保证代码紧凑,这也就是为什么数十KB的框架代码,在普通的服务器上不仅能够驱动百万级pv的电子商务应用,更能作为手机APP的后端支撑。 ## 交流方式 >i 84PHP官方QQ群:823907259 准备好了吗?接下来,我们将为您详细介绍如何使用84PHP框架! ## 视频教程及Demo 我们提供了视频教程和一个简单的 `Demo` 作为示例,帮助初学者入门以及深入理解本框架。 视频及Demo地址:[点击进入>>>](https://www.84php.com/?class=15&space=news) # 目录结构 ``` / 站点根目录(或虚拟主机中的 www & wwwroot 目录) │ ├─Config 配置文件目录 │ ├─Common.php 核心配置文件 │ └─... 其它模块配置文件 │ ├─Core 应用目录 │ ├─Class 模块目录 │ │ ├─Base 基础模块目录(不建议改动) │ │ ├─Module 可选模块目录 │ │ └─index.php 默认文件 │ │ │ ├─Errors 报错定义目录 │ │ ├─Http404.php Http404状态码报错文件 │ │ ├─Http500.php Http500状态码报错文件 │ │ ├─Http4xx.php Http4xx状态码报错文件 │ │ ├─Http5xx.php Http5xx状态码报错文件 │ │ ├─Style.php 报错模板文件 │ │ └─index.php 默认文件 │ │ │ ├─Initial.php 初始化文件(请勿修改) │ └─index.php 默认文件 │ ├─Source 模板目录 │ ├─Data 数据处理部分 │ └─Template 静态模板部分 │ ├─Temp 模板目录 │ ├─Cache 编译缓存目录 │ ├─Log 日志文件目录 │ ├─ip-blacklist.php IP黑名单 │ └─ip-whitelist.php IP白名单 │ ├─Web Web目录(对外访问目录) │ └─index.php 入口文件 │ ├─Rewrite.zip 伪静态规则 └─Readme.html 入门指南 ``` # 准备工作及核心配置 ## 准备工作 >w 在开始使用前,需要通过服务器的伪静态设置将所有流量牵引至 `/Web/index.php` 文件。 `/Rewrite.zip` 下包含了伪静态规则,可根据需要自行调整。 请根据具体情况选择 `开发环境版本` (不屏蔽报错)或 `生产环境版本` (屏蔽报错)的伪静态规则。 * IIS环境下,请将对应环境版本文件夹内的 `web.config` 文件放置于网站根目录,在安装好URL重写模块之后即可使用。 * Apache环境下,请将对应环境版本文件夹内的 `.htaccess` 文件放置于网站根目录,在Apache的配置文件中开启URL重写选项之后即可使用。 * Nginx环境下,请将对应环境版本文件夹内的 `84php.conf` 文件引入到Nginx的配置文件 `nginx.conf` 中,也可以将84php.conf中的代码插入到nginx.conf中的合适位置。 * 如果有额外需求,可根据需要自行调整伪静态规则。 >i 规则隐藏了.php文件后缀,并屏蔽了对/Core、/Source、/Temp等关键路径的访问,以及当HTTP状态码为4xx或5xx时,展示友好的出错页面。同时将流量牵引至/Web/index.php。 ## 核心配置 >w 框架的核心配置文件位于 `/Config/Common.php` ,文件中的 `$FrameworkConfig` 数组变量,包含了所有的关键设置。 * **`Debug`** `(Bool)` `TRUE` : 调试模式,`TRUE` 代表开启、`FALSE` 代表关闭,默认开启。 当调试模式关闭时,报错等级将调整至最低 `(意味着某些不重要的错误将会被忽略)` ,而当调试模式开启时,框架会自动对修改过的模板文件进行编译,并告知浏览器对所有页面都不进行缓存;同时在发生错误时显示详细的报错信息 `(可能包含文件路径、出错类型或数据库信息)` 。 在调试模式关闭的情况下,可以开启Wrong模块中记录日志的配置项,报错信息将会被写入日志中,详情请参阅Wrong模块的说明文档。 >d 为了确保安全,在正式使用(以下称作生产环境)时,务必关闭调试模式。 * **`Route`** `(String)` `'MIX'` : 框架的路由模式。 当值为 `BASE` 时,可通过类似 `/Web/index.php?p_a_t_h=/auth/login` 的形式,即通过参数 `p` 访问缓存,必须以 `/` 开头,且不含后缀 `.php` 。 当值为 `PATH` 时,可通过类似 `/auth/login` 的形式直接访问。 当值为 `MIX` 时,则同时兼容上述两种方式。 >w 是否区分大小写,取决于服务器环境配置。 * **`Https`** `(Bool)` `FALSE` : 是否强制使用HTTPS访问,`TRUE` 代表开启、`FALSE` 代表关闭,默认关闭。 如果开启,将会把HTTP请求重定向为HTTPS请求。 >w 由于运行环境的限制,在某些情况下(如服务器环境配置不当时),如果不存在 `$_SERVER['HTTPS']` 变量,将导致框架 `报错` 。 * **`RunTimeLimit`** `(Bool | Int)` `FALSE` : 程序运行时的超时时限,单位为秒,默认跟随运行环境配置。 当此变量为 `Bool` 类型的值 `FALSE` 时,将 `跟随` 运行环境配置;此变量为 `Int` 类型时,请参考PHP官方手册中有关 `set_time_limit()` 函数的说明。 >w 由于运行环境的限制,在某些情况下(如在虚拟主机中运行),本设置可能 `不会生效` 。 * **`SafeCode`** `(String)` `''` : 安全码,默认为空。 请将此项设置为一个长度 `大于10` 的随机字符串,否则所有使用到安全码的功能 `都不会` 启用。 * **`SessionStart`** `(Bool)` `FALSE` : 用以指定是否自动地开启SESSION,`TRUE` 代表开启、`FALSE` 代表关闭,默认开启。 如果想要在应用运行时 `自动地` 启用SESSION,请将值设置为 `TRUE` 。 * **`TimeZone`** `(String)` `'Asia/Shanghai'` : 程序运行时的时区,默认为中国上海。 请参考PHP官方手册中关于 `date_default_timezone_set()` 函数的说明。 >w 由于运行环境的限制,在某些情况下(如在虚拟主机中运行),本设置可能 `不会生效` 。 * **`XPoweredBy`** `(String)` `'ASP.NET'` : 用以指定如何显示服务器端运行环境,默认为 `ASP.NET` ,能够起到一定的伪装及安全防护作用,不建议修改。 * **`Always200`** `(Bool)` `TRUE` : 用以指定是否在Hrader中始终返回 `HTTP 200` 状态码,`TRUE` 代表开启、`FALSE` 代表关闭,默认开启。 开启后,无论什么情况发生,框架都将尽可能地返回 `HTTP 200` 状态码。 # 常量 截至当前版本,本框架有以下常量: * **`RootPath`** `(String)` `~` : 此常量代表了站点根目录,即 `/Core` 目录的父一级目录路径。 * **`Runtime`** `(Float)` `~` : 此常量代表了框架开始加载时的时间戳。 # 模块 >d 请注意,一定不要以 `MVC` 模式开发框架的使用经验来理解84PHP,否则你将无法理解以下内容。 在路径 `/Core/Class` 中,有 `Base & Module` 两个文件夹,其中包含了框架所有使用到的 `类`(Class,每一个类均拥有各自的一类功能)。 但在官方所有关于84PHP的表述中,将把它称作 `模块` (Module): * `Base` 目录下的模块,是 `基础模块` ,支撑着框架的基本功能。 除非您完全了解框架的运行原理并参透了代码含义,否则不能删除其中的任何一个文件。 * `Module` 目录下的模块,是 `可选模块` ,除了在应用中被使用到的模块,可以删除其余的模块以精简代码。 框架源码包中已经包含了大部分常用模块,您可以自行编写模块,还可以下载其他开发者编写的 `第三方模块` 。 >d 请注意,Base目录和Module目录下的模块名称不能够重复。 在路径 `/Config` 中,可能存在与模块名相对应的 `配置文件` `(也可能不存在)` 。 例如,`Pay.php` 对应的是 `Pay` 模块(提供在线支付功能,在 `Module` 目录下),其内存储着支付接口的通信密钥和该模块所需的其它配置项。 对于基础模块的配置文件,建议谨慎修改。 >w 您可以通过手动编辑配置文件的方式调整配置项,亦可通过Setting模块进行灵活的配置,有关Setting模块的详细说明,请参阅该模块的说明文档。 有关模块配置项的动态注入,请查看下一节内容。 # 注入配置项 自4.0.0版本起,不再支持通过SESSION动态注入配置项,请通过Setting模块中的Change()方法完成。有关Setting模块的详细说明,请参阅该模块的说明文档。 通过 `动态注入` 定义与通过 `配置文件` 定义的区别: * `动态注入` 更加灵活,适合需要使用多个同类配置项的情况,但由于通常要从外部获取变量的值(比如从数据库中读取),效率会低于从配置文件中直接获取。因此特别是在并发量大的时候,性能差异会更加明显。 * `配置文件` 性能更优秀,并且不会因为数据库泄露等未知因素失去配置,但灵活性稍差,建议在高并发场景使用。 >d 动态注入的配置项仅 `运行时` 有效。 # 语法 本框架中有两种语法,一种是 `模块语法` ,另一种是 `模板语法` 。 * `模块语法` ,就是调用模块时使用的语法,它们应当出现在 `Data` 目录中的模板文件里,完成模块对应的功能。 语法如下: **[ 模块名 >> 方法名 ( 传参数组 ) ]** **在详述之前,请先看一个例子:** 如果在模板文件中使用模块语法: **\$Post= [ Receive >> Post ( \$Config ) ] ;** 那么,将会调用 `Receive` 模块中的 `Post()` 方法,将参数 `$Config` 传入其中,并对POST接收到的表单数据进行处理,并将结果存储在 `$Post` 变量中( `$Post` 可以是任意的变量名)。 **来看一看编译之后的代码:** ```php LoadModule('Receive','Base'); $Post=$_SERVER['84PHP_MODULE']['Receive']->Post($Config); ``` 经过编译,框架自动请求了对应模块的物理路径,并自动判断了模块类别,即 `Base``Module` 模块,同时实例化了模块(类)和调用指定的方法。 **回过头看模块语法:** **[ 模块名 >> 方法名 ( 传参数组 ) ]** 如果模块中的方法没有返回值,或者您不需要模块的返回值,可以留空。 例如,在 `Vcode` 模块中使用 `Base()` 方法生成一个验证码,由于在Vcode模块中Base()方法是没有返回值的(也不需要获取返回值),那么: **[ Vcode >> Base () ]** 就可以完成方法的使用。 自4.0.0版本起,方法传参的方式调整为快捷传参,即通过数组 `array('参数名'=>[参数值])` 的方式进行传参。详情见各模块示例代码。 >w 传参数组中的键,即 `参数名` 还可以用 `中文参数名` 代替。 例如 `array('字段'=>'id')` 等同于 `array('field'=>'id')` ,增加代码可读性的同时减少记忆负担。 详情见各模块方法的参数说明。 * `模板语法` ,就是静态模板中的快捷语法,以HTML内嵌代码的形式实现PHP语言中的 `echo``if...else...``foreach` 等功能,并且可以嵌套结合使用。 它们应当出现在 `Template` 目录中的模板文件里。 和大多数框架类似,模板语法如下: 1. **输出变量**: ``` {变量} ``` 例如, ``` {$Var} ``` 等同于: ```php ``` 2. **if...else / if...else...语句**: ``` {if (条件)} [code] {else if (条件)} [code] {else} [code] {/if} ``` 例如, ``` {if ($Var==1) } Yes{$Var}. {else if ($Var==2) } Lucky{$Var}. {else} No. {/if} ``` 等同于: ```php Yes. Lucky. No. ``` 3. **Foreach(或loop)语句,其中数组元素的键为** `$Key` **,对应的值为** `$Val` : ``` {foreach 变量} [code] {/foreach} ``` 例如, ``` {foreach $Array } The key is {$Key}, and the value is {$Val}. {/foreach} ``` 等同于: ```php $Val){ ?> The key is , and the value is . ``` 4. **运行一段PHP代码**: ``` {? PHP代码 ?} ``` 例如, ``` {? echo 'Now timestamp is:'.time(); ?} ``` 等同于: ```php ``` >w 模板语法的语法规则存储于 `/Config/Cache.php` ,您可以自行设计语法。 # 模板 >d 自4.0.0版本起,已删除原 `Action` 目录。如需升级,将其中的文件移动到 `Data` 目录下即可。 >w 如果有更高的安全要求,可以将模板目录设置为其它名称,请参见文档《基础模块说明》中有关 `Cache` 模块的说明。 框架模板文件的默认路径是 `/Source` ,包含 `Data``Template` 两个目录。 浏览器访问时,在没有设置额外伪静态规则的情况下,Web目录下会有与之对应对应的实体文件。即访问 `yourdomain.com/a/test` 时,`/Temp/Cache` 目录下,目录 `a` 以及目录a中的 `test.php` 是真实存在的,而这些文件就是经过编译处理之后的文件。 * `Data` 目录,是操作数据的PHP代码存放的目录。 * `Template` 目录,是静态模板存放的目录,一般来说尽可能的少包含原生PHP代码,以便提高模板的移植性。 **两者之间的关系是:** 1. 假设 `Template` 目录有一个文件 `A.php` ,并且只是一个 `没有数据操作` 的页面,比如,仅仅是从SESSION中输出用户名 ``` {$_SESSION['username']} ``` ,而没有比如查询数据库这一类需要用到模块的复杂操作,则只需要建立 `Template/A.php` 即可,框架按照模板语法编译后将会在 `/Temp/Cache` 目录下生成 `A. php` 。 2. 假设 `Template` 目录中有文件 `B.php` 需要展示用户当前的余额$Count,而余额$Count `需要从数据库中查找最新数据` ,那么, 需要在Data目录下建立一个 `相同名称` 的文件,即建立 `Data/B.php` ,并在其中编写例如: ``` $Config = array( 'wherefield'=>'id', 'wherevalue'=>'3', 'wherefield'=>'=', ); $Count=[ Mysql >> Select($Config) ]; ``` 的代码并保存,然后建立 `Template/B.php` ,并在其中编写例如(假设余额存储在数据表字段 `total` 中): ``` {$Count['total']} ``` 的代码并保存,框架会将 `Data/B.php` 中出现的 `模块语法` 编译(编译完成的部分称作 `PartD` )、将 `Template/B.php` 按照 `模板语法` 编译(编译完成的部分称作 `PartT` ),随后框架将按照 `PartD` 在前、`PartT` 在后的规则,将这两部分编译后代码合并,最终在框架 `/Temp/Cache` 目录下生成 `B. php` 。 本示例编译后的 `B.php` 代码如下(已省略无关的代码): ```php 'id', 'wherevalue'=>'3', 'wherefield'=>'=', ); $Count=$_SERVER['84PHP_MODULE']['Mysql']->Select($Config); echo $Count['total']; ?> ``` **当仅仅需要操作数据,而不进行大量HTML输出时,比如判断用户是否登陆的代码,可以仅在 `Data` 目录下建立模板。** **下面是两者的关系图:** ![structure.png](https://img.cdn.bux.cn/open/84php/3.0.1/structure.png) >d 模板文件的文件类型为php,不支持修改,为了防止模板文件被访问,除了通过服务器设置访问规则外,请务必在每一个模板文件中加入: `exit;#` 这六个字符不能多也不能少,独占一行。作用是当用户访问模板文件时,由于存在exit;而停止运行。 这一行代码会在编译时被自动忽略,也就是说在/Cache目录下的文件中不会包含这六个字符。 >w `Data``Template` 目录中模板文件的路径要保持相同。 如 `Template/Test/A.php` 对应的文件是 `Data/Test/A.php` 。 模板文件相对于模板目录( `Data``Template` )的路径,也就是编译后文件相对于 `/Temp/Cache` 目录的路径。 # 缓存及自动编译 在 `/Temp/Cache` 下的所有文件均为经过编译的 `缓存文件` 。 框架具有自动编译机制,当调试模式 `开启` 时,所有模板文件中,如果存在模板文件的 `修改时间` 晚于缓存文件的修改时间,或者是存在 `尚未编译` 的模板文件时,则框架会对该模板自动进行编译。 >d 切勿直接修改缓存文件!这将会导致自动编译失效。 如遇此类情况,请修改模板文件,使得模板文件的修改时间 `晚于` 缓存文件,也可以删除 `/Cache` 目录下的对应文件进行缓存重建。 >w 框架具有无效缓存清空机制,当调试模式 `开启` 时,如果不存在缓存所对应的模板文件,则会 `清除` 对应的缓存。 即当您删除某个模板文件后,对应的缓存并不会同步清空。只有在该缓存被请求时,才会清除缓存,且该缓存不会被输出。 >w 当服务器调整系统时间后,或服务器时间异常时,可能会导致自动编译 `失效` 。框架会自动重置模板文件的修改时间来修复这个问题。如果仍然无法解决,请调整服务器时间,并清空 `/Temp/Cache` 目录下的所有文件,或者使用 `Cache` 模块重建缓存(详情见模块说明)。 >w 如果您的模板文件存在语法错误,例如出现两个;;符号,将会触发php系统级别的报错,且报错将会发生在自动编译模块运行之前。 遇到这样的情况,您可以在修改完模板文件中的错误代码之后,重新访问页面。 # 文件引入 在实际场景中往往需要使用 `require``include` 引入一些常用的文件,但由于框架的编译机制为被动触发编译,因此对于引入的文件,必须手动触发编译。即在引入代码前,通过 `Cache` 模块的 `Compile` 方法进行编译,详情请参见基础模块说明。 # 路由 框架的URI组成就是最原始的 `域名/文件相对路径` 模式。 其中 `文件相对路径` 指的是缓存文件相对于缓存目录的路径,同时也是模板文件相对于模板目录( `Data``Template` )的路径。 当访问时将首先在Web目录下寻找对应的文件,如果有则停止后续操作,因此如果有文件 `/Web/css/style.css` ,则直接访问 `域名/css/style.css` 即可。 上面这一步由服务器的伪静态规则完成,接下来的步骤将由框架完成。 当此路径是一个目录时,会优先寻找缓存目录中此路径下的 `index.php` ,等同于访问 `相对路径/index` 。 因此尽量不要把文件夹命名为 `index` ,因为会触发下一节将讲到的 `重名策略` 。 若未找到文件,将会尝试在缓存目录中的 `文件相对路径.php` 文件。 当找不到任何文件时,将触发报错。 >w 我们强烈建议页面使用 `原生URI` 形式,即 `?Field1=value1&...` 这样的形式传递参数,因为目前的搜索引擎已经能够解析URI参数而不影响SEO,且用户记忆URI中的参数的场景极少。 如果您依然需要对URI进行美化,请通过服务器的伪静态功能中的正则表达式完成操作,即使如此,服务器的操作效率通常比PHP高出20%以上。 # 重名策略 由于框架使用实体文件对应的缓存方式,因此对于文件名与目录名 `重名` 时采用了特定的处理策略。 如果存在 `a.php` ,且同级目录下存在文件 `a/index.php` ,即如下文件结构: ``` /Temp/Cache 缓存目录 ├─a │ └─index.php └─a.php ``` 当访问 `xxx.com/a` 时,运行的是 `a.php` 而非 `a/index.php` ,如果需要运行后者,请访问 `xxx.com/a/index` 。 缓存的编译/更新同样遵循上述策略。 # 报错机制 框架拥有完善的报错机制,报错信息的模板页位于 `/Core/Errors/html-style.php``/Core/Errors/json-style.php` 中,您可以自行替换,其中 `{$ErrorInfo}` 为报错信息显示的位置,`{$StatusCode}` 为状态码。 对于部分模块,当调试模式 `开启` 时,将会显示详细的报错信息和文件的路径、出错行号,否则将显示基本的错误码。错误码对应的详细错误信息,请在文档 `错误码查询` 中了解。 >w 如需显示JSON形式的报错信息,请在访问请求中添加 `X_REQUESTED_WITH = xmlhttprequest` 请求头。 >d 由于PHP语言的限制,有极少数在代码运行前的报错无法被捕获。此部分报错将由 `PHP系统` 完成。 如果您需要对您的应用添加自定义报错,请使用: ```php Wrong::Report(__FILE__,__LINE__,String类型的出错信息); ``` 上面的报错信息仅在调试模式 `开启` 时才会显示,如果您希望在调试模式关闭时也向访客显示出错信息,请使用: ```php Wrong::Report(__FILE__,__LINE__,String类型的出错信息, TRUE); ``` 默认的状态码是 `500` ,您也可以自定义状态码: ```php Wrong::Report(__FILE__,__LINE__,String类型的出错信息, 是否显示详细报错, 状态码); ``` 完成报错显示。 详情请参见基础模块说明。 # 升级 在 `4.0.0` 版本之后,如需升级最新版本的框架,仅需覆盖 `/Core` 路径下的全部文件,即可完成升级,模板 `无需改动` 。 如果新版本的框架代码中,更新了 `/Config` 下的文件, `请先更改配置项` ,之后再覆盖文件。 >d 强烈建议跟随官网的最新版本升级应用框架,您将会获得更丰富的功能、更优异的性能、更稳定的代码以及更坚固的安全防护。 >w 如果您是从 `2.x` 升级,请先按照本文档修改模板文件中方法的 `模块语法` 和模块的 `配置文件` 之后,替换所有文件。 请注意,自 `4.0.0` 版本起,框架的模块配置目录已由 `Public` 修改为 `Config` 。 同时,由于路由调整为单一入口模式,您还需要更新伪静态规则。 # 安全规范 **养成良好的编码习惯对于应用安全性的提升至关重要!** 以下是我们推荐的安全规范: * 必须对 `所有` 来自外部的输入通过Receive中的相应模块进行安全过滤!禁止直接使用php://input、$_REQUEST、$_GET、$_POST、$_COOKIE和直接输出用户上传的非二进制文件的内容; * 如果需要存储用户上传文件的原始文件名,请务必对文件名进 `安全过滤` ; * 尽可能的使用SESSION `而非` COOKIE来实现用户的登录状态保持; * 每一个模板文件必须添加 `exit;#` ; * 在生产环境下,务必 `关闭` 调试模式; * 尽量 `不要` 将用户输入的内容作为SQL语句中的字段操作,也就是说,如果需要操作由用户确定的字段,则应尽可能的预先定义好字段,通过数字编号代替。否则,请单独建立数据库,并建立限制权限的单独的数据库用户; * 请通过服务器端的伪静态设置,将非 `/Web` 目录以外的目录设置为禁止访问; * 请设置对应的HTTP403、404、500页面,而 `不显示` 服务器默认的错误页面; * 请特别关注 `HTTP403` 列出目录的安全隐患; * 请使用CDN/WAF完成服务器原始IP地址的隐藏及安全防护,同时建议在服务器上安装安全防护软件; * 关闭生产服务器服务器的 `22/3389` 端口; * 对用户上传目录取消执行权限; * 启用HTTPS。 # 高性能 以下是我们推荐的高性能架构规范: * 开启OPCache; * 尽可能地使用CDN,以降低源站 `带宽消耗` ; * 建议使用NoSQL对热点数据进行 `缓存` ; * 条件允许的话, `站库分离` 也是提升性能的好方法; * 不要在数据库SQL语句中进行多表联合查询或嵌套查询; * 尽可能地将计算过程交由 `代码层` 执行,而不是交给数据库; * 尽可能地避免调用远程API; * 对于网站应用,强烈推荐使用静态页+AJAX的方式进行构建; * 条件允许的话,使用对象存储或专门的存储服务器来接收上传的文件; * 将过于久远的数据转存到单独的数据库或者文本中。 # 版权声明&联系方式 > 本框架为免费开源、遵循Apache2开源协议的框架,但不得删除框架内文件的版权信息,违者必究。 > > This framework is free and open source, following the framework of Apache2 open source protocol, but the copyright information of files are not allowed to be deleted,violators will be prosecuted to the maximum extent possible. > > ©2020 Bux. All rights reserved. >w反馈Bug,可加入 `QQ群` 或发送邮件至 `tech@bux.cn` 进行反馈。