Maison  >  Article  >  Framework ThinkPHP5 illustré (2) : processus d'exécution et cycle de vie de l'application

Framework ThinkPHP5 illustré (2) : processus d'exécution et cycle de vie de l'application

天蓬老师
天蓬老师original
2017-05-18 11:45:055573parcourir

Basé sur le dernier ThinkPHP 5.0.8, il a été initialement produit par xmind mind map. Si vous sentez que l'image n'est pas claire, vous pouvez télécharger le fichier source de xmind et l'ouvrir avec le logiciel xmind.

De plus, le code source utilisé dans la carte mentale est entièrement dans les notes de la carte. Vous ne pouvez le voir que si vous téléchargez le fichier source xmind.

Les étudiants qui souhaitent apprendre le développement ThinkPHP5 par eux-mêmes ne doivent pas manquer cet avantage. Les programmeurs qui travaillent actuellement sur le développement du projet ThinkPHP5 peuvent le sauvegarder pour référence future

1. Carte mentale :

Framework ThinkPHP5 illustré (2) : processus dexécution et cycle de vie de lapplication

2. Version texte de la description générale de l'architecture du framework :

Architecture du framework

1 Présentation de l'architecture

1.1 Basé sur le modèle de conception MVC

1.1.1 Modèle : Modèle

1.1.2 View:View

1.1.3 Contrôleur : Contrôleur

1.2 Routage d'accès URL basé sur MVC

1.2.1 http:/ /nom de domaine/ Fichier d'entrée/module/contrôleur/opération/paramètre/valeur...


1.3 Fichier d'entrée

1.3.1 La plupart commun : index .php

1.3.2 Vous pouvez lier d'autres fichiers d'entrée au module, tels que : admin.php

1.4 Application App

1.4.1 Objets qui gèrent le cycle de vie du framework : classe thinkApp

1.4.2 Appelés et exécutés par le fichier d'entrée

1.4.3 Les répertoires d'application avec le même APP_PATH sont considérés comme identiques application

1.4.4 Une application peut avoir plusieurs entrées, telles que index.php dans le frontend et admin.php dans le backend

1.4.5 L'application possède son propre fichier de configuration indépendant et fichier de fonction publique


1.5 Module

1.5.1 Une application est généralement composée de plusieurs modules

1.5.2 Un module est généralement un sous-répertoire dans le répertoire de l'application : app/index/

1.5.3 Les modules sont généralement composés de plusieurs fichiers de classes de contrôleur Ces classes peuvent être gérées dans des répertoires

1.5.4 Pour les applications simples, vous n'avez pas besoin de créer un répertoire de modules. Utilisez une architecture de module unique et désactivez la prise en charge de plusieurs modules dans la configuration de l'application : 'app_multi_module'=>false

1.5.5 Les modules peuvent également avoir leur propre répertoire indépendant. fichiers de configuration, fichiers publics et fichiers de bibliothèque de classes


1.6 Contrôleur

1.6.1 Le contrôleur est chargé de répondre aux demandes des utilisateurs, d'appeler le traitement du modèle, en sélectionnant la vue sortie, et ne doit pas intervenir dans le traitement métier

1.6.2 Chaque contrôleur est en fait un fichier de classe : Index.php

1.6.3 À partir de la version 5.0, le contrôleur peut fonctionner normalement sans hériter d'une classe parent

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


1.7 Action

1.7.1 Un contrôleur comprend plusieurs méthodes d'opération, et la méthode d'opération est la plus petite unité d'URL accès

1.7.2 Méthode de fonctionnement si nécessaire Les paramètres doivent être transmis dans : $_GET ou $_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 Modèle Modèle

1.8.1 Compléter l'activité réelle encapsulation de la logique et des données, et renvoi de données indépendantes du format

1.8.2 Le modèle prend en charge la conception en couches : couche logique/couche de service/couche d'événements

1.8.3 La classe de modèle n'a pas à accéder à la base de données. Elle est connectée uniquement pour les opérations CURD, qui est vraiment inerte Connexion

1.9 View View

1.9.1 Les données renvoyées par le contrôleur appelant la classe modèle doivent être empaquetées dans. différents formats par la classe de vue et renvoyés.

1.9.2 Vous pouvez déterminer s'il faut effectuer le rendu directement ou utiliser la sortie du modèle en fonction de vos besoins

1.9.3 La vue contient une série de fichiers modèles correspondant aux opérations dans le contrôleur

1.9.4 Le répertoire des modèles peut être défini dynamiquement dans la méthode d'opération


1.10 NameSpace NameSpace

1.10.1 Namespace est principalement utilisé dans le fichier bibliothèque de classes du framework

1.10.2 L'espace de noms doit être conforme au mécanisme de chargement automatique du PSR-4 : le nom de l'espace correspond au chemin de la classe


2 Cycle de vie

2.1 Fichier d'entrée index.php

2.1.1 Emplacement : public/index.php

2.1.2 Le fichier d'entrée généralement uniquement définit les constantes et charge le fichier de démarrage du framework

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

2.2 Fichier de démarrage : start.php

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


2.2.1 Charger la 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 Charger les définitions de constantes système

2.2.1.2 Charger les fichiers de définition de variables d'environnement

2.2.1.3 Enregistrez le mécanisme de chargement automatique

2.2.1.3. 1 Appelez Loader::register() pour charger les bibliothèques de classes standard et les bibliothèques de classes tierces

2.2.1.3.2 Contenu chargé automatiquement

2.2.1.3.2.1 Chargement automatique de la méthode du système d'enregistrement thinkLoader::autoload

2.2.1.3.2.2 Enregistrer la définition de l'espace de noms du système

2.2.1.3.2.3 Charger le fichier de mappage de la bibliothèque de classes (s'il existe)

2.2.1.3 .2.4 Si Composer est installé, enregistrez Composer pour qu'il se charge automatiquement

2.2.1.3.2.5 Enregistrez le répertoire d'extension d'extension


2.2.1.3.3 Chargement automatique de la bibliothèque de classes

2.2.1.3.3.1 S'il faut définir le mappage de la bibliothèque de classes

2.2.1.3.3.2 PSR-4 Chargement automatique détection

2.2.1.3.3.3 PSR- 0 Détection de chargement automatique

2.2.1.4 Erreur d'enregistrement et mécanisme de gestion des exceptions

2.2.1.4.1 Exécuter Error::register( ), qui se compose de trois parties

2.2 .1.4.1.1 Méthode d'arrêt de l'application : thinkError::appShutdown

2.2.1.4.1.2 Méthode de gestion des erreurs : thinkError::appError

2.2.1.4.1.3 Méthode de gestion des exceptions : thinkError::appException

2.2.1.5 Charger le fichier de configuration de la convention

2.2.1.5.1 thinkConfig::set(include THINK_PATH . 'convention ' . EXT);

2.2.2 Exécuter l'application :App::run()->send();

2.2.2.1 App::run() saisit l'objet Request et renvoie l'objet 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框架思维导图下载地址:

Framework ThinkPHP5 illustré (2) : processus d'exécution et cycle de vie de l'application2框架架构.xmind.zip

【相关推荐】

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

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

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

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn