PHP代码审计——ThinkPHP基础
一、ThinkPHP概述
1. ThinPHP是一个轻量级的PHP框架,旨在提供快速开发Web应用程序的工具和资源。它采用了MVC(Model-View-Controller)架构,使开发人员可以更好地组织和管理代码。ThinPHP还提供了许多有用的功能,如路由、数据库抽象层、模板引擎等,使开发人员可以更快地构建Web应用程序。相比其他PHP框架,ThinPHP的优点在于它的轻量级和易用性。它的代码库非常小,因此可以快速下载和安装。它支持多种数据库(MySQL、PostgreSQL、SQLite等),同时还支持多种模板引擎(Smarty、Twig等)。此外,它还具有强大的缓存机制和安全性,提供了一些内置的安全功能,如防止SQL注入、XSS攻击、CSRF攻击等。
2. MVC是一种常见的软件设计模式,用于将应用程序分为三个主要组件:模型、视图和控制器。在ThinkPHP中,MVC是框架的核心,它使开发人员可以更好地组织和管理代码。
- 模型是应用程序的数据层,用于处理与数据库交互的所有操作。在ThinkPHP中,模型通常是一个继承自think\Model类的PHP类。模型类包含与数据库表对应的属性和方法,例如find、save和delete等方法。
- 视图是应用程序的表示层,用于呈现数据和用户界面。在ThinkPHP中,视图通常是一个包含HTML和PHP代码的模板文件。模板文件可以使用模板引擎来动态生成HTML代码,例如ThinkPHP的内置模板引擎Think\Template。
- 控制器是应用程序的业务逻辑层,用于处理用户请求并返回响应。在ThinkPHP中,控制器通常是一个继承自think\Controller类的PHP类。控制器类包含与用户请求对应的方法,例如index、login和register等方法。当用户发出请求时,控制器将根据请求的URL调用相应的方法,并将结果返回给用户。控制器还可以使用模型来访问数据库,并使用视图来呈现数据和用户界面。
3. 在MVC模式下,Web程序的功能通常在控制器部分实现。控制器是应用程序的业务逻辑层,用于处理用户请求并返回响应。它们是MVC架构的一部分,用于将应用程序的业务逻辑与其表示层分离。控制器通常包含与用户请求对应的方法,例如index、login和register等方法。当用户发出请求时,控制器将根据请求的URL调用相应的方法,并将结果返回给用户。控制器还可以使用模型来访问数据库,并使用视图来呈现数据和用户界面。因此,控制器是Web程序中实现功能的关键部分。这也说明,MVC模式的应用程序,其漏洞也通常在控制器下产生
二、ThinkPHP的目录结构与入口文件
1. 初始目录结果如下
www WEB部署目录(或者子目录)
├─application 应用目录
│ ├─common 公共模块目录(可以更改)
│ ├─module_name 模块目录
│ │ ├─config.php 模块配置文件
│ │ ├─common.php 模块函数文件
│ │ ├─controller 控制器目录
│ │ ├─model 模型目录
│ │ ├─view 视图目录
│ │ └─ ... 更多类库目录
│ │
│ ├─command.php 命令行工具配置文件
│ ├─common.php 公共函数文件
│ ├─config.php 公共配置文件
│ ├─route.php 路由配置文件
│ ├─tags.php 应用行为扩展定义文件
│ └─database.php 数据库配置文件
│
├─public WEB目录(对外访问目录)
│ ├─index.php 入口文件
│ ├─router.php 快速测试文件
│ └─.htaccess 用于apache的重写
│
├─thinkphp 框架系统目录
│ ├─lang 语言文件目录
│ ├─library 框架类库目录
│ │ ├─think Think类库包目录
│ │ └─traits 系统Trait目录
│ │
│ ├─tpl 系统模板目录
│ ├─base.php 基础定义文件
│ ├─console.php 控制台入口文件
│ ├─convention.php 框架惯例配置文件
│ ├─helper.php 助手函数文件
│ ├─phpunit.xml phpunit配置文件
│ └─start.php 框架入口文件
│
├─extend 扩展类库目录
├─runtime 应用的运行时目录(可写,可定制)
├─vendor 第三方类库目录(Composer依赖库)
├─build.php 自动生成定义文件(参考)
├─composer.json composer 定义文件
├─LICENSE.txt 授权说明文件
├─README.md README 文件
├─think 命令行入口文件
> router.php用于php自带webserver支持,可用于快速测试
> 切换到public目录后,启动命令:php -S localhost:8888 router.php
> 上面的目录结构和名称是可以改变的,这取决于你的入口文件和配置参数。
2. ThinkPHP的入口文件为public/index.php,实际部署网站的时候对外的访问目录为public,它负责处理所有进入应用程序的Web请求。每个请求都必须经过该文件进行路由和分发。 以下是该文件的基本结构:
<?php
define('APP_PATH', __DIR__ . '/../app/');
//定义应用程序运行时目录路径
define('RUNTIME_PATH', __DIR__ . '/../runtime/');
//加载框架的入口文件
require __DIR__ . '/../thinkphp/start.php';
- 第一行定义了应用程序根目录的路径。默认情况下,该路径设置为public目录的父目录,即应用程序的根目录。
- 第二行定义了应用程序运行时目录的路径。该目录用于存储框架生成的缓存文件和日志文件等运行时数据。 这一行代码有可能没有。
- 第三行加载框架的入口文件。该文件包含了所有必要的类和函数,以及自动加载器和错误处理程序等功能。
- 在入口文件加载完成后,它会调用框架核心的启动程序think\App::run()方法。该方法负责初始化应用程序,并将请求传递给路由处理程序进行路由匹配和分发。路由和分发过程完成后,应用程序执行对应的控制器和动作方法,并输出结果。
三、ThinkPHP的调试模式
1. 在应用程序的配置文件config/app.php中,修改debug选项为true,修改app_trace选项为true:
'debug' => true,
'app_trace' => true,
2. 然后当我们访问一个不存在或不正确的路由时,就会出现如下报错界面
四、ThinkPHP的URL访问模式
1. ThinkPHP在没有启用强制路由的情况下的典型访问URL为
http://serverName/index.php(或者其它应用入口文件)/模块/控制器/操作/[参数名/参数值...]
2. 支持切换到命令行访问,如果切换到命令行模式下面的访问规则是
php.exe index.php(或者其它应用入口文件) 模块/控制器/操作/[参数名/参数值...]
3. ThinkPHP5取消了URL模式的概念,普通的URL模式访问不再被支持,但参数可以通过普通URL模式传递
php.exe index.php(或者其它应用入口文件) 模块/控制器/操作?参数名=参数值&..
http://serverName/index.php(或者其它应用入口文件)?s=/模块/控制器/操作/[参数名/参数值...]
五、ThinkPHP的控制器
1. ThinkPHP的控制器是用于处理用户请求并返回响应的重要组成部分。它们是MVC架构的一部分,用于将应用程序的业务逻辑与其表示层分离。
- ThinkPHP的控制器负责处理请求并将响应数据返回给客户端。控制器是一个类,它继承了框架的基础控制器类。每个控制器都映射到一个URL路由,并包含一组动作方法来处理不同的请求。当请求发送到特定路由时,相应的控制器和动作方法将被调用。
- 在控制器中,开发者可以定义其控制器逻辑并与模型或应用程序的其他组件交互。控制器可以访问请求参数、会话数据和其他应用程序资源。
- ThinkPHP还提供了一种名为“约定优于配置”的特性,这意味着如果您遵循一定的控制器和动作方法的命名约定,框架将自动路由请求到正确的控制器和动作方法。
2. ThinkPHP默认的控制器为application/index/controller/index.php,我们可以在该文件中新建一个test方法
public function test(){
echo 'Hello, ThinkPHP!';
}
- 访问该方法需要定位到该函数的路由,否则直接访问将会报错,正确的路由如下
http://localhost/index.php/index/index/test
- 如下,成功访问application/index/controller/index.php中的test()方法
3. 要在ThinkPHP中创建一个控制器,只需要在application/index/controller目录下新建一个php文件,创建新的函数即可
- 例如,新建一个hello.php文件,写入如下代码
<?php
namespace app\index\controller; class Hello
{
public function index()
{
echo 'Hello, world!';
} public function hello()
{
echo 'Hello, Web Security!';
}
}
- 访问控制器路由
http://localhost/index.php/index/hello/hello
- 如下,成功访问hello.php中的hello方法
4. 标准的ThinkPHP的URL访问格式
http://domainName/index.php/模块/控制器/操作/[参数名/参数值...]
六、ThinkPHP的路由
1. 路由是指在应用程序中定义URL和请求处理程序之间的映射关系。在ThinkPHP中,路由是由应用程序的路由表配置文件定义的。路由表指定了不同的URL模式以及在处理不同URL时应该调用哪个控制器和方法。 ThinkPHP支持多种路由风格,例如传统的PathInfo模式、兼容模式(支持PathInfo和查询字符串)、路由模式(支持正则表达式)等。这些路由风格可以通过应用程序配置文件进行设置。 通过路由,您可以将URL重定向到特定的控制器和动作方法。此外,您还可以使用路由变量来匹配特定的URL模式,并将URL参数传递到控制器中。 总之,路由在ThinkPHP中是非常重要的,因为它指定了应用程序的URL结构和请求处理方式。通过设置路由,您可以实现可读性更好的URL,并促进应用程序的可维护性和可扩展性。
2. 详细说明介绍ThinkPHP的路由
- 首先,打开应用程序的路由配置文件config/route.php,添加以下内容:
use think\Route;
Route::get('user/:id', 'index/User/index');
- 在该例子中,我们创建了一条路由规则,该规则指定HTTP GET请求的URL必须由路由/user/:id匹配,并将匹配的请求转发到index控制器的User方法。 接下来,我们打开index控制器类的文件app\index\controller\User.php,添加以下代码:
namespace app\index\controller;
use think\Controller; class User extends Controller
{
public function index($id)
{
echo 'User ID: '.$id;
}
}
- 在该例子中,我们创建了名为User的控制器类,并在该类中创建了名为index的动作方法。该方法使用$id变量来接收通过路由传递的参数,并输出用户ID。
- 最后,打开Web浏览器并输入http://localhost/index.php/user/123,应用程序将输出“User ID: 123”。
七、ThinkPHP的参数传入
1. 首先,在路由配置文件config/route.php中添加以下代码:
use think\Route;
Route::get('blog/:id', 'blog/read', ['ext' => 'html'], ['id' => '\d+']);
2. 在该例子中,我们定义了一个路由规则,它允许HTTP GET请求匹配以“/blog/”开头,后跟数字参数的URL。规则将该请求传递到名为blog的控制器的名为read的动作方法。我们还指定了一个扩展名为“html”的参数,并使用正则表达式指定该参数必须是数字。 然后,我们在控制器文件app/controller/blog.php中添加以下代码:
<?php
namespace app\index\controller;
use think\Controller;
use think\Request; class Blog
{
public function read($id)
{
$request = Request::instance();
echo 'Blog ID: ' . $id . '<br/>';
echo 'Extension: ' . $request->ext() . '<br/>';
echo 'URL: ' . $request->url() . '<br/>';
}
}
3. 在该例子中,我们创建了一个名为Blog的控制器类,并在该类中创建了一个名为read的动作方法,该方法使用$id变量接收从路由传递的参数,并输出该参数,以及请求的扩展名和URL。 最后,我们可以在Web浏览器中输入以下URL进行测试:http://example.com/blog/123.html,应用程序将匹配路由规则并调用Blog控制器的read方法。方法将输出以下内容:
八、ThinkPHP的框架执行流程
1. 首先,Web服务器(如Apache或Nginx)将请求发送到应用程序的入口文件public/index.php,它位于应用程序根目录下。
// [ 应用入口文件 ]
// 定义应用目录
define('APP_PATH', __DIR__ . '/../application/');
// 加载框架引导文件
require __DIR__ . '/../thinkphp/start.php';
2. 入口文件初始化应用程序的核心实例化thinkphp/start.php,这将创建一个App对象并运行应用程序,最终输出响应内容。
namespace think; // ThinkPHP 引导文件
// 加载基础文件
require __DIR__ . '/../thinkphp/base.php';
//执行应用
think\App::run()->send();
3. 入口文件初始化应用程序的基础设置thinkphp/base.php,包括定义应用程序的常量和自动加载机制:
- 环境常量
- 载入Loader类
- 注册自动加载
- 注册错误和异常处理机制
- 加载惯例配置文件
4. 应用程序在运行时,先通过路由系统解析URL路径和请求方法,找到对应的控制器和方法,控制器文件和方法文件分别位于应用程序的controller和model目录下
5. thinkphp/library/think/App.php执行控制器的方法,生成响应内容
PHP代码审计——ThinkPHP基础的更多相关文章
- ThinkPHP -- 基础入门
ThinkPHP文件结构说明: |——ThinkPHP.php 框架入口文件 |——Common 框架公共文件目录 |——Conf ...
- thinkphp基础入门(2)
第一节介绍了thinkphp基本路径问题,第二节将介绍thinkphp的常见用法(M层跟V层) 我们先在Controller层新建个IndexController.class.php(新建文件的格式为 ...
- thinkphp基础入门(1)
ThinkPHP目录如下,Application顾名思义就是应用的意思(我们的代码放在这里),Public就是公共文件的意思(主要放JS CSS 等前端资源文件),ThinkPHP文件是框架的核心包( ...
- ThinkPHP基础知识
1.入口文件中定义的内容 // 检测PHP环境if(version_compare(PHP_VERSION,'5.3.0','<')) die('require PHP > 5.3.0 ! ...
- TP框架---thinkphp基础知识
php框架 发瑞 一.真实项目开发步骤: 多人同时开发项目,协作开发项目.分工合理.效率有提高(代码风格不一样.分工不好) 测试阶段 上线运行 对项目进行维护.修改.升级(单个人维护项目,十分困 ...
- ThinkPHP基础(1)
多层MVC模式 M:Model 数据模型层,负责数据操作 V:View 视图层,负责显示视图 C:Controller 控制器,实现业务逻辑 控制器访问及路由解析 通过url地址get参数找到指定的控 ...
- Thinkphp基础配置
访问项目中的index.phpApplication下会自动生成一些文件 在Application下建两个目录 一个Admin用来放后台中的文件 一个Public用来放公共文件 然后去Appplica ...
- thinkphp安装 版本 3.1.3
基础版: 只有thinkphp基础运行功能 完整版:基础运行能力,还有图片.上传等各种处理类(建议下载完整版) 重要的三个变量 define('APP_DEBUG',True); // 定义应用目录d ...
- (转) ThinkPHP模板自定义标签使用方法
这篇文章主要介绍了ThinkPHP模板自定义标签使用方法,需要的朋友可以参考下 转之--http://www.jb51.net/article/51584.htm 使用模板标签可以让网站前台开发 ...
- ThinkPHP 类似Yii的Gii生成Model的功能。
ThinkPHP 类似Yii的Gii生成Model的功能.自动生成ThinkPhp 3.1 的基础模型.. #!/usr/bin/env php <?php /** * * THINKPHP 基 ...
随机推荐
- Masa Framework源码解读-02缓存模块(分布式缓存进阶之多级缓存)
序言 今天这篇文章来看看Masa Framework的缓存设计,上一篇文章中说到的MasaFactory的应用也会在这章节出现.文章中如有错误之处还请指点,咱们话不多说,直入主题. Masa Fr ...
- 从操作实例“UI界面实现SSH登录服务器并执行命令监控”中学习到的线程与线程间参数传递方法记录
从操作实例"UI界面实现SSH登录服务器并执行命令监控"中学习到的线程与线程间参数传递方法记录: https://www.cnblogs.com/babashi9527/p/165 ...
- 65.C++的输入流和输出流
1.流的概念和流类库的结构 程序的输入指的是从输入文件将数据传送给程序,程序的输出指的是从程序将数据传送给输出文件. C++输入输出包含以下三个方面的内容: 对系统指定的标准设备的输入和输 ...
- Linux Bash Shell 中变量的 5 个易错点
Linux 中的 Bash 脚本支持对变量的操作,下面咸鱼将介绍 Linux Bash Shell 中关于变量的 5 个易错点 因为编程习惯,这类现象往往发生在大多数使用过其他流行编程语言的程序员身上 ...
- 你可能需要的 6 个 React 开发小技巧
这是一个可怕的问题,在React中,我们经常会编写条件语句来显示不同的视图,比如这个简单的例子. const App = () => { return ( <> { loadin ...
- 如何用Python对股票数据进行LSTM神经网络和XGboost机器学习预测分析(附源码和详细步骤),学会的小伙伴们说不定就成为炒股专家一夜暴富了
前言 最近调研了一下我做的项目受欢迎程度,大数据分析方向竟然排第一,尤其是这两年受疫情影响,大家都非常担心自家公司裁员或倒闭,都想着有没有其他副业搞搞或者炒炒股.投资点理财产品,未雨绸缪,所以不少小伙 ...
- [Windows]BAT脚本自定义函数
1 helloworld @echo off call :helloworld helloworld goto :EOF :helloworld setlocal echo %1 endlocal&a ...
- 《Flask Web 开发指南 pt.2》
哈喽大家好,我是咸鱼 在<Flask Web 开发指南 pt.1>中,咸鱼跟大家介绍了 Flask 的由来--诞生于一个愚人节玩笑,简单介绍了一些关于 Flask 的概念,并且编写了一个简 ...
- Java学习笔记13
1.Date类 1.1 概述 java.util.Date类表示特定的瞬间,精确到毫秒. 1.2 构造方法 Date类有多个构造方法,部分已经过时. 方法 作用 public Date() 从此刻 ...
- Java学习笔记02
1. 运算符和表达式 运算符 就是对常量或者变量进行操作的符号. 如:+ - * / 表达式 用运算符把常量或者变量连接起来的,符合Java语法的式子就是表达式. 如:a + b ...