搜索
首页头条图解ThinkPHP5框架(二):应用运行流程与生命周期

基于最新ThinkPHP5.0.8制定,原搞是xmind思维导图制作,如果觉得图片看不太清楚,可以下载xmind源文件,用xmind软件打开。

另外,思维导图中使用的源码,全部在导图备注中,只有下载了xmind源文件,才可以看到。

想自学ThinkPHP5开发的同学,一定不要错过这个福利。正在从事ThinkPHP5项目开发的程序员,可以收藏,以备查询

一、思维导图:

一张图让你完全搞懂ThinkPHP5框架

二、框架架构整体描述文字版:

框架架构

1 架构总览

1.1 基于MVC设计模式

1.1.1 Model:模型

1.1.2 View:视图

1.1.3 Controller:控制器

1.2 基于MVC的URL访问路由

1.2.1 http://域名/入口文件/模块/控制器/操作/参数/值...


1.3 入口文件

1.3.1 最常见:index.php

1.3.2 可以为模块绑定其它入口文件,如后:admin.php

1.4 应用App

1.4.1 管理框架生命周期的对象:\think\App类

1.4.2 由入口文件调用并执行

1.4.3 具有相同的APP_PATH应用目录的,视为同一个应用

1.4.4 一个应用可以有多个入口,例如前台为index.php,后台为admin.php

1.4.5 应用有自己独立的配置文件与公共函数文件


1.5 模块Module

1.5.1 一个应用通常是由多个模块组成

1.5.2 一个模块通常是应用目录中一个子目录: app/index/

1.5.3 模块通常由多个控制器类文件组成,可以将这些类以目录方式管理

1.5.4 简单应用,可不创建模块目录,使用单模块架构,在应用配置中关闭多模块支持: 'app_multi_module'=>false

1.5.5 模块也可有自己独立的配置文件和公共文件、类库文件


1.6 控制器Controller

1.6.1 控制器负责响应用户的请求,调用模型处理,选择视图输出,不应介入业务处理

1.6.2 每个控制器其实就是一个类文件: Index.php

1.6.3 5.0开始,控制器不用继承任何父类就可以正常工作

<?php
namespace app\index\controller; class Index {
public function index()
   {
      return &#39;hello,thinkphp!&#39;;
   } 
}


1.7 操作Action

1.7.1 一个控制器包括多个操作方法,操作方法是URL访问的最小单元

1.7.2 操作方法如果要求参数,则必须传入:$_GET或$_POST

