tp5.1源码分析

下载tp5.1.35

composer create-projecttopthink/think=5.1.35 imooc_tp5 --prefer-dist

执行php think run

php think optimize:autoload 生成classmap.php

自动加载Loader 深度分析

    类的自动加载

注册系统自动加载spl_autoload_register

loader::register

// Composer自动加载支持

autoload_static.php的属性都映射到本类

self::${$attr} = $composerClass::${$attr}

 

// 注册命名空间

addNamespace

会给composer下的autoload_static.php

填充新的内容

$prefixLengthsPsr4

$prefixDirsPsr4

// 注册类库别名Loader::addClassAlias

 

新增自定义类

2、放在thinkphp/library/ali/Send.php


composer下的自动加载

找到composer下的autoload_static.php



解读配置文件

配置文件的种类

1、惯例配置thinkphp/convention.php

2、应用配置config/app.php..

3、模块配置config/index

4、动态配置


php 底层ArrayAccess

提供像访问数组一样访问对象的能力的接口

实现它的四个方法


yaconf扩展

https://github.com/laruence/yaconf下载源码

phpize

./configure --with-php-config=/usr/local/php/bin/php-config

make &&make install

vim php.ini

extension=yaconf.so

yaconf.directory=/usr/local/nginx/html/imooc_tp5/ini


Config底层类分析


Load深度加载

Public/index.php 调用容器的app类,会调用initialize方法,它会调用init方法

其中有一段是调用load方法的


本身$this没有config这个属性,会调用容器种的__get()方法,最后实例化config类,调用load()方法,加载配置文件(多种格式)



Yaml初体验


1、安装pecl install yaml

https://blog.csdn.net/nianyixiaotian/article/details/97017381

2、php -i|grep php.ini


使用方法:

$abc=yaml_parse_file("../config/singwa.yaml");

优化1

框架的bug 需要把环境变量配置的代码提前到$this->configExt



项目中使用

在根目录创建.env   写入CONFIG_EXT=”.yaml”

在控制器层调用



优化2



设计模式

单例模式

注册树模式

依赖注入

1、依赖注入主要用来减少代码间的耦合

2、有效分离对象和它所需的外部资源



PHP的反射机制

Container容器类

编写自己的容器类

包括单例模式、注册树模式、反射机制


实例化



Countable类的使用


Container容器类刨析


获取容器中的对象实例

[if !vml]

[endif]

Make()方法  创建类的实例

[if !vml]

[endif]

[if !vml]

[endif]

[if !vml]

[endif]

在控制器中具体使用容器

[if !vml]

[endif]


门面模式facade

[if !supportLists]1、[endif]门面为容器中的类提供了一个静态调用接口

[if !supportLists]2、[endif]相比于传统的静态方法调用,带来了更好的可测试性和扩展性。


thinkphp\library\think\Facade.php此类是父类

thinkphp\library\think\facade\有很多文件,每个文件只做一件事

继承并返回类的标识。

[if !vml]

[endif]

底层的类不是静态的方法

如thinkphp\library\think\config.php类里不是静态的方法。

上层可以通过静态的方式去用think\xxx.php的方法。


1、dump(\think\facade\Config::get("app."));

2、\think\facade\Config类没有get方法,会调用父类facade类的__callStatic

[if !vml]

[endif]

3、__callStatic的createFacade,创建实例

[if !vml]

[endif]

好处:通过静态的方法调用类的方法。

图示

[if !vml]

[endif]

在控制器中的具体使用

        dump(\Config::get("app."));

       dump(\think\facade\Config::get("app."));

门面模式facade实战

普通的写法

在application\common\Singwa.php

[if !vml]

[endif]

控制器层实例化调用

[if !vml]

[endif]


使用门面模式进行

[if !vml]

[endif]

[if !vml]

[endif]

[if !vml]

[endif]                           

最后在控制器用静态的方式调用

[if !vml]

[endif]

框架执行流程以及路由解读

Container::get('app')找到think\App.php

初始化应用init分析

1、多次初始化

2、检测被多次初始化

$array=debug_backtrace();var_dump($array);

想要知道某方法被在哪调用可以使用它,主要是回溯跟踪。


App.php下的init做的功能

1、加载初始化文件 $path.init.php(本身是没有的,$path是application或具体模块目录)

2、加载行为扩展文件$path.tags.php (application下有此文件)

3、加载公共文件$path.common.php (application下有此文件)

4、加载助手函数helper.php

5、加载中间件 $path.middleware.php(本身是没有的,$path是application或具体模块目录)

6、注册服务的容器对象实例$path.provider.php  然后bindTo($provider)

7、自动读取配置目录文件,并load

8、如果有具体的模块,则对容器中的对象实例进行配置更新


注册服务的容器对象实例

[if !vml]

[endif]

[if !vml]

[endif]

application\common\Sa.php

