Laravel框架关键技术解析

一、组件化开发与composer使用

A.组件化开发

B.composer使用

C.手动构建Laravel框架

1.index.php:自动加载函数的添加、服务容器实例化与服务注册、路由加载、请求实例化与路由分发、响应生成与发送

2.composer dump-autoload:更新自动加载文件

二、Laravel框架安装与调试环境建立

1.composer安装

命令1:composer global require “laravel/installer=~1.1”

命令2:composer create-project laravel/laravel —prefer-dist

三、Laravel框架中常用的PHP语法

A.组件化开发语法条件

1.命名空间

  • PHP命名空间只支持导入类,而不支持导入函数或常量
  • 对命名空间中的名称来说,最前面是不允许有反斜杠的
  • 对完全限定名称的函数、类和常量可以直接解析
  • 对所有非限定名称和非完全限定名称的函数、类和常量,根据当前导入的命名空间进行转换
  • 在命名空间内部,所有的没有根据导入规则转换的非限定名称和非完全限定名称均会在其前面加上当前命名空间名称
  • 在命名空间内部,对非限定名称和非限定 名称的函数进行调用时,先在当前命名空间下解析,如果查找不到再在全局空间下查找
  • 在命名空间内部对非限定名称和非完全限定名称的类进行调用时,只会在当前命名空间下解析

2.文件包含

  • require产生错误,include出警告
  • 通过__autoload或spl_autoload_register()方法进行自动加载
  • 在Laravel架构中,通过函数spl_autoload_register实现类自动加载函数的注册,其中类的自动加载函数队列中包含了两个类的自动加载函数,一个是composer生成的基于PSR规范的自动加载函数,另一个是Laravel框架核心别名的自动加载函数

B.匿名函数

1.匿名函数(Anonymous functions)也叫闭包函数(Closure)即一个没有指定名称的函数,经常用做回调函数(callback)参数的值

2.匿名函数既可以作为参数传递给函数,也可以做为变量赋值,进而控制函数的执行过程;可以从父作用域中继承变量,使用use关键字来继承;默认PHP是通过复制的方式传入上层变量进入匿名函数,如果需要改变上层变量的值,需要通过引用的方式传递。

3.Laravel框架中的应用:大量使用,如在服务提供者注册过程中,通过将服务名称与提供服务的匿名函数进行绑定,在使用时可以实现动态服务解析。可以通俗的理解为对一种资源的提供,这个资源可以是一个类的实例、一个路径或是一个文件等,提供服务就是提供一种资源(Illuminate\Routing\ControllerServiceProvider.php)

C.PHP中的特殊语法

1.魔术方法:通常用户不会主动调用,而是在特定的时机被PHP系统自动调用,可以理解为系统事件监听方法,在事件发生时才触发执行。Laravel示例(Illuminate\Database\Eloquent\Model.php)

2.魔术常量:__LINE__、__FILE__、__DIR__、__FUNCTION__、__CLASS__、__TRAIT__、__METHOD__、__NAMESPACE__

D.反射

1.主要用来动态地获取系统中类、实例对象、方法等语言构件的信息,通过反射API函数可以实现对这些语言构件信息的动态获取和动态操作

2.Laravel服务容器解析服务的过程:Illuminate\Container\Container.php

E.后期静态绑定

1.后期静态绑定(PHP5.3.0),即在类的继承过程中,使用的类不再是当前类,而是调用的类。

2.使用static来实现,通过这种机制,“static::”不再被解析为定义当前方法所在的类,而是在实际运行时计算得到的,即为运行时最初调用的类,不仅限制于静态方法的调用

3.后期静态绑定还可以用于对象实例化中,在实例化对象时,static会根据运行时调用的类来决定实例化对象,而self是根据所在位置的类来决定实例化对象

4.Laravel示例:Illuminate\Database\Eloquent\Model.php,如query()方法中(new static)->newQuery();

F.Laravel中使用的其他新特性

1.trait

  • 优先级:当前类的方法会覆盖trait中的方法,trait中的方法会覆盖基类的方法
  • 多个trait通过逗号分隔,通过use关键字列出多个trait
  • 冲突的解决:如果两个trait都插入了一个同名的方法,若没有明确解决冲突将会产生一个致命错误,使用insteadof操作符来明确指定使用哪一个,同时,可以通过as操作符改变名称来引入
  • 使用as语法可以用来调整方法的访问控制
  • trait抽象方法使类中必须实现这个方法
  • trait中可以用静态方法和静态变量
  • trait也可以定义属性