<?php
namespace app\index\controller; class Index {
public function index() {
return &#39;index&#39;; } public function hello($name) {
return &#39;Hello,&#39;.$name; }
}

1.8 模型Model

1.8.1 完成实际的业务逻辑和数据封装,并返回与格式 无关的数据

1.8.2 模型支持分层设计:逻辑层/服务层/事件层

1.8.3 模型类不一定要访问数据库,只有CURD操作时才连接,是真正的惰性连接

1.9 视图View

1.9.1 控制器调用模型类返回的数据,要通视图类包装成不同的格式返回。

1.9.2 可根据需求确定是直接渲染还是用模板输出

1.9.3 视图有一系列的模板文件与控制器中的操作对应

1.9.4 可以在操作方法中动态设置模板目录


1.10 命名空间NameSpace

1.10.1 命名空间主要用在框架的类库文件中

1.10.2 命名空间必须符合PSR-4的自动加载机制:空间名与类的路径对应


2 生命周期

2.1 入口文件index.php

2.1.1 位置: public/index.php

2.1.2 入口文件中通常只定义常量和加载框架引导文件

<?php
// 应用入口文件
// 定义项目路径 
define(&#39;APP_PATH&#39;, __DIR__ . &#39;/../application/&#39;); 
// 加载框架引导文件 
require __DIR__ . &#39;/../thinkphp/start.php&#39;;

2.2 引导文件:start.php

<?php
namespace think;
// ThinkPHP 引导文件
// 加载基础文件
require __DIR__ . &#39;/base.php&#39;;
// 执行应用
App::run()->send();


2.2.1 加载base.php

<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------

define(&#39;THINK_VERSION&#39;, &#39;5.0.5&#39;);
define(&#39;THINK_START_TIME&#39;, microtime(true));
define(&#39;THINK_START_MEM&#39;, memory_get_usage());
define(&#39;EXT&#39;, &#39;.php&#39;);
define(&#39;DS&#39;, DIRECTORY_SEPARATOR);
defined(&#39;THINK_PATH&#39;) or define(&#39;THINK_PATH&#39;, __DIR__ . DS);
define(&#39;LIB_PATH&#39;, THINK_PATH . &#39;library&#39; . DS);
define(&#39;CORE_PATH&#39;, LIB_PATH . &#39;think&#39; . DS);
define(&#39;TRAIT_PATH&#39;, LIB_PATH . &#39;traits&#39; . DS);
defined(&#39;APP_PATH&#39;) or define(&#39;APP_PATH&#39;, dirname($_SERVER[&#39;SCRIPT_FILENAME&#39;]) . DS);
defined(&#39;ROOT_PATH&#39;) or define(&#39;ROOT_PATH&#39;, dirname(realpath(APP_PATH)) . DS);
defined(&#39;EXTEND_PATH&#39;) or define(&#39;EXTEND_PATH&#39;, ROOT_PATH . &#39;extend&#39; . DS);
defined(&#39;VENDOR_PATH&#39;) or define(&#39;VENDOR_PATH&#39;, ROOT_PATH . &#39;vendor&#39; . DS);
defined(&#39;RUNTIME_PATH&#39;) or define(&#39;RUNTIME_PATH&#39;, ROOT_PATH . &#39;runtime&#39; . DS);
defined(&#39;LOG_PATH&#39;) or define(&#39;LOG_PATH&#39;, RUNTIME_PATH . &#39;log&#39; . DS);
defined(&#39;CACHE_PATH&#39;) or define(&#39;CACHE_PATH&#39;, RUNTIME_PATH . &#39;cache&#39; . DS);
defined(&#39;TEMP_PATH&#39;) or define(&#39;TEMP_PATH&#39;, RUNTIME_PATH . &#39;temp&#39; . DS);
defined(&#39;CONF_PATH&#39;) or define(&#39;CONF_PATH&#39;, APP_PATH); // 配置文件目录
defined(&#39;CONF_EXT&#39;) or define(&#39;CONF_EXT&#39;, EXT); // 配置文件后缀
defined(&#39;ENV_PREFIX&#39;) or define(&#39;ENV_PREFIX&#39;, &#39;PHP_&#39;); // 环境变量的配置前缀

// 环境常量
define(&#39;IS_CLI&#39;, PHP_SAPI == &#39;cli&#39; ? true : false);
define(&#39;IS_WIN&#39;, strpos(PHP_OS, &#39;WIN&#39;) !== false);

// 载入Loader类
require CORE_PATH . &#39;Loader.php&#39;;

// 加载环境变量配置文件
if (is_file(ROOT_PATH . &#39;.env&#39;)) {
    $env = parse_ini_file(ROOT_PATH . &#39;.env&#39;, true);
    foreach ($env as $key => $val) {
        $name = ENV_PREFIX . strtoupper($key);
        if (is_array($val)) {
            foreach ($val as $k => $v) {
                $item = $name . &#39;_&#39; . strtoupper($k);
                putenv("$item=$v");
            }
        } else {
            putenv("$name=$val");
        }
    }
}

// 注册自动加载
\think\Loader::register();

// 注册错误和异常处理机制
\think\Error::register();

// 加载惯例配置文件
\think\Config::set(include THINK_PATH . &#39;convention&#39; . EXT);


2.2.1.1 加载系统常量定义

2.2.1.2 加载环境变量定义文件

2.2.1.3 注册自动加载机制

2.2.1.3.1 调用Loader::register(),加载符合规范类库及第三方类库

2.2.1.3.2 自动加载的内容

2.2.1.3.2.1 注册系统的自动加载方法 \think\Loader::autoload

2.2.1.3.2.2 注册系统命名空间定义

2.2.1.3.2.3 加载类库映射文件(如果存在)

2.2.1.3.2.4 如果存在 Composer 安装,则注册 Composer 自动加载

2.2.1.3.2.5 注册 extend 扩展目录


2.2.1.3.3 类库自动加载的检测顺序

2.2.1.3.3.1 是否定义类库映射

2.2.1.3.3.2 PSR-4 自动加载检测

2.2.1.3.3.3 PSR-0 自动加载检测

2.2.1.4 注册错误和异常处理机制

2.2.1.4.1 执行 Error::register() 注册,由三部分组成

2.2.1.4.1.1 应用关闭方法: think\Error::appShutdown

2.2.1.4.1.2 错误处理方法: think\Error::appError

2.2.1.4.1.3 异常处理方法: think\Error::appException

2.2.1.5 加载惯例配置文件

2.2.1.5.1 \think\Config::set(include THINK_PATH . 'convention' . EXT);

2.2.2 执行应用:App::run()->send();

2.2.2.1 App::run()输入Request对象,返回Response对象

2.2.2.2 Response::send():发送数据到客户端

2.3 应用初始化:App::initCommon()和init()方法

/**
     * 初始化应用
     */
    public static function initCommon()
    {
        if (empty(self::$init)) {
            // 初始化应用
            $config       = self::init();
            self::$suffix = $config[&#39;class_suffix&#39;];

            // 应用调试模式
            self::$debug = Env::get(&#39;app_debug&#39;, Config::get(&#39;app_debug&#39;));
            if (!self::$debug) {
                ini_set(&#39;display_errors&#39;, &#39;Off&#39;);
            } elseif (!IS_CLI) {
                //重新申请一块比较大的buffer
                if (ob_get_level() > 0) {
                    $output = ob_get_clean();
                }
                ob_start();
                if (!empty($output)) {
                    echo $output;
                }
            }

            // 注册应用命名空间
            self::$namespace = $config[&#39;app_namespace&#39;];
            Loader::addNamespace($config[&#39;app_namespace&#39;], APP_PATH);
            if (!empty($config[&#39;root_namespace&#39;])) {
                Loader::addNamespace($config[&#39;root_namespace&#39;]);
            }

            // 加载额外文件
            if (!empty($config[&#39;extra_file_list&#39;])) {
                foreach ($config[&#39;extra_file_list&#39;] as $file) {
                    $file = strpos($file, &#39;.&#39;) ? $file : APP_PATH . $file . EXT;
                    if (is_file($file) && !isset(self::$file[$file])) {
                        include $file;
                        self::$file[$file] = true;
                    }
                }
            }

            // 设置系统时区
            date_default_timezone_set($config[&#39;default_timezone&#39;]);

            // 监听app_init
            Hook::listen(&#39;app_init&#39;);

            self::$init = true;
        }
        return Config::get();
    }

    /**
     * 初始化应用或模块
     * @access public
     * @param string $module 模块名
     * @return array
     */
    private static function init($module = &#39;&#39;)
    {
        // 定位模块目录
        $module = $module ? $module . DS : &#39;&#39;;

        // 加载初始化文件
        if (is_file(APP_PATH . $module . &#39;init&#39; . EXT)) {
            include APP_PATH . $module . &#39;init&#39; . EXT;
        } elseif (is_file(RUNTIME_PATH . $module . &#39;init&#39; . EXT)) {
            include RUNTIME_PATH . $module . &#39;init&#39; . EXT;
        } else {
            $path = APP_PATH . $module;
            // 加载模块配置
            $config = Config::load(CONF_PATH . $module . &#39;config&#39; . CONF_EXT);
            // 读取数据库配置文件
            $filename = CONF_PATH . $module . &#39;database&#39; . CONF_EXT;
            Config::load($filename, &#39;database&#39;);
            // 读取扩展配置文件
            if (is_dir(CONF_PATH . $module . &#39;extra&#39;)) {
                $dir   = CONF_PATH . $module . &#39;extra&#39;;
                $files = scandir($dir);
                foreach ($files as $file) {
                    if (strpos($file, CONF_EXT)) {
                        $filename = $dir . DS . $file;
                        Config::load($filename, pathinfo($file, PATHINFO_FILENAME));
                    }
                }
            }

            // 加载应用状态配置
            if ($config[&#39;app_status&#39;]) {
                $config = Config::load(CONF_PATH . $module . $config[&#39;app_status&#39;] . CONF_EXT);
            }

            // 加载行为扩展文件
            if (is_file(CONF_PATH . $module . &#39;tags&#39; . EXT)) {
                Hook::import(include CONF_PATH . $module . &#39;tags&#39; . EXT);
            }

            // 加载公共文件
            if (is_file($path . &#39;common&#39; . EXT)) {
                include $path . &#39;common&#39; . EXT;
            }

            // 加载当前模块语言包
            if ($module) {
                Lang::load($path . &#39;lang&#39; . DS . Request::instance()->langset() . EXT);
            }
        }
        return Config::get();
    }

 

2.3.1.1 定位模块目录

2.3.1.2 加载初始化文件

2.3.1.2.1 加载模块配置

2.3.1.2.2 读取数据库配置文件

2.3.1.2.3 读取扩展配置文件

2.3.1.2.4 加载应用状态配置

2.3.1.2.5 加载行为扩展文件

2.3.1.2.6 加载公共文件

2.3.1.2.7 加载当前模块语言包

2.3.2 检测应用调试模式:self::$debug = Env::get('app_debug', Config::get('app_debug'));

2.3.3 注册应用命名空间:self::$namespace = $config['app_namespace'];

2.3.4 加载额外文件:'extra_file_list'

2.3.5 设置系统时区:date_default_timezone_set($config['default_timezone']);

2.3.6 监听app_init:  Hook::listen('app_init');

2.3.7 返回所有配置项:return Config::get();

2.4 URL访问检测:

2.4.1 PATH_INFO:http://serverName/index.php/index/index/hello/val/value

2.4.2 兼容方式:http://serverName/index.php?s=/index/index/hello&val=value

2.5 路由检测:App::routeCheck($request, array $config)与设置路由机制:route($route, $must = false)

/**
     * URL路由检测(根据PATH_INFO)
     * @access public
     * @param  \think\Request $request
     * @param  array          $config
     * @return array
     * @throws \think\Exception
     */
    public static function routeCheck($request, array $config)
    {
        $path   = $request->path();
        $depr   = $config[&#39;pathinfo_depr&#39;];
        $result = false;
        // 路由检测
        $check = !is_null(self::$routeCheck) ? self::$routeCheck : $config[&#39;url_route_on&#39;];
        if ($check) {
            // 开启路由
            if (is_file(RUNTIME_PATH . &#39;route.php&#39;)) {
                // 读取路由缓存
                $rules = include RUNTIME_PATH . &#39;route.php&#39;;
                if (is_array($rules)) {
                    Route::rules($rules);
                }
            } else {
                $files = $config[&#39;route_config_file&#39;];
                foreach ($files as $file) {
                    if (is_file(CONF_PATH . $file . CONF_EXT)) {
                        // 导入路由配置
                        $rules = include CONF_PATH . $file . CONF_EXT;
                        if (is_array($rules)) {
                            Route::import($rules);
                        }
                    }
                }
            }

            // 路由检测(根据路由定义返回不同的URL调度)
            $result = Route::check($request, $path, $depr, $config[&#39;url_domain_deploy&#39;]);
            $must   = !is_null(self::$routeMust) ? self::$routeMust : $config[&#39;url_route_must&#39;];
            if ($must && false === $result) {
                // 路由无效
                throw new RouteNotFoundException();
            }
        }
        if (false === $result) {
            // 路由无效 解析模块/控制器/操作/参数... 支持控制器自动搜索
            $result = Route::parseUrl($path, $depr, $config[&#39;controller_auto_search&#39;]);
        }
        return $result;
    }

    /**
     * 设置应用的路由检测机制
     * @access public
     * @param  bool $route 是否需要检测路由
     * @param  bool $must  是否强制检测路由
     * @return void
     */
    public static function route($route, $must = false)
    {
        self::$routeCheck = $route;
        self::$routeMust  = $must;
    }
}

2.5.1 路由到模块/控制器/操作

2.5.2 路由到外部重定向地址;

2.5.3 路由到控制器方法;

2.5.4 路由到闭包函数;

2.5.5 路由到类的方法;

2.6 请求分发与响应输出:Response::send()

2.6.1 控制器的所有操作方法都是 return 返回而不是直接输出

2.6.2 自动转换成 default_return_type 参数配置的格式

2.7 应用结束,写入日志

2.7.1 系统的日志包括用户调试输出的和系统自动生成的日志,统一会在应用结束的时候进行写入操作

2.7.2 日志的写入操作受日志初始化的影响

3 入口文件

3.1 采用单一入口模式进行项目部署(并非唯一入口)

3.2 不同应用对应不同入口,但入口文件内容和功能基本一致

3.3 入口文件内容

<?php
// 定义应用目录 
define(&#39;APP_PATH&#39;, __DIR__ . &#39;/../application/&#39;); 
// 加载框架引导文件 
require __DIR__ . &#39;/../thinkphp/start.php&#39;;

3.3.1 定义应用目录:define('APP_PATH', __DIR__ . '/../application/');

3.3.2 定义系统常量:define('CONF_PATH', __DIR__ . '/../config/');

3.3.3 加载框架引导文件: require __DIR__ . '/../thinkphp/start.php';

3.4 入口文件位于public目录下

3.4.1 这是为了让应用部署更安全

3.4.2 public必须是Web可访问目录

3.4.3 其实文件或目录应该放在非Web访问目录下面


4 URL访问

4.1 URL设计

4.1.1 PATH_INFO:http://index.php/模块/控制器/操作/[参数名/参数值...]

4.1.2 兼容模型:http://index.php?s=/模块/控制器/操作/[参数名/参数值...]

4.1.3 不支持普通URL模式,但传参可以:http://index.php/module/controller/action?id=10

4.1.4 URL默认不区分大小写,都会转为小写的,控制器部分自动转为驼峰法处理

4.2 隐藏入口文件

4.2.1 隐藏入口文件,可优化URL,网站更安全

4.2.2 在入口文件同级:public/.htaccess

4.2.3 Apache配置文件httpd.conf加载:mod_rewrite.so模块,支持URL重写

4.2.4 httpd.conf:AllowOverride None 将None设置为 All


5 模块设计

5.1 默认为多模块,支持单一模块设计 

5.2 模块命名空间均为app为根空间

5.3 模块可以看作是类库的集合:控制器类,模型类

5.4 模块类库:app\模块名\类库\类名

5.5 入口文件中隐藏模块和控制器


由于默认是采用多模块的支持,所以多个模块的情况下必须在URL地址中标识当前模块,如果只有一个模块的 话,可以进行模块绑定,方法是应用的入口文件中添加如下代码:

// 绑定当前访问到index模块 define('BIND_MODULE','index');

绑定后,我们的URL访问地址则变成:

http://serverName/index.php/控制器/操作/[参数名/参数值...]

访问的模块是 index 模块。 如果你的应用比较简单,模块和控制器都只有一个,那么可以在应用公共文件中绑定模块和控制器,如下:

// 绑定当前访问到index模块的index控制器 define('BIND_MODULE','index/index');

设置后,我们的URL访问地址则变成:

http://serverName/index.php/操作/[参数名/参数值...]

访问的模块是 index 模块,控制器是 Index 控制器。

5.5.1 绑定当前访问的模块:define('BIND_MODULE','index');

5.5.2 绑定当前访问的模块和控制器:define('BIND_MODULE','userlogin/getname');

5.6 单一模块设计:'app_multi_module'=>false,

5.6.1 可以把应用目录当作模块目录

5.6.2 模块中的控制器命名空间也要调整

6 命名空间

6.1 命名空间的路径与类库文件的目录一致,可以实现类的自动加载(惰性加载)

6.2 根命名空间:类库包

6.2.1 think:系统核心类库 (think/library/think)

6.2.2 traits:系统trait类库(think/library/traits)

6.2.3 app:应用类库(application)

6.2.4 自定义根命名空间

6.2.4.1 默认加载EXTEND_APTH目录中的类库,目录名为根

我们只需要把自己的类库包目录放入 EXTEND_PATH 目录(默认为 extend ,可配置),就可以自动注册对 应的命名空间,例如:

我们在 extend 目录下面新增一个 my 目录,然后定义一个 \my\Hello 类( 类文件位于 extend/my/Hello.php )如下:

<?php
namespace my;
class Hello
{
  public function  index()
  {
    return &#39;hello tp5&#39;;
  }
}

我们就可以在控制器中,直接实例化和调用:

<?php
namespace app\index\controller;
class Index
{
    public function index()
    {
      $obj = new \my\Hello();
       return   $obj->index();
    }
}

6.2.4.2 可在入口文件中重新定义:define('EXTEND_PATH','../vendor/');

6.2.4.3 手动注册根命名空间

6.2.4.3.1 应用公共文件:common.php中添加如代码:

在应用公共文件中添加下面的代码:

\think\Loader::addNamespace(&#39;my&#39;,&#39;../application/extend/my/&#39;);

如果要同时注册多个根命名空间,可以使用:

\think\Loader::addNamespace([ &#39;my&#39; => &#39;../application/extend/my/&#39;, &#39;org&#39; => &#39;../application/extend/org/&#39;, ]);

6.2.4.3.2 应用配置文件:config.php中添加:

可以直接在应用的配置文件中添加配置,系统会在应用执行的时候自动注册。

&#39;root_namespace&#39; => [ &#39;my&#39; => &#39;../application/extend/my/&#39;, &#39;org&#39; => &#39;../application/extend/org/&#39;, ]

6.3 可以给命名空间创建别名

6.3.1 应用公共文件common.php


7 trait引入

7.1 trait提供了一种代码复用机制,是类的公共方法集,与继承相比,相当于横向扩展了类的功能

7.2 PHP5.4使用load_trait()引入,PHP5.5以上可以直接自动加载

但由于PHP5.4版本不支持 trait 的自动加载,因此如果是PHP5.4版本,必须手动导入 trait 类库,系统 提供了一个助手函数 load_trait ,用于自动加载 trait 类库,例如,可以这样正确引入 trait 类库。

namespace app\index\controller; load_trait(&#39;controller/Jump&#39;); class index {
// 引入traits\controller\Jump
use \traits\controller\Jump; public function index() {
$this->assign(&#39;name&#39;,&#39;value&#39;);
$this->show(&#39;index&#39;); }
}

如果你的PHP版本大于 5.5 的话,则可以省略 load_trait 函数引入 trait 。

namespace app\index\controller; class index {
use \traits\controller\Jump;
public function index()
{
}
 }

可以支持同时引入多个 trait 类库,例如:

namespace app\index\controller; load_trait(&#39;controller/Other&#39;); load_trait(&#39;controller/Jump&#39;); class index
{
use \traits\controller\Other; use \traits\controller\Jump; public function index() { }
}

或者使用

namespace app\index\controller; load_trait(&#39;controller/Other&#39;); load_trait(&#39;controller/Jump&#39;); class index {
use \traits\controller\Other,\traits\controller\Jump;
public function index()
{
} 
}


7.3 trait命名冲突的解决方案

7.3.1 insteadof:冲突时指定使用哪一个trait类

7.3.2 as:将另一个冲突的trait类以别名的方式访问

8 API友好

8.1 数据输出

8.1.1 控制器中数据输出统一用Response类处理,并不直接输出

8.1.2 设置 default_return_type 或者动态设置不同类型的 Response 输出就可以自动进行数据转换

8.1.3 大多数情况下,你只需要在控制器中返回字符串或者数组即可

8.1.4 默认为html,可在配置文件中:'default_return_type'=>'json'

8.2 错误调试


8.2.1 Trace 调试功能支持 Socket 在内的方 式,可以实现远程的开发调试


三、ThinkPHP5框架思维导图下载地址:

图解ThinkPHP5框架(二):应用运行流程与生命周期2框架架构.xmind.zip

【相关推荐】

1. 图解ThinkPHP5框架(一):基础知识,开发规范与目录结构

2. 图解ThinkPHP5框架(三):配置类Config.php源码解读

3. 2017年最新的10个thinkphp视频教程推荐

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
宝塔部署thinkphp5报错怎么办宝塔部署thinkphp5报错怎么办Dec 19, 2022 am 11:04 AM

宝塔部署thinkphp5报错的解决办法:1、打开宝塔服务器,安装php pathinfo扩展并启用;2、配置“.access”文件,内容为“RewriteRule ^(.*)$ index.php?s=/$1 [QSA,PT,L]”;3、在网站管理里面,启用thinkphp的伪静态即可。

thinkphp5 post得不到值怎么办thinkphp5 post得不到值怎么办Dec 06, 2022 am 09:29 AM

thinkphp5 post得不到值是因为TP5是通过strpos函数在Header的content-type值中查找app/json字符串的,其解决办法就是设置Header的content-type值为app/json即可。

thinkphp5 url重写不行怎么办thinkphp5 url重写不行怎么办Dec 12, 2022 am 09:31 AM

thinkphp5 url重写不行的解决办法:1、查看httpd.conf配置文件中是否加载了mod_rewrite.so模块;2、将AllowOverride None中的None改为All;3、修改Apache配置文件.htaccess为“RewriteRule ^(.*)$ index.php [L,E=PATH_INFO:$1]”保存即可。

thinkphp5怎么获取请求过来的网址thinkphp5怎么获取请求过来的网址Dec 20, 2022 am 09:48 AM

thinkphp5获取请求网址的方法:1、使用“\think\Request”类的“$request = Request::instance();”方法获取当前的url信息;2、通过自带的助手函数“$request->url()”获取包含域名的完整URL地址。

怎么去除thinkphp5标题栏icon怎么去除thinkphp5标题栏iconDec 20, 2022 am 09:24 AM

去除thinkphp5标题栏icon的方法:1、找到thinkphp5框架public下的favicon.ico文件;2、删除该文件或者选择另一张图片命名改为favicon.ico,并替换原favicon.ico文件即可。

thinkphp5提示控制器不存在怎么办thinkphp5提示控制器不存在怎么办Dec 06, 2022 am 10:43 AM

thinkphp5提示控制器不存在的解决办法:1、检查对应的控制器里面的命名空间是否写对,修改为正确的命名空间;2、打开相应的tp文件,修改类名即可。

ThinkPHP5怎么查询昨天的数据ThinkPHP5怎么查询昨天的数据Dec 05, 2022 am 09:20 AM

ThinkPHP5查询昨天数据的方法:1、打开ThinkPHP5相关文件;2、通过表达式“db('table')->whereTime('c_time', 'yesterday')->select();”查询昨天的数据即可。

thinkphp5报错提示怎么设置thinkphp5报错提示怎么设置Dec 07, 2022 am 10:31 AM

thinkphp5设置报错提示的方法:1、进入项目根目录下的public文件夹,打开index.php入口文件;2、查看调试模式开关的注释;3、将“APP_DEBUG”常量的值调整为true即可展示错误信息提示。

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
2 周前By尊渡假赌尊渡假赌尊渡假赌
仓库:如何复兴队友
4 周前By尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒险:如何获得巨型种子
4 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

SublimeText3 英文版

SublimeText3 英文版

推荐:为Win版本,支持代码提示!

EditPlus 中文破解版

EditPlus 中文破解版

体积小,语法高亮,不支持代码提示功能

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版