[if !vml]

[endif]

控制器层

dump(Container::get('sa')->abcd());

路由初始化

initialize方法最后调用

$this->routeInit();

主要工作是扫描根目录的route,引入所有文件。

并导入

[if !vml]

[endif]

Route::get指向的是think\Route.php下的rule方法

[if !vml]

[endif]

http://127.0.0.1:8000/hello/111

Route类种rule方法执行方式脑图

https://naotu.baidu.com/file/bacd378635905a00c7a20bd9ca9d59bf

route.php--->Domain.php--继承-->RuleGroup.php—调用—>addRule方法

路由规则预处理setRule方法

如果是$   则处理成        $this->option['complete_match']= true;

[if !vml]

[endif]

[if !vml]

[endif]

可选的是[:name]=>                                    


[if !vml]

[endif]

$value的结果是

[if !vml]

[endif]

[if !vml]

[endif]

Set的结果是

$this->item[name][]=$value

[if !vml]

[endif]

[if !vml]

[endif]

setRule注册路由规则

$this->rule[$route->getDomain()][$rule][$route->getMethod()]= $route;


$rule路由规则

[if !vml]

[endif]

路由参数

Rule.php 的rule()方法的第四个参数option=[]来表示

Route::get()  //返回的是RuleItem对象

两种方式设置参数

[if !vml]

[endif]

变量规则

Rule.php的rule()方法的第五个参数$pattern

写法

[if !vml]

[endif]

另外一种写法

[if !vml]

[endif]

注册变量规则

[if !vml]

[endif]

资源路由

支持设置restful请求的资源路由,


[if !vml]

[endif]

[if !vml]

[endif]

Route.php定义了rest的几种规则

[if !vml]

[endif]

Resource这个类在library\think\route\Resoure.php

通过资源路由的实例

[if !vml]

[endif]

[if !vml]

[endif]

[if !vml]

[endif]

路由配置--数组方式配置

之前都是调用route类的方法,现在使用返回数组的方式

[if !vml]

[endif]

APP.php的initialize方法,调用了routeInit路由初始化方法

它调用了import方法

import方法做路由规则的导入

[if !vml]

[endif]

Dispatch初始

APP.php的run()方法

[if !vml]

[endif]

打印两个场景

[if !supportLists]1、[endif]通过路由配置

[if !supportLists]2、[endif]普通的,没有经过配置的

无论是什么模式,最后$dispatch的结果都是

[if !vml]

[endif]

上上图中的routeCheck()方法种有url路由检测

[if !vml]

[endif]

最后return $dispatch

而check()方法

[if !vml]

[endif]

[if !vml]

[endif]

request类如何找到

上上图中的$this->request,是Route.php的属性,

[if !vml]

[endif]

[if !vml]

[endif]

没有容器则创建容器

[if !vml]

[endif]

调用container.php的make方法,会找到Request.php



DOmain.php->check()------RuleGroup.php->check()

检测url变量和规则路由是否匹配

Route.php -->check()检测url路由

Domain.php->check()检测域名路由parent::check($request, $url, $completeMatch)

RuleGroup.php->check()检测分组路由

RuleGroup.php->checkMergeRuleRegex()检测分组路由

[if !vml]

[endif]

RuleItem.php-> checkRule()检测路由


其中会调用match()方法主要是检测url变量和规则路由是否匹配

dump($match)时变量数组

控制器解读

课前复习

匿名函数

在php5.3及以上版本

匿名函数,也叫闭包函数,允许临时创建一个没有指定名称的函数。

[if !vml]

[endif]

Eg2:匿名函数作为函数的参数访问