2.简化的三元运算符:

  • PHP5.3起,三元运算符可以省略中间,如$value=exp1?:exp2,当exp1==true时,返回exp1,否则返回exp2

https://github.com/zhangyue0503/php/tree/master/laravelkuangjiaguanjianjishujiexi/3

四、Laravel框架中使用的HTTP协议基础

A.HTTP发展与相关网络技术

1.wireshark

B.HTTP协议简介

五、Laravel框架初识

A.Laravel框架应用程序目录结构

1.Laravel框架应用程序是符合PSR规范的,如果添加了新的目录,需要在composer.json文件中添加PSR规范的自动加载部分并执行update命令

2.根目录

  • app:主要包含应用程序的核心代码,用户构建应用的大部分工作都在这个目录下进行,包括路由文件、控制器文件、模型文件等
  • bootstrap:主要包含几个框架启动和自动加载配置的文件
  • config:主要包含应用程序常用的配置文件信息
  • database:主要包含数据库迁移和数据库填充文件
  • public:为应用程序的入口目录,包含index.php,同时包含静态资源文件如CSS、JS、images等
  • resources:主要包含视图文件
  • storage:包含编译后的Blade模板、基于文件的session、文件缓存和日志等文件
  • tests:主要包含自动化测试文件
  • vendor:主要包含依赖库文件,其中包含Laravel框架的源码
  • .env文件:一个重要的文件,为Laravel框架主配置文件
  • conposer.json文件:composer项目依赖管理文件

3.app目录

  • Console:主要包含所有的artisan命令
  • Events:用来放置与事件相关的类
  • Http:主要包含路由文件、控制器文件、请求文件、中间文件等,是应用程序与Laravel框架源代码等外部库交互的主要地方
  • Jobs:主要包含消息队列的各种消息类文件
  • Listeners:主要包含监听事件类文件
  • Providers:主要包含服务提供者的相关文件
  • app目录下可以放置模型类文件
  • app目录已经通过composer包含到自动加载目录中,所以新建目录不需要更新自动加载类,但是类的命名空间需要与文件目录相符

4.vendor目录

  • composer:主要包含composer按照PSR规范生成的自动加载类
  • laravel:包含Laravel框架的源代码
  • symfony:Laravel框架的底层使用了symfony框架的部分
  • monolog:包括日志记录模块文件
  • phpunit:包含程序单元测试模块文件

B.Laravel框架应用程序的三个重要环节

1.路由

  • 作用:根据请求资源定位符的不同,将用户的请求按照事先规划的方案提交给指定的控制器或者功能函数来处理
  • 基础路由设置:Route::方法名('资源标识’,闭包函数或控制器响应函数标识);
  • 路由参数:Route::get(‘资源标识/{参数名[?][/{参数名}……]} ‘,闭包函数或控制器响应函数标识)[->where(‘参数名’,'正则’)];
  • 路由命名:Route::get('资源标识’,[‘as’=>’命名’,uses=>闭包函数或控制器响应函数标识]),使用这个路由重定向时$url=route('命名’)
  • 路由群组:Route::group([‘prefix’=>’组资源名’,’middleware’=>’中间件'],function(){子路由……});

2.控制器

  • 通常放在laravel/app/Http/Controllers目录下,继承自Illuminate\Routing\Controller类,作为HTTP请求的二次分发控制部分,通过依赖注入解决了与路由的紧耦合关系
  • 基础控制器路由:Route::请求方法(‘资源标识/{参数名[?][/{参数名}……]’,’控制器类名@函数名称’);参数与顺序有关,与命名无关
  • 隐式控制器路由:Route::controller(‘路由前缀’,’控制器类名’[,命名路由]);请求结构为”主机地址/路由前缀/控制器方法名/路由参数”,如/home/index/xiaoming,会找到HomeController的getIndex($name)方法,anyIndex可以不限制请求方式,驼峰名方法如getHomeIndex,请求时为home-index
  • RESTFul资源控制器路由:Route::resource('资源标识’,’控制器类名’);

3.视图

  • 两种方式生成视图:直接返回字符串,使用view()方法返回视图响应
  • 数据传递三种方式:数组方式,with方式(return view('')->with(‘key’,’value')),with加变量名方式(return view(‘’)->withUsername(‘value’))
  • blade布局语法标签
    • @extend(‘布局文件名’):用于继承一个布局文件
    • @section(‘区块名’):用于定义一个区块,它可以有不同的结尾标识,@show用于显示,@stop和@endsection用于结束一个区块,@overwrite用于重写前面的区块。如果在布局模板文件中用@stop或@endsection结束这个区块,则视图文件将无法覆盖这个区块
    • @parent:用于显示继承的布局模板中的内容
    • @yield(‘区块文件’,'默认内容’):用于在布局文件中定义一个区块,默认内容不是必须的
    • @include(‘子视图名称’):用于在视图文件中加载子视图文件,使得视图文件结构清晰

六、Laravel框架中的设计模式

A.服务容器

1.将服务理解为系统运行中需要的东西,如对象、文件路径、系统配置等,服务容器就是这些东西的载体,在程序运行过程中动态地为系统提供这些服务,也可以看做是提供这些资源

2.依赖:一个对象实现某个功能需要其他对象相关功能的支持,当用new关键字在一个组件内部实例化一个对象时就解决了一个依赖,但同时也引入 了另一个严重的问题——耦合

3.不应该在类的内部固化实例的初始化行为,而是转由外部负责,在系统运行期间,将这种依赖关系通过动态注入的方式实现,这就是IOC模式的设计思想

4.IOC(Inversion of Control)模式又称依赖注入(Dependency Injection)模式。控制反转是将组件间的依赖关系从程序内部提到外部容器来管理,而依赖注入是指组件依赖通过外部以参数或其他形式注入,两种说法本质上是一个意思

5.Laravel中:Illuminate\Container\Container

B.请求处理管道简介

1.装饰者模式:是在开放—关闭原则下实现动态添加或减少功能的一种方式。Laravel框架中,在解析请求生成响应之前或之后需要经过中间件的处理,主要包括验证维护模式、Cookie加密、开启会话、CSRF保护等,而这些处理有些是在生成响应之前,有些是在生成响应之后

2.请求处理管道:Laravel中通过Illuminate\Pipeline\Pipeline类实现

https://github.com/zhangyue0503/php/tree/master/laravelkuangjiaguanjianjishujiexi/6

七、请求到响应的生命周期

A.程序启动准备

1.入口文件public/index.php

2.启动准备阶段是require_once __DIR__.’/../bootstrap/app.php’部分,主要实现了服务容器的实例化和基本注册,包括服务容器本身注册、基础服务提供者注册、核心类另名注册和基本路径注册等

3. Kernel类$middleware(中间件)和$routeMiddleware(路由中间件),中间件是请求进入路由前的处理类,路由中间件是请求进入路由处理后的处理类

B.请求实例化

C.处理请求

1.应用程序的引导包括环境检测、配置加载、日记配置、异常处理、外观注册、服务提供者注册和启动服务七个步骤

2.在配置加载的过程中设置的参数都可以在.env文件中进行设置,而.env中对环境的配置将会覆盖配置加载项,当然,也可以修改不覆盖

3.外观注册分为两个步骤:一是完成外观自动加载类的实例化并将外观别名数组添加到该实例中,这里需要与composer的自动加载类进行区别;二是完成外观自动加载类中的自动加载函数的添加。

4.两个别名:一是容器核心别名,存在Application中的$aliases,另一个是外观别名,定义在app.php配置文件中,程序运行后存储在AliasLoader类实例的$aliases属性中

5.在服务提供者的注册过程中将服务提供者分为三类

  • when类是注册事件,只有当事件发生时才会自动注册这个服务提供者,通过registerLoadEvents()监听,当事件发生时调用register()函数进行服务注册
  • eager类会直接加载,加载方式和注册基础服务提供者的过程相同,直接通过createProvider()函数实例他并注册
  • deferred类的服务提供者存储在列表中,需要加载时才会加载,记录在服务容器的$deferredServices数组属性中,在使用服务容器进行解析时,如果发现这个服务在延时服务数组中,则会注册

D.响应的发送与程序终止

八、服务容器与服务提供者

A.服务容器

1.Laravel中服务容器相当于大脑,服务提供者相当于神经系统

2.服务提供者首先需要将各个功能模块具备的功能注册到服务容器中,当需要完成某些功能时,服务容器会通过服务提供者注册的服务完成相应的准备,然后会调用准备好的功能模块实现相应的功能

3.服务容器只有一个,而服务提供者遍布整个框架的各个功能模块内

4.对于Laravel框架,当接收到一个请求时,就会为了处理这个请求首先生成一个服务容器,用于容纳处理请求需要的服务

5.回调函数绑定的就是一个回调函数,实例对象服务绑定的是一个实例对象

6.回调函数的绑定还分为两种:

  • 普通绑定每次生成该服务的实例对象时都会生成一个新的实例对象,也就是说在程序的生命周期中,可以同时生成很多个这种实例对象
  • 单例绑定在生成一个实例对象后,如果再次生成就会返回第一次生成的实例对象

7.还有一种形式,即绑定具体类名称,本质上也是绑定回调函数的方式,只是回调函数是服务容器根据提供的参数自动生成的,如:$app-bind(XXX::class, XXX::class)

8.四种解析方式:

  • 直接通过$app->make()方法
  • 通过类似数组访问的方式,因为服务容器实现了ArrayAccess接口,$app[]
  • 通过全局函数app()解析,如果参数为NULL,则返回服务容器的实例
  • 通过Facades中的App外观解析

9.Laravel框架还实现了一种依赖注入的方式进行服务解析,服务名称必须为服务生成的实例对象的类名称或接口名称,通过服务容器创建的类的构造函数可以通过依赖注入的方式解决依赖问题,对于方法也是一样

B.服务提供者

1.服务提供者中两个方法

  • register()用于服务绑定
  • boot()会在所有服务提供者注册完成后才被调用,这时可以在其中使用所有已经注册过的服务

2.注册服务提供者:config\app.php中,providers项

  • Web请求-->>服务容器解析Web处理核心类(全局的$kernel变量,包含一个$bootstrappers数组,记录程序处理请求的准备工作需要的类)-->>$kernel类的handle()调用bootstrap()函数-->>bootstrapWith()函数-->>实例化处理$bootstrappers中的RegisterProviders实例-->>调用实例中的bootstrap()-->>调用服务容器中的registerConfiguredProviders(),从配置文件中提取所有的服务提供者

3.缓载服务提供者:对于不是每个请求都需要使用的服务只有在需要时才临时进行服务绑定,然后再进行服务解析。需要将$defer属性设置为true,同时定义一个provides方法,用于返回服务提供者绑定服务的名称

https://github.com/zhangyue0503/laravel5.4cn

九、请求与响应的操作

A.HTTP请求实例的操作

1.三种获取Request的方法

  • Request::all(); //Facade方式
  • app(‘request’); //直接服务容器获取
  • public function xxx(Request $request) //依赖注入方式

2.请求参数:all()、method()、query()、input()、only()、except()、url()、fullUrl()、path()等等

3.一次性存储

  • flash()、flashOnly()、flashExcept()
  • redirece()->withInput()
  • $request->old() 或者old() //获取

B.HTTP响应

1.Laravel中对于响应生成的三种形式

  • 只生成响应主体内容部分
  • 生成响应的首部和主体部分
  • 生成重定向的响应,即只包含响应的重定向首部

2.生成响应的主体内容:return “字符串”或return view(‘xxx’)

3.生成自定义响应的实例:new Response()、response()

4.生成重定向的响应:重定向响应是一个特殊的响应,只是在响应报文首部中包含了Location重定向字段,Laravel中的RedirectResponse类是在Symfony框架的RedirectResponse类的基础上加入了session一次性数据、自定义首部信息等功能

https://github.com/zhangyue0503/laravel5.4cn

十、数据库及操作

A.数据库迁移与填充

1.Laravel的数据库迁移其实是定义了一个统一的接口来实现数据库架构的创建和维护,而这种统一的接口与底层的数据库及其操作语言都是无关的

2.迁移文件及命令:

  • Laravel/database/migrations下
  • php artisan make:migration 文件名 —create=表名
  • php artisan migrate
  • php artisan migrate:rollback

3.数据库填充文件及命令:

  • Laravel/database/seeds下
  • php artisan make:seeder XXXXSeeder //创建,第一次要composer down-autoload一下
  • php artisan db:seed [—class=类名]

B.查询构造器

1.Laravel框架的查询构造器是在PDO扩展基础上设计的一个“重量级”的数据库扩展

2.查询构造器建立过程:

  • 一个是数据库连接封装阶段
  • 一个是查询构造器生成阶段

3.数据库封装阶段:

  • 一是数据库管理器阶段,\Illuminate\Database\DatabaseManager
  • 二是数据库连接工厂阶段,\Illuminate\Database\Connectors\ConnectionFactory
  • 三是数据库连接器阶段,\Illuminate\Database\Connectors\MySqlConnector
  • 四是数据库连接创建阶段,\Illuminate\Database\Connectors\ConnectionFactory

4.查询构造器类(\Illuminate\Database\Query\Builder)实例封装了数据库连接实例、请求语法实例和结果处理实例,这里类的实例提供了统一的接口方法供查询构造器实例使用

5.查询构造器使用阶段:

  • SQL语句准备阶段,Illuminate\Database\Query\Grammars
  • SQL语句执行阶段,Illuminate\Database\Connection

C.Eloquent ORM

1.两个阶段

  • Eloquent ORM查询构造器的生成,Illuminate\Database\Eloquent\Model::newQuery()
  • 操作命令的执行,Illuminate\Database\Eloquent\Builder

2.ORM映射最大的好处是将数据表的结构映射成一个类对象,可以将数据以对象的形式封装使用,程序的编写将变得高效而且结构清晰

3.对于多个表而且表间存在不同的关系时,如果使用不好会严重影响程序的性能

4.创建命令:php artisan make:model 名称

https://github.com/zhangyue0503/laravel5.4cn

十一、Redis数据库

A.redis数据库的应用

1.Laravel框架整合了predis资源包后将这些操作的过程划分三个阶段:

  • 以外观方式通过服务容器获取redis数据库客户端服务,Illuminate\Support\Facades\Redis
  • redis数据库客户端实例化过程,Illuminate\Redis\RedisManager
  • 操作指令的生成和发出

https://github.com/zhangyue0503/laravel5.4cn

十二、会话

A.Laravel框架中的session机制

1.当客户端访问服务器时,服务器将开启session,检测请求的Cookie中是否携带sessionID,如果携带则使用该sessionID,如果没有则新产生一个sessionID。这个过程可以称为session的启动阶段。通过中间件StartSession开启会话

2.根据sessionID来恢复之前 存储的数据,在请求处理期间可以使用恢复的数据,同时也可以向session中继续添加或删除数据。这个过程可以称为session的操作阶段。

3.当返回响应时,将session中的数据存储到相应的位置,以备下一次请求到来时使用并发送sessionID的Cookie。这个过程可以先称为session的关闭阶段。

https://github.com/zhangyue0503/laravel5.4cn

十三、消息队列

1.消息队列可以解决大并发和多种语言通信接口等问题

2.实时socket连接和推送问题node.js更为擅长,实现效率也更高

3.分布式任务处理Java更为擅长,特别是与银行等金融行业的接口

4.Laravel框架中包括数据库、Beanstalkd、IronMQ、Amazon SQS、redis、同步和NULL,这些类型的驱动

A.同步类型消息队列:消息

1.消息发送

  • 生成消息类:php artisan make:job QueuedTest —queued
  • Laravel中通过不同的Job类实现消息的封装,通过序列化封装成json格式然后将其发送

2.消息处理

  • 消息队列的执行流程,七个步骤:消息实例生成(工作生成)、消息队列实例生成(队列连接生成)、消息序列化封装、消息存储(消息推送)、消息获取(消息抛出)、消息处理类封装和消息处理

B.数据库类型消息队列

1.数据表:php artisan queue:table

2.Iiiuminate\Queue\DatabaseQueue

https://github.com/zhangyue0503/laravel5.4cn

十四、认证与数据验证

A.认证

1.通过路由中间件进行用户权限认证:Illuminate\Auth\Middleware\Authenticate

2.权限认证的一些方法:中间件auth、Auth::user()、Request::user()、依赖注入Authenticatable $user、Auth::check()等等

B.数据验证

1.控制器验证:Controller基类使用了一个ValidatesRequests的trait,其中的validate()函数用于完成数据验证结果的判断、错误令牌存储以及重定向

2.表单请求验证:php artisan make:request RegisterRequest,通过依赖注入public function postRegister(RegisterRequest $request){}进入方法即通过验证,还包含authorize()方法可以实现用户权限的精确控制

https://github.com/zhangyue0503/laravel5.4cn

十五、思维笔记实例

https://github.com/zhangyue0503/php/tree/master/laravelkuangjiaguanjianjishujiexi/laravel

(运行不了)

原文发布于微信公众号 - 硬核项目经理(fullstackpm)

原文发表时间:2017-07-16

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券