Demo(function(){return“####”})

闭包

连接闭包和外界变量的关键字:USE

闭包可以保存所在代码块上下文的一些变量和值。

PHP在默认情况下,匿名函数不能调用所在代码块的上下文变量,而需要通过使用use关键字

[if !vml]

[endif]

匿名函数作为返回值返回

[if !vml]

[endif]

通俗的说:子函数可以使用父函数中的局部变量,这种行为就叫做闭包!

闭包函数返回时,该函数内部变量处于激活状态,函数所在栈区依然保留


实例化控制器

App.php run()方法

[if !vml]

[endif]

[if !vml]

[endif]

调用该类的run()

[if !vml]

[endif]

在本类是抽象方法,在Module.php中实现

[if !vml]

[endif]

[if !vml]

[endif]

实例化控制器

[if !vml]

[endif]

执行控制器中的方法

Module.php 中的exec()方法

[if !vml]

[endif]

[if !vml]

[endif]

[if !vml]

[endif]

[if !vml]

[endif]

$data时方法最后的return “hello world”

闭包返回的数据,最后注册到中间件中

执行autoResponse调度

[if !vml]

[endif]

[if !vml]

[endif]

第一次走的是elseif  执行Response::create()方法

[if !vml]

[endif]

实例化的时候会调用构造方法,

[if !vml]

[endif]


最后autoResponse返回的的结果是

以及

[if !vml]

[endif]

返回的结果是一样的

[if !vml]

[endif]

[if !vml]

[endif]

[if !vml]

[endif]

执行中间件的调度


输出数据到终端

[if !vml]

[endif]

fastcgi_finish_request()

客户端响应到此结束,服务端代码还是会去执行

控制器的初始化

[if !vml]

[endif]



trait特性讲解

php以前是单继承的,无法同时继承多个类

trait jump类

[if !vml]

[endif]

[if !vml]

[endif]

DB和模型

DB操作

Db::query($sql)

Db需要use \think\Db

query这个静态方法是没有的

 \think\Db.php类文件没有query方法,会调用__callStatic()方法

会调用本类的static::connect()方法,主要是用来切换数据库连接

[if !vml]

[endif]

[if !vml]

[endif]

[if !vml]

[endif]

$this->connection 是Connection.php 下的Mysql的实例,它在connector下,Mysql.php没有query方法,去父类找query()


Db类库结合连接器、查询器、生成器

$res=DB::table('imooc_user')->where(['id'=>1])->find();

没有tabe方法,会调用__callStatic()方法

call_user_func_array([static::connect(),$method], $args);

这里是 static::connect是结果new Query

table 在此类中,where也一样,find 方法会

$result = $this->connection->find($this);

而connection是依赖注入的方式find(Query $query)

此方法中有生成器

// 生成查询SQL

$sql = $this->builder->select($query);

builder中的select方法主要是使用str_replace替换下列字符串中的字符


SELECT%DISTINCT% %FIELD% FROM %TABLE%%FORCE%%JOIN%%WHERE%%GROUP%%HAVING%%UNION%%ORDER%%LIMIT%

%LOCK%%COMMENT%

model场景

[if !vml]

[endif]


model场景分析--新增逻辑

print_r(model('user'));


app\index\model\User Object ( [data] => Array ( ) [relation]

=> Array ( ) )


save()方法在model.php

在此方法中调用本类的checkBeforeSave()方法,主要功能是写入之前检查数据

checkBeforeSave调用setAttr

[if !vml]

[endif]

setAttr方法


// 检测修改器$method = 'set' . Loader::parseName($name, 1) . 'Attr';

最后形成

// 设置数据对象属性

return$this->data[$name] = $value;

深度分析

设置完属性对象,逻辑还是回到save()方法中,接着进行insertData方法

[if !vml]

[endif]

[if !vml]

[endif]

其中上上图的insert方法

[if !vml]

[endif]

[if !vml]

[endif]

最后在此方法中执行execute()




异常处理、缓存

Base.php有类的关系映射,通过\Cache找到对应的门面模式

通过配置文件设置需要type是文件,redis,memcache,

通过工厂模式进行调用

面试技巧

MySQL基本使用、优化(加索引、主从分离,读写分离),查询elecsearch

redis场景投票、抢票、排序

Nginx 基本配置限流,负载均衡

框架:深入理解框架就够了

简历体现技术难点

内推:算法,数据结构


框架层:设计模式、门脸模式、迭代器、反射、类自动加载、路由


对框架的理解

[if !supportLists]1、[endif]组织好目录结构,如应用目录,配置目录,

[if !supportLists]2、[endif]入口文件处理自动加载(框架层的自动加载,composer的自动加载)

[if !supportLists]3、[endif]容器(单例模式)

[if !supportLists]4、[endif]配置文件的加载(tp配置文件写在文件里,对性能有损耗,yaconf)

[if !supportLists]5、[endif]路由(中大型公司用不到,在nginx做配置就可以)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,657评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,889评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,057评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,509评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,562评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,443评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,251评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,129评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,561评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,779评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,902评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,621评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,220评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,838评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,971评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,025评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,843评论 2 354

推荐阅读更多精彩内容

  • 对于java中的思考的方向,1必须要看前端的页面,对于前端的页面基本的逻辑,如果能理解最好,不理解也要知道几点。 ...
    神尤鲁道夫阅读 814评论 0 0
  • tp5.1运行环境要求PHP5.6+ 对比5.0 1、采用容器统一管理对象2、facade支持3、对象化路由4、取...
    余头阅读 1,060评论 0 0
  • Sonar翻译 Sonar翻译... 1 User Guide(用户指南)... 2 第一章Fixing the ...
    pig_zzZ阅读 2,780评论 0 1
  • CHAPTER 1: INTRODUCTION 第一章:简介 In this chapter, we discus...
    哈小奇阅读 1,030评论 2 1
  • 当天我就把想法落实到行动上,我名下唯一的财产就是这辆车,我把车过户到朋友的名下,对方要是问起就说是买的,另...
    汇誉通阅读 252评论 0 0