<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Laravel Archives - 成長駭客交流第一站 - HyperGrowths™</title>
	<atom:link href="https://hypergrowths.com/category/software-engineering/laravel/feed/" rel="self" type="application/rss+xml" />
	<link>https://hypergrowths.com/category/software-engineering/laravel/</link>
	<description>用SEO內容行銷加速增長? 企業發展遇到增長瓶頸？加入 HyperGrowths，學習突破性增長策略，優化行銷方案，助力企業飛躍式發展</description>
	<lastBuildDate>Fri, 30 Apr 2021 09:31:16 +0000</lastBuildDate>
	<language>zh-TW</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.3.5</generator>

<image>
	<url>https://hypergrowths.com/wp-content/uploads/2020/11/cropped-?.png</url>
	<title>Laravel Archives - 成長駭客交流第一站 - HyperGrowths™</title>
	<link>https://hypergrowths.com/category/software-engineering/laravel/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>【PHP】用了这么久的Laravel框架，你分析过核心架构了没</title>
		<link>https://hypergrowths.com/software-engineering/laravel/21810/topic-364906604/</link>
		
		<dc:creator><![CDATA[marketer]]></dc:creator>
		<pubDate>Fri, 30 Apr 2021 09:31:16 +0000</pubDate>
				<category><![CDATA[Laravel]]></category>
		<category><![CDATA[进阶PHP月薪30k]]></category>
		<guid isPermaLink="false">https://hypergrowths.com/software-engineering/laravel/21810/topic-364906604/</guid>

					<description><![CDATA[<p>Laravel最初的设计是为了面向MVC架构的，它可以满足如事件处理、用户身份验证等各种需求。另外它还有一个由管理数据库强力支持，用于管理模块化和可扩展性代码的软件包管理器。 Laravel以其简洁、优雅的特性赢得了…</p>
<p>The post <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com/software-engineering/laravel/21810/topic-364906604/" data-wpel-link="internal">【PHP】用了这么久的Laravel框架，你分析过核心架构了没</a> appeared first on <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com" data-wpel-link="internal">成長駭客交流第一站 - HyperGrowths™</a>.</p>
]]></description>
										<content:encoded><![CDATA[<article class="Post-Main Post-NormalMain">
<header class="Post-Header">
<h1 class="Post-Title">【PHP】用了这么久的Laravel框架，你分析过核心架构了没</h1>
<div class="Post-Author">
<div class="AuthorInfo"></div>
</div>
</header>
<div class="Post-RichTextContainer">
<div class="RichText ztext Post-RichText">
<p>Laravel最初的设计是为了面向MVC架构的，它可以满足如事件处理、用户身份验证等各种需求。另外它还有一个由管理数据库强力支持，用于管理模块化和可扩展性代码的软件包管理器。</p>
<p>Laravel以其简洁、优雅的特性赢得了大家的广泛关注，无论是专家还是新手，在开发PHP项目的时候，都会第一时间的想到Laravel本文我们将分析一下laravel框架的核心架构。</p>
<p><b>主要包含的内容有：容器、应用框架、内核、契约、入口文件、服务提供者、路由、门面。</b></p>
<p>laravel框架的架构模式（设计核心，laravel 框架是使用服务组件化的开发模式开发的，laravel框架就是由不同的服务组件构成的）</p>
<p>laravel 里面多个服务提供者构成了laravel组件。分层设计：把相同功能的类库放在同一个文件夹里面。</p>
<p>laravel框架有多个类组成服务，由多个服务组成组件。类 -&gt; 服务 -&gt; 组件</p>
<p>laravel使用组件化的开发模式，多个类 -&gt; 服务 -&gt; 组件，多个类组成服务，多个服务构成组件。多个组件提供不同的服务，然后多个服务构成我们的项目。</p>
<h2>容器：执行依赖注入和管理依赖的工具</h2>
<ul>
<li>【绑定】对象、实例（共享实例）、接口（接口到实现）、闭包4个抽象和具体类到容器数组中。</li>
<li>【解析】已绑定的抽象（通过反射机制实现解析具体类中的依赖注入），即创建实例。</li>
</ul>
<p>整一个框架里面就围绕这个容器提供依赖的，所以相当于一个心脏，也是 laravel 的一个心脏。</p>
<h2>应用程序</h2>
<p>在构造函数中注册基本绑定和注册基本服务</p>
<ul>
<li>构造函数中【注册基本绑定】到容器共享实例数组中：绑定自身到app 抽象；绑定自身到从容器类抽象</li>
<li>构造函数中【注册基本服务】到容器绑定数组中：包含但不限于：路由对象、请求对象、日志契约接口到文件日志实现类、文件日志服务对象、mysql日志服务对象</li>
</ul>
<h2>内核</h2>
<ul>
<li>内核类通过构造函数将依赖（应用框架（容器））注入</li>
<li>并在构造函数中解析路由对象到内核的属性中</li>
<li>将请求对象传入到路由对象（在构造函数中解析路由对象到内核的属性中）的请求分发方法中</li>
</ul>
<h2>请求生命周期</h2>
<p>理论上，生命周期主要有这么些阶段，但其中，开发者大多数只需关注路由、中间件、控制器、闭包函数、逻辑处理等几步</p>
<p>当然，每一步的内部，还是会有更多细化的执行流程，在这里，一般不深入研究框架或改造框架，很少会细化研究，但研究底层，依旧是学习的好选择</p>
<h2>服务</h2>
<p>说的就是提供给你所需要的东西，在laravel里面所提供的服务有 认证服务、数据库服务、缓存服务、队列服务等等。laravel框架所有服务都定义在了app/config/app.php 里面</p>
<h2>服务提供者</h2>
<p>可以给你提供一组服务的东西就是服务提供者，laravel里面如上所示其实定义的服务器提供者，比如</p>
<ol>
<li>IlluminateAuthAuthServiceProvider::class,提供认证服务的服务提供者</li>
<li>IlluminateCacheCacheServiceProvider::class,提供缓存服务的服务提供者</li>
</ol>
<p><b>好处</b>:开发者可以节省下更多的精力去处理项目逻辑，且不同开发个体之间能达到一定默契，最重要的是，项目达到分层解耦，业务逻辑只依赖于服务，并不依赖于服务底层的实现。</p>
<p>解耦之后，我们可以任意升级或自定义服务的底层实现，只要确保底层类实现了该服务</p>
<p><b>总结</b>：其实服务是一个抽象的概念，服务器提供者是完成这个抽象概念的具体实施者</p>
<h2>服务容器</h2>
<p>把所有的服务放在一个盒子里，存放服务的容器。laravel里面的服务容器位于：vendor/laravel/frameworksrcilluminateContainerContainer.php. Container.php </p>
<p>就是laravel框架的服务容器</p>
<h2>契约</h2>
<p>用来规划服务提供者的格式、方法、参数等，给服务提供者规范了一定约束。所以在框架里面所有的契约都是接口，这样才能规范服务提供者。</p>
<h2>门面</h2>
<p>门面再一次展示了Laravel在设计上的优秀，它让Laravel变得更加灵活易扩展，那么它的概念是：</p>
<ul>
<li>为开发者提供服务容器中服务的静态代理。</li>
<li>它对服务访问方式做了补充，之前使用服务必须获取服务的实例，再调用服务的方法，但使用facade，就可以直接把服务当静态对象来调用了。</li>
<li>config/app.php中服务别名alias大多数都使用了facade</li>
<li>使用facade是有风险的，并不是用的越多越好，这在手册上有少量的介绍，但具体的，还是需要开发中去发现</li>
</ul>
<h2>入口文件</h2>
<ul>
<li>实例化应用框架.。</li>
<li>通过路由门面类的静态方法执行路由配置。具体执行流程查看门面相应的内容即可。</li>
<li>绑定内核契约的接口到实现。</li>
<li>解析内核契约对象接口（即获取实现契约接口的具体实现类的实例化对象）。</li>
<li>调用请求对象设置请求地址到请求对象的属性中，并将请求对象返回的方法。</li>
<li>将请求对象传入到内核的处理请求方法中。</li>
</ul>
<h2>路由对象</h2>
<ul>
<li>将路由配置项添加到路由对象的路由表中</li>
<li>请求分发方法执行查找路由表的方法</li>
<li>执行匹配到请求的路由，即执行控制器下的方法或者立即执行闭包。</li>
</ul>
<h2>点关注，不迷路</h2>
<p>好了各位，以上就是这篇文章的全部内容了，能看到这里的人呀，都是<b>人才</b>。之前说过，PHP方面的技术点很多，也是因为太多了，实在是写不过来，写过来了大家也不会看的太多，所以我这里把它整理成了PDF和文档，如果有需要的可以<a href="https://link.zhihu.com/?target=https%3A//shimo.im/docs/rjJttdvCJpYtHpW3/" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">进阶PHP月薪30k&gt;&gt;&gt;架构师成长路线【视频、面试文档免费获取】</a> 《进阶PHP月薪30k&gt;&gt;&gt;架构师成长路线【视频、面试文档免费获取】》</p>
</div>
</div>
</article>
<p>The post <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com/software-engineering/laravel/21810/topic-364906604/" data-wpel-link="internal">【PHP】用了这么久的Laravel框架，你分析过核心架构了没</a> appeared first on <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com" data-wpel-link="internal">成長駭客交流第一站 - HyperGrowths™</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Laravel的生命周期</title>
		<link>https://hypergrowths.com/software-engineering/laravel/21630/topic-353526842/</link>
		
		<dc:creator><![CDATA[marketer]]></dc:creator>
		<pubDate>Fri, 30 Apr 2021 09:08:50 +0000</pubDate>
				<category><![CDATA[Laravel]]></category>
		<guid isPermaLink="false">https://hypergrowths.com/software-engineering/laravel/21630/topic-353526842/</guid>

					<description><![CDATA[<p>目录 简介 一、Composer 自动加载项目依赖 二、创建应用实例 创建容器 绑定内核 HTTP 内核类 Console 内核 绑定异常处理 三、接收请求并响应 解析内核 处理 HTTP 请求 发送响应 四、终止应用程序 五、总结 Referen…</p>
<p>The post <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com/software-engineering/laravel/21630/topic-353526842/" data-wpel-link="internal">Laravel的生命周期</a> appeared first on <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com" data-wpel-link="internal">成長駭客交流第一站 - HyperGrowths™</a>.</p>
]]></description>
										<content:encoded><![CDATA[<article class="Post-Main Post-NormalMain">
<header class="Post-Header">
<h1 class="Post-Title">Laravel的生命周期</h1>
<div class="Post-Author">
<div class="AuthorInfo"></div>
</div>
</header>
<div class="Post-RichTextContainer">
<div class="RichText ztext Post-RichText">
<p><b>目录</b></p>
<ul>
<li> 简介</li>
<li> 一、Composer 自动加载项目依赖</li>
<li> 二、创建应用实例</li>
<li> 创建容器</li>
<li> 绑定内核<br /> HTTP 内核类 Console 内核 绑定异常处理</li>
<li> 三、接收请求并响应</li>
<li> 解析内核</li>
<li>处理 HTTP 请求</li>
<li> 发送响应</li>
<li> 四、终止应用程序</li>
<li> 五、总结</li>
<li> References</li>
</ul>
<p>Laravel的生命周期开始于 public/index.php，结束于 public/index.php。</p>
<p>客户端的所有请求都经由Web服务器引导到这个文件中。</p>
<p>以下是public/index.php 文件的源码和注释：</p>
<div class="highlight">
<pre><code class="language-php"><span class="c1">#public/index.php 文件
</span><span class="c1">// 定义了laravel一个请求的开始时间
</span><span class="nx">define</span><span class="p">(</span><span class="s1">'LARAVEL_START'</span><span class="p">,</span><span class="nx">microtime</span><span class="p">(</span><span class="k">true</span><span class="p">));</span><span class="c1">// composer自动加载机制，加载项目依赖
</span><span class="k">require</span><span class="no">__DIR__</span><span class="o">.</span><span class="s1">'/../vendor/autoload.php'</span><span class="p">;</span><span class="c1">// 这句话你就可以理解laravel,在最开始引入了一个ioc容器。
</span><span class="nv">$app</span><span class="o">=</span><span class="k">require_once</span><span class="no">__DIR__</span><span class="o">.</span><span class="s1">'/../bootstrap/app.php'</span><span class="p">;</span><span class="c1">// 这个相当于我们创建了Kernel::class的服务提供者
</span><span class="nv">$kernel</span><span class="o">=</span><span class="nv">$app</span><span class="o">-&gt;</span><span class="na">make</span><span class="p">(</span><span class="nx">IlluminateContractsHttpKernel</span><span class="o">::</span><span class="na">class</span><span class="p">);</span><span class="c1">// 获取一个 Request ，返回一个 Response。以把该内核想象作一个代表整个应用的大黑盒子，输入 HTTP 请求，返回 HTTP 响应
</span><span class="c1">// 处理请求
</span><span class="nv">$response</span><span class="o">=</span><span class="nv">$kernel</span><span class="o">-&gt;</span><span class="na">handle</span><span class="p">(</span><span class="c1">// 创建请求实例
</span><span class="nv">$request</span><span class="o">=</span><span class="nx">IlluminateHttpRequest</span><span class="o">::</span><span class="na">capture</span><span class="p">()</span><span class="p">);</span><span class="c1">// 发送响应，就是把我们服务器的结果返回给浏览器。
</span><span class="nv">$response</span><span class="o">-&gt;</span><span class="na">send</span><span class="p">();</span><span class="c1">// 终止程序，这个就是执行我们比较耗时的请求，
</span><span class="nv">$kernel</span><span class="o">-&gt;</span><span class="na">terminate</span><span class="p">(</span><span class="nv">$request</span><span class="p">,</span><span class="nv">$response</span><span class="p">);</span></code></pre>
</div>
<p>由上可知 Laravel 的生命周期分为以下3个主要阶段：</p>
<ul>
<li>加载项目依赖。</li>
<li>创建Laravel应用实例</li>
<li>接收请求并响应。</li>
</ul>
<p>接下来我们根据 public/index.php 文件，开始 Laravel 的生命周期之旅吧！</p>
<h3>一、Composer 自动加载项目依赖</h3>
<div class="highlight">
<pre><code class="language-php"><span class="c1">// composer自动加载机制
</span><span class="k">require</span><span class="no">__DIR__</span><span class="o">.</span><span class="s1">'/../vendor/autoload.php'</span><span class="p">;</span></code></pre>
</div>
<p>Composer 是 PHP 的包管理器，用来管理项目依赖的工具，autoload.php 中引入了 Composer 自动生成的加载程序，实现加载第三方依赖。</p>
<p>autoload.php 文件代码：</p>
<div class="highlight">
<pre><code class="language-php"><span class="c1">// autoload.php @generated by Composer
</span><span class="k">require_once</span><span class="no">__DIR__</span><span class="o">.</span><span class="s1">'/composer/autoload_real.php'</span><span class="p">;</span><span class="k">return</span><span class="nx">ComposerAutoloaderInit101671ca9bbc2f62f8335eb842637291</span><span class="o">::</span><span class="na">getLoader</span><span class="p">();</span></code></pre>
</div>
<h3>二、创建应用实例</h3>
<div class="highlight">
<pre><code class="language-php"><span class="nv">$app</span><span class="o">=</span><span class="k">require_once</span><span class="no">__DIR__</span><span class="o">.</span><span class="s1">'/../bootstrap/app.php'</span><span class="p">;</span></code></pre>
</div>
<p>bootstrap/app.php 文件代码：</p>
<div class="highlight">
<pre><code class="language-php"><span class="c1">// 创建Laravel应用的ioc容器，
</span><span class="nv">$app</span><span class="o">=</span><span class="k">new</span><span class="nx">IlluminateFoundationApplication</span><span class="p">(</span><span class="nv">$_ENV</span><span class="p">[</span><span class="s1">'APP_BASE_PATH'</span><span class="p">]</span><span class="o">??</span><span class="nx">dirname</span><span class="p">(</span><span class="no">__DIR__</span><span class="p">)</span><span class="p">);</span><span class="c1">// 完成内核的绑定
</span><span class="nv">$app</span><span class="o">-&gt;</span><span class="na">singleton</span><span class="p">(</span><span class="nx">IlluminateContractsHttpKernel</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="nx">AppHttpKernel</span><span class="o">::</span><span class="na">class</span><span class="p">);</span><span class="nv">$app</span><span class="o">-&gt;</span><span class="na">singleton</span><span class="p">(</span><span class="nx">IlluminateContractsConsoleKernel</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="nx">AppConsoleKernel</span><span class="o">::</span><span class="na">class</span><span class="p">);</span><span class="nv">$app</span><span class="o">-&gt;</span><span class="na">singleton</span><span class="p">(</span><span class="nx">IlluminateContractsDebugExceptionHandler</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="nx">AppExceptionsHandler</span><span class="o">::</span><span class="na">class</span><span class="p">);</span><span class="c1">// 返回实例
</span><span class="k">return</span><span class="nv">$app</span><span class="p">;</span></code></pre>
</div>
<p>如果你理解了 Ioc（控制反转），那么对于以上代码你一定很熟悉。</p>
<p>Ioc 容器（服务容器） 是 Laravel 的核心，这一阶段主要实现了 2大功能：</p>
<ul>
<li> 1、创建容器</li>
<li> 2、绑定内核</li>
</ul>
<h3>创建容器</h3>
<div class="highlight">
<pre><code class="language-php"><span class="nv">$app</span><span class="o">=</span><span class="k">new</span><span class="nx">IlluminateFoundationApplication</span><span class="p">(</span><span class="nv">$_ENV</span><span class="p">[</span><span class="s1">'APP_BASE_PATH'</span><span class="p">]</span><span class="o">??</span><span class="nx">dirname</span><span class="p">(</span><span class="no">__DIR__</span><span class="p">)</span><span class="p">);</span></code></pre>
</div>
<p>我们进入 IlluminateFoundationApplication  容器中，以下是构造函数的分析：</p>
<div class="highlight">
<pre><code class="language-php"><span class="sd">/**
</span><span class="sd">     * Create a new Illuminate application instance.
</span><span class="sd">     *
</span><span class="sd">     * @param  string|null  $basePath
</span><span class="sd">     * @return void
</span><span class="sd">     */</span><span class="k">public</span><span class="k">function</span><span class="fm">__construct</span><span class="p">(</span><span class="nv">$basePath</span><span class="o">=</span><span class="k">null</span><span class="p">)</span><span class="p">{</span><span class="k">if</span><span class="p">(</span><span class="nv">$basePath</span><span class="p">)</span><span class="p">{</span><span class="c1">// 1、路径绑定
</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">setBasePath</span><span class="p">(</span><span class="nv">$basePath</span><span class="p">);</span><span class="p">}</span><span class="c1">// 2、基础绑定
</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">registerBaseBindings</span><span class="p">();</span><span class="c1">// 3、基础服务提供者绑定（事件，日志，路由）
</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">registerBaseServiceProviders</span><span class="p">();</span><span class="c1">// 4、核心别名绑定，目的是给核心的类命名空间设置别名，以便后续使用
</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">registerCoreContainerAliases</span><span class="p">();</span><span class="p">}</span></code></pre>
</div>
<h3>绑定内核</h3>
<div class="highlight">
<pre><code class="language-php"><span class="c1">// 完成内核的绑定
</span><span class="c1">// HTTP内核
</span><span class="nv">$app</span><span class="o">-&gt;</span><span class="na">singleton</span><span class="p">(</span><span class="nx">IlluminateContractsHttpKernel</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="nx">AppHttpKernel</span><span class="o">::</span><span class="na">class</span><span class="p">);</span><span class="c1">// Console内核
</span><span class="nv">$app</span><span class="o">-&gt;</span><span class="na">singleton</span><span class="p">(</span><span class="nx">IlluminateContractsConsoleKernel</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="nx">AppConsoleKernel</span><span class="o">::</span><span class="na">class</span><span class="p">);</span><span class="c1">// 绑定异常处理
</span><span class="nv">$app</span><span class="o">-&gt;</span><span class="na">singleton</span><span class="p">(</span><span class="nx">IlluminateContractsDebugExceptionHandler</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="nx">AppExceptionsHandler</span><span class="o">::</span><span class="na">class</span><span class="p">);</span></code></pre>
</div>
<p>在 Laravel 中只要是通过 public/index.php 来启动框架的，都会用到 Http Kernel（主要作用就是接受请求并返回响应），而其他的例如通过 artisan 命令、计划任务、队列等启动框架进行处理的都会用到 Console 内核。</p>
<p>其中 HTTP 内核类继承 IlluminateFoundationHttpKernel ，HTTP内核类中定义了中间件相关数组，中间件主要是提供了一种方便机制用来过滤进入应用的请求和处理HTTP响应。</p>
<p>HTTP 内核类：</p>
<div class="highlight">
<pre><code class="language-php"><span class="o">&lt;?</span><span class="nx">php</span><span class="k">namespace</span><span class="nx">AppHttp</span><span class="p">;</span><span class="k">use</span><span class="nx">IlluminateFoundationHttpKernel</span><span class="k">as</span><span class="nx">HttpKernel</span><span class="p">;</span><span class="k">class</span><span class="nc">Kernel</span><span class="k">extends</span><span class="nx">HttpKernel</span><span class="p">{</span><span class="sd">/**
</span><span class="sd">     * The application's global HTTP middleware stack.
</span><span class="sd">     *
</span><span class="sd">     * These middleware are run during every request to your application.
</span><span class="sd">     *
</span><span class="sd">     * @var array
</span><span class="sd">     */</span><span class="k">protected</span><span class="nv">$middleware</span><span class="o">=</span><span class="p">[</span><span class="nx">AppHttpMiddlewareTrustProxies</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="nx">AppHttpMiddlewareCheckForMaintenanceMode</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="nx">IlluminateFoundationHttpMiddlewareValidatePostSize</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="nx">AppHttpMiddlewareTrimStrings</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="nx">IlluminateFoundationHttpMiddlewareConvertEmptyStringsToNull</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="p">];</span><span class="sd">/**
</span><span class="sd">     * The application's route middleware groups.
</span><span class="sd">     *
</span><span class="sd">     * @var array
</span><span class="sd">     */</span><span class="k">protected</span><span class="nv">$middlewareGroups</span><span class="o">=</span><span class="p">[</span><span class="s1">'web'</span><span class="o">=&gt;</span><span class="p">[</span><span class="nx">AppHttpMiddlewareEncryptCookies</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="nx">IlluminateCookieMiddlewareAddQueuedCookiesToResponse</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="nx">IlluminateSessionMiddlewareStartSession</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="c1">// IlluminateSessionMiddlewareAuthenticateSession::class,
</span><span class="nx">IlluminateViewMiddlewareShareErrorsFromSession</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="nx">AppHttpMiddlewareVerifyCsrfToken</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="nx">IlluminateRoutingMiddlewareSubstituteBindings</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="p">],</span><span class="s1">'api'</span><span class="o">=&gt;</span><span class="p">[</span><span class="s1">'throttle:60,1'</span><span class="p">,</span><span class="s1">'bindings'</span><span class="p">,</span><span class="p">],</span><span class="p">];</span><span class="sd">/**
</span><span class="sd">     * The application's route middleware.
</span><span class="sd">     *
</span><span class="sd">     * These middleware may be assigned to groups or used individually.
</span><span class="sd">     *
</span><span class="sd">     * @var array
</span><span class="sd">     */</span><span class="k">protected</span><span class="nv">$routeMiddleware</span><span class="o">=</span><span class="p">[</span><span class="s1">'auth'</span><span class="o">=&gt;</span><span class="nx">AppHttpMiddlewareAuthenticate</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="s1">'auth.basic'</span><span class="o">=&gt;</span><span class="nx">IlluminateAuthMiddlewareAuthenticateWithBasicAuth</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="s1">'bindings'</span><span class="o">=&gt;</span><span class="nx">IlluminateRoutingMiddlewareSubstituteBindings</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="s1">'cache.headers'</span><span class="o">=&gt;</span><span class="nx">IlluminateHttpMiddlewareSetCacheHeaders</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="s1">'can'</span><span class="o">=&gt;</span><span class="nx">IlluminateAuthMiddlewareAuthorize</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="s1">'guest'</span><span class="o">=&gt;</span><span class="nx">AppHttpMiddlewareRedirectIfAuthenticated</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="s1">'signed'</span><span class="o">=&gt;</span><span class="nx">IlluminateRoutingMiddlewareValidateSignature</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="s1">'throttle'</span><span class="o">=&gt;</span><span class="nx">IlluminateRoutingMiddlewareThrottleRequests</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="s1">'verified'</span><span class="o">=&gt;</span><span class="nx">IlluminateAuthMiddlewareEnsureEmailIsVerified</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="p">];</span><span class="sd">/**
</span><span class="sd">     * The priority-sorted list of middleware.
</span><span class="sd">     *
</span><span class="sd">     * This forces non-global middleware to always be in the given order.
</span><span class="sd">     *
</span><span class="sd">     * @var array
</span><span class="sd">     */</span><span class="k">protected</span><span class="nv">$middlewarePriority</span><span class="o">=</span><span class="p">[</span><span class="nx">IlluminateSessionMiddlewareStartSession</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="nx">IlluminateViewMiddlewareShareErrorsFromSession</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="nx">AppHttpMiddlewareAuthenticate</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="nx">IlluminateSessionMiddlewareAuthenticateSession</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="nx">IlluminateRoutingMiddlewareSubstituteBindings</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="nx">IlluminateAuthMiddlewareAuthorize</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="p">];</span><span class="p">}</span></code></pre>
</div>
<p>HTTP内核类的父类：IlluminateFoundationHttpKernel 提供了名为 $bootstrappers 的引导程序数组，包括了环境检测、加载配置、处理异常、Facades注册、服务提供者注册、启动服务这6个 程序。</p>
<div class="highlight">
<pre><code class="language-php"><span class="sd">/**
</span><span class="sd">     * The bootstrap classes for the application.
</span><span class="sd">     *
</span><span class="sd">     * @var array
</span><span class="sd">     */</span><span class="k">protected</span><span class="nv">$bootstrappers</span><span class="o">=</span><span class="p">[</span><span class="nx">IlluminateFoundationBootstrapLoadEnvironmentVariables</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="nx">IlluminateFoundationBootstrapLoadConfiguration</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="nx">IlluminateFoundationBootstrapHandleExceptions</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="nx">IlluminateFoundationBootstrapRegisterFacades</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="nx">IlluminateFoundationBootstrapRegisterProviders</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="nx">IlluminateFoundationBootstrapBootProviders</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="p">];</span></code></pre>
</div>
<p>Console 内核：</p>
<p>一个健壮的应用程序除了满足网络请求外，还应该包括执行计划任务、异步队列等，Laravel中通过artisan工具定义各种命令来完成非 HTTP 请求的各种场景。<code>artisan</code>命令通过 Laravel 的 Console 内核完成对应用核心组件的调度来完成任务。</p>
<p>Console 内核在这不做详细介绍。</p>
<h3>绑定异常处理</h3>
<p>异常处理由 AppExceptionsHandler 类完成，所有的异常处理都由其处理，在这里同样不做详细介绍。</p>
<h3>三、接收请求并响应</h3>
<h3>解析内核</h3>
<div class="highlight">
<pre><code class="language-php"><span class="nv">$kernel</span><span class="o">=</span><span class="nv">$app</span><span class="o">-&gt;</span><span class="na">make</span><span class="p">(</span><span class="nx">IlluminateContractsHttpKernel</span><span class="o">::</span><span class="na">class</span><span class="p">);</span></code></pre>
</div>
<p>这里将 HTTP 内核解析出来，我们进一步查看IlluminateContractsHttpKernel::class 的内部代码，</p>
<p>构造函数中注入了app容器和路由器2个函数，在实例化内核的过程中，将内核中定义的中间件注册到路由器中，注册完成后便可以处理HTTP请求前调用中间件 实现过滤请求的目的。</p>
<p>IlluminateFoundationHttpKernel 的构造函数：</p>
<div class="highlight">
<pre><code class="language-php"><span class="sd">/**
</span><span class="sd">     * Create a new HTTP kernel instance.
</span><span class="sd">     *
</span><span class="sd">     * @param  IlluminateContractsFoundationApplication  $app
</span><span class="sd">     * @param  IlluminateRoutingRouter  $router
</span><span class="sd">     * @return void
</span><span class="sd">     */</span><span class="k">public</span><span class="k">function</span><span class="fm">__construct</span><span class="p">(</span><span class="nx">Application</span><span class="nv">$app</span><span class="p">,</span><span class="nx">Router</span><span class="nv">$router</span><span class="p">)</span><span class="p">{</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">app</span><span class="o">=</span><span class="nv">$app</span><span class="p">;</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">router</span><span class="o">=</span><span class="nv">$router</span><span class="p">;</span><span class="nv">$router</span><span class="o">-&gt;</span><span class="na">middlewarePriority</span><span class="o">=</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">middlewarePriority</span><span class="p">;</span><span class="k">foreach</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">middlewareGroups</span><span class="k">as</span><span class="nv">$key</span><span class="o">=&gt;</span><span class="nv">$middleware</span><span class="p">)</span><span class="p">{</span><span class="nv">$router</span><span class="o">-&gt;</span><span class="na">middlewareGroup</span><span class="p">(</span><span class="nv">$key</span><span class="p">,</span><span class="nv">$middleware</span><span class="p">);</span><span class="p">}</span><span class="k">foreach</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">routeMiddleware</span><span class="k">as</span><span class="nv">$key</span><span class="o">=&gt;</span><span class="nv">$middleware</span><span class="p">)</span><span class="p">{</span><span class="nv">$router</span><span class="o">-&gt;</span><span class="na">aliasMiddleware</span><span class="p">(</span><span class="nv">$key</span><span class="p">,</span><span class="nv">$middleware</span><span class="p">);</span><span class="p">}</span><span class="p">}</span><span class="c1">// IlluminateRoutingRouter 类中
</span><span class="sd">/**
</span><span class="sd">     * Register a group of middleware.
</span><span class="sd">     *
</span><span class="sd">     * @param  string  $name
</span><span class="sd">     * @param  array  $middleware
</span><span class="sd">     * @return $this
</span><span class="sd">     */</span><span class="k">public</span><span class="k">function</span><span class="nf">middlewareGroup</span><span class="p">(</span><span class="nv">$name</span><span class="p">,</span><span class="k">array</span><span class="nv">$middleware</span><span class="p">)</span><span class="p">{</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">middlewareGroups</span><span class="p">[</span><span class="nv">$name</span><span class="p">]</span><span class="o">=</span><span class="nv">$middleware</span><span class="p">;</span><span class="k">return</span><span class="nv">$this</span><span class="p">;</span><span class="p">}</span><span class="sd">/**
</span><span class="sd">     * Register a short-hand name for a middleware.
</span><span class="sd">     *
</span><span class="sd">     * @param  string  $name
</span><span class="sd">     * @param  string  $class
</span><span class="sd">     * @return $this
</span><span class="sd">     */</span><span class="k">public</span><span class="k">function</span><span class="nf">aliasMiddleware</span><span class="p">(</span><span class="nv">$name</span><span class="p">,</span><span class="nv">$class</span><span class="p">)</span><span class="p">{</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">middleware</span><span class="p">[</span><span class="nv">$name</span><span class="p">]</span><span class="o">=</span><span class="nv">$class</span><span class="p">;</span><span class="k">return</span><span class="nv">$this</span><span class="p">;</span><span class="p">}</span></code></pre>
</div>
<h3>处理 HTTP 请求</h3>
<div class="highlight">
<pre><code class="language-php"><span class="c1">// handle 方法处理请求
</span><span class="nv">$response</span><span class="o">=</span><span class="nv">$kernel</span><span class="o">-&gt;</span><span class="na">handle</span><span class="p">(</span><span class="c1">// 创建请求实例
</span><span class="nv">$request</span><span class="o">=</span><span class="nx">IlluminateHttpRequest</span><span class="o">::</span><span class="na">capture</span><span class="p">()</span><span class="p">);</span></code></pre>
</div>
<p>创建请求实例：在处理请求过程之前会通过 IlluminateHttpRequest 的 capture 方法，以进入应用的HTTP请求訊息为基础，创建出一个 Laravel Request请求实例，在后续应用剩余的生命周期中Request请求实例就是对本次HTTP请求的抽象。</p>
<div class="highlight">
<pre><code class="language-php"><span class="sd">/**
</span><span class="sd">     * Create a new Illuminate HTTP request from server variables.
</span><span class="sd">     *
</span><span class="sd">     * @return static
</span><span class="sd">     */</span><span class="k">public</span><span class="k">static</span><span class="k">function</span><span class="nf">capture</span><span class="p">()</span><span class="p">{</span><span class="k">static</span><span class="o">::</span><span class="na">enableHttpMethodParameterOverride</span><span class="p">();</span><span class="k">return</span><span class="k">static</span><span class="o">::</span><span class="na">createFromBase</span><span class="p">(</span><span class="nx">SymfonyRequest</span><span class="o">::</span><span class="na">createFromGlobals</span><span class="p">());</span><span class="p">}</span><span class="sd">/**
</span><span class="sd">     * Creates a new request with values from PHP's super globals.
</span><span class="sd">     *
</span><span class="sd">     * @return static
</span><span class="sd">     */</span><span class="k">public</span><span class="k">static</span><span class="k">function</span><span class="nf">createFromGlobals</span><span class="p">()</span><span class="p">{</span><span class="nv">$request</span><span class="o">=</span><span class="nx">self</span><span class="o">::</span><span class="na">createRequestFromFactory</span><span class="p">(</span><span class="nv">$_GET</span><span class="p">,</span><span class="nv">$_POST</span><span class="p">,</span><span class="p">[],</span><span class="nv">$_COOKIE</span><span class="p">,</span><span class="nv">$_FILES</span><span class="p">,</span><span class="nv">$_SERVER</span><span class="p">);</span><span class="k">if</span><span class="p">(</span><span class="mi">0</span><span class="o">===</span><span class="nx">strpos</span><span class="p">(</span><span class="nv">$request</span><span class="o">-&gt;</span><span class="na">headers</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">(</span><span class="s1">'CONTENT_TYPE'</span><span class="p">),</span><span class="s1">'application/x-www-form-urlencoded'</span><span class="p">)</span><span class="o">&amp;&amp;</span><span class="nx">in_array</span><span class="p">(</span><span class="nx">strtoupper</span><span class="p">(</span><span class="nv">$request</span><span class="o">-&gt;</span><span class="na">server</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">(</span><span class="s1">'REQUEST_METHOD'</span><span class="p">,</span><span class="s1">'GET'</span><span class="p">)),</span><span class="p">[</span><span class="s1">'PUT'</span><span class="p">,</span><span class="s1">'DELETE'</span><span class="p">,</span><span class="s1">'PATCH'</span><span class="p">])</span><span class="p">)</span><span class="p">{</span><span class="nx">parse_str</span><span class="p">(</span><span class="nv">$request</span><span class="o">-&gt;</span><span class="na">getContent</span><span class="p">(),</span><span class="nv">$data</span><span class="p">);</span><span class="nv">$request</span><span class="o">-&gt;</span><span class="na">request</span><span class="o">=</span><span class="k">new</span><span class="nx">ParameterBag</span><span class="p">(</span><span class="nv">$data</span><span class="p">);</span><span class="p">}</span><span class="k">return</span><span class="nv">$request</span><span class="p">;</span><span class="p">}</span></code></pre>
</div>
<p>handle 处理请求：将 HTTP 请求抽象成 Laravel Request 请求实例后，请求实例会被传导进入到HTTP内核的 handle 方法内部，请求的处理就是由 handle 方法来完成的。</p>
<div class="highlight">
<pre><code class="language-php"><span class="k">namespace</span><span class="nx">IlluminateFoundationHttp</span><span class="p">;</span><span class="k">class</span><span class="nc">Kernel</span><span class="k">implements</span><span class="nx">KernelContract</span><span class="p">{</span><span class="sd">/**
</span><span class="sd">     * Handle an incoming HTTP request.
</span><span class="sd">     *
</span><span class="sd">     * @param  IlluminateHttpRequest  $request
</span><span class="sd">     * @return IlluminateHttpResponse
</span><span class="sd">     */</span><span class="k">public</span><span class="k">function</span><span class="nf">handle</span><span class="p">(</span><span class="nv">$request</span><span class="p">)</span><span class="p">{</span><span class="k">try</span><span class="p">{</span><span class="nv">$request</span><span class="o">-&gt;</span><span class="na">enableHttpMethodParameterOverride</span><span class="p">();</span><span class="nv">$response</span><span class="o">=</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">sendRequestThroughRouter</span><span class="p">(</span><span class="nv">$request</span><span class="p">);</span><span class="p">}</span><span class="k">catch</span><span class="p">(</span><span class="nx">Exception</span><span class="nv">$e</span><span class="p">)</span><span class="p">{</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">reportException</span><span class="p">(</span><span class="nv">$e</span><span class="p">);</span><span class="nv">$response</span><span class="o">=</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">renderException</span><span class="p">(</span><span class="nv">$request</span><span class="p">,</span><span class="nv">$e</span><span class="p">);</span><span class="p">}</span><span class="k">catch</span><span class="p">(</span><span class="nx">Throwable</span><span class="nv">$e</span><span class="p">)</span><span class="p">{</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">reportException</span><span class="p">(</span><span class="nv">$e</span><span class="o">=</span><span class="k">new</span><span class="nx">FatalThrowableError</span><span class="p">(</span><span class="nv">$e</span><span class="p">));</span><span class="nv">$response</span><span class="o">=</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">renderException</span><span class="p">(</span><span class="nv">$request</span><span class="p">,</span><span class="nv">$e</span><span class="p">);</span><span class="p">}</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">app</span><span class="p">[</span><span class="s1">'events'</span><span class="p">]</span><span class="o">-&gt;</span><span class="na">dispatch</span><span class="p">(</span><span class="k">new</span><span class="nx">EventsRequestHandled</span><span class="p">(</span><span class="nv">$request</span><span class="p">,</span><span class="nv">$response</span><span class="p">)</span><span class="p">);</span><span class="k">return</span><span class="nv">$response</span><span class="p">;</span><span class="p">}</span><span class="p">}</span></code></pre>
</div>
<p>handle 方法接收了一个请求，并在最后返回了一个 HTTP响应。</p>
<p>接下来进入 sendRequestThroughRouter 方法，通过中间件/路由器发送给定的请求。</p>
<p>该方法的程序执行如下：</p>
<p>1、将 request 请求实例注册到 app 容器当中</p>
<p>2、清除之前的 request 实例缓存</p>
<p>3、启动引导程序：加载内核中定义的引导程序来引导启动应用</p>
<p>4、将请求发送到路由：通过 Pipeline 对象传输 HTTP请求对象流经框架中定义的HTTP中间件和路由器来完成过滤请求，最终将请求传递给处理程序（控制器方法或者路由中的闭包）由处理程序返回相应的响应。</p>
<div class="highlight">
<pre><code class="language-php"><span class="sd">/**
</span><span class="sd">     * Send the given request through the middleware / router.
</span><span class="sd">     *
</span><span class="sd">     * @param  IlluminateHttpRequest  $request
</span><span class="sd">     * @return IlluminateHttpResponse
</span><span class="sd">     */</span><span class="k">protected</span><span class="k">function</span><span class="nf">sendRequestThroughRouter</span><span class="p">(</span><span class="nv">$request</span><span class="p">)</span><span class="p">{</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">app</span><span class="o">-&gt;</span><span class="na">instance</span><span class="p">(</span><span class="s1">'request'</span><span class="p">,</span><span class="nv">$request</span><span class="p">);</span><span class="nx">Facade</span><span class="o">::</span><span class="na">clearResolvedInstance</span><span class="p">(</span><span class="s1">'request'</span><span class="p">);</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">bootstrap</span><span class="p">();</span><span class="k">return</span><span class="p">(</span><span class="k">new</span><span class="nx">Pipeline</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">app</span><span class="p">))</span><span class="o">-&gt;</span><span class="na">send</span><span class="p">(</span><span class="nv">$request</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">through</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">app</span><span class="o">-&gt;</span><span class="na">shouldSkipMiddleware</span><span class="p">()</span><span class="o">?</span><span class="p">[]</span><span class="o">:</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">middleware</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">then</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">dispatchToRouter</span><span class="p">());</span><span class="p">}</span></code></pre>
</div>
<p>bootstrap 引导程序</p>
<div class="highlight">
<pre><code class="language-php"><span class="sd">/**
</span><span class="sd">     * Bootstrap the application for HTTP requests.
</span><span class="sd">     *
</span><span class="sd">     * @return void
</span><span class="sd">     */</span><span class="k">public</span><span class="k">function</span><span class="nf">bootstrap</span><span class="p">()</span><span class="p">{</span><span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">app</span><span class="o">-&gt;</span><span class="na">hasBeenBootstrapped</span><span class="p">())</span><span class="p">{</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">app</span><span class="o">-&gt;</span><span class="na">bootstrapWith</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">bootstrappers</span><span class="p">());</span><span class="p">}</span><span class="p">}</span><span class="sd">/**
</span><span class="sd">     * Get the bootstrap classes for the application.
</span><span class="sd">     *
</span><span class="sd">     * @return array
</span><span class="sd">     */</span><span class="k">protected</span><span class="k">function</span><span class="nf">bootstrappers</span><span class="p">()</span><span class="p">{</span><span class="k">return</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">bootstrappers</span><span class="p">;</span><span class="p">}</span><span class="sd">/**
</span><span class="sd">     * The bootstrap classes for the application.
</span><span class="sd">     *
</span><span class="sd">     * @var array
</span><span class="sd">     */</span><span class="k">protected</span><span class="nv">$bootstrappers</span><span class="o">=</span><span class="p">[</span><span class="nx">IlluminateFoundationBootstrapLoadEnvironmentVariables</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="nx">IlluminateFoundationBootstrapLoadConfiguration</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="nx">IlluminateFoundationBootstrapHandleExceptions</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="nx">IlluminateFoundationBootstrapRegisterFacades</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="nx">IlluminateFoundationBootstrapRegisterProviders</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="nx">IlluminateFoundationBootstrapBootProviders</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="p">];</span><span class="cm">/*引导启动Laravel应用程序
</span><span class="cm">1. DetectEnvironment  检查环境
</span><span class="cm">2. LoadConfiguration  加载应用配置
</span><span class="cm">3. ConfigureLogging   配置日至
</span><span class="cm">4. HandleException    注册异常处理的Handler
</span><span class="cm">5. RegisterFacades    注册Facades 
</span><span class="cm">6. RegisterProviders  注册Providers 
</span><span class="cm">7. BootProviders      启动Providers
</span><span class="cm">*/</span></code></pre>
</div>
<p>关于引导程序的启动原理，有时间我们再抽出来看看。</p>
<h3>发送响应</h3>
<div class="highlight">
<pre><code class="language-php"><span class="nv">$response</span><span class="o">-&gt;</span><span class="na">send</span><span class="p">();</span></code></pre>
</div>
<p>经过了以上阶段，终于获取到了我们想要的数据，接下来是将数据响应到客户端。</p>
<p>程序由在 IlluminateHttpResponse 内部由其父类 SymfonyComponentHttpFoundationResponse 的 send() 方法实现。</p>
<div class="highlight">
<pre><code class="language-php"><span class="sd">/**
</span><span class="sd">     * Sends HTTP headers and content.
</span><span class="sd">     *
</span><span class="sd">     * @return $this
</span><span class="sd">     */</span><span class="k">public</span><span class="k">function</span><span class="nf">send</span><span class="p">()</span><span class="p">{</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">sendHeaders</span><span class="p">();</span><span class="c1">// 发送头部訊息
</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">sendContent</span><span class="p">();</span><span class="c1">// 发送报文主题
</span><span class="k">if</span><span class="p">(</span><span class="nx">function_exists</span><span class="p">(</span><span class="s1">'fastcgi_finish_request'</span><span class="p">))</span><span class="p">{</span><span class="nx">fastcgi_finish_request</span><span class="p">();</span><span class="p">}</span><span class="k">elseif</span><span class="p">(</span><span class="o">!</span><span class="nx">in_array</span><span class="p">(</span><span class="nx">PHP_SAPI</span><span class="p">,</span><span class="p">[</span><span class="s1">'cli'</span><span class="p">,</span><span class="s1">'phpdbg'</span><span class="p">],</span><span class="k">true</span><span class="p">))</span><span class="p">{</span><span class="k">static</span><span class="o">::</span><span class="na">closeOutputBuffers</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="k">true</span><span class="p">);</span><span class="p">}</span><span class="k">return</span><span class="nv">$this</span><span class="p">;</span><span class="p">}</span></code></pre>
</div>
<h3>四、终止应用程序</h3>
<p>该过程调用终止中间件。</p>
<p>响应完成后，HTTP 内核会调用 terminate  中间件做一些后续的处理工作。比如，Laravel 内置的  session 中间件会在响应发送到浏览器之后将会话数据写入存储器中。</p>
<p>HTTP 内核的 terminate 方法会调用 terminate 中间件的 terminate 方法，调用完成后，整个生命周期结束。</p>
<div class="highlight">
<pre><code class="language-php"><span class="nv">$kernel</span><span class="o">-&gt;</span><span class="na">terminate</span><span class="p">(</span><span class="nv">$request</span><span class="p">,</span><span class="nv">$response</span><span class="p">);</span><span class="sd">/**
</span><span class="sd">     * Call the terminate method on any terminable middleware.
</span><span class="sd">     *
</span><span class="sd">     * @param  IlluminateHttpRequest  $request
</span><span class="sd">     * @param  IlluminateHttpResponse  $response
</span><span class="sd">     * @return void
</span><span class="sd">     */</span><span class="k">public</span><span class="k">function</span><span class="nf">terminate</span><span class="p">(</span><span class="nv">$request</span><span class="p">,</span><span class="nv">$response</span><span class="p">)</span><span class="p">{</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">terminateMiddleware</span><span class="p">(</span><span class="nv">$request</span><span class="p">,</span><span class="nv">$response</span><span class="p">);</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">app</span><span class="o">-&gt;</span><span class="na">terminate</span><span class="p">();</span><span class="p">}</span><span class="sd">/**
</span><span class="sd">     * Call the terminate method on any terminable middleware.
</span><span class="sd">     *
</span><span class="sd">     * @param  IlluminateHttpRequest  $request
</span><span class="sd">     * @param  IlluminateHttpResponse  $response
</span><span class="sd">     * @return void
</span><span class="sd">     */</span><span class="k">protected</span><span class="k">function</span><span class="nf">terminateMiddleware</span><span class="p">(</span><span class="nv">$request</span><span class="p">,</span><span class="nv">$response</span><span class="p">)</span><span class="p">{</span><span class="nv">$middlewares</span><span class="o">=</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">app</span><span class="o">-&gt;</span><span class="na">shouldSkipMiddleware</span><span class="p">()</span><span class="o">?</span><span class="p">[]</span><span class="o">:</span><span class="nx">array_merge</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">gatherRouteMiddleware</span><span class="p">(</span><span class="nv">$request</span><span class="p">),</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">middleware</span><span class="p">);</span><span class="k">foreach</span><span class="p">(</span><span class="nv">$middlewares</span><span class="k">as</span><span class="nv">$middleware</span><span class="p">)</span><span class="p">{</span><span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nx">is_string</span><span class="p">(</span><span class="nv">$middleware</span><span class="p">))</span><span class="p">{</span><span class="k">continue</span><span class="p">;</span><span class="p">}</span><span class="p">[</span><span class="nv">$name</span><span class="p">]</span><span class="o">=</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">parseMiddleware</span><span class="p">(</span><span class="nv">$middleware</span><span class="p">);</span><span class="nv">$instance</span><span class="o">=</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">app</span><span class="o">-&gt;</span><span class="na">make</span><span class="p">(</span><span class="nv">$name</span><span class="p">);</span><span class="k">if</span><span class="p">(</span><span class="nx">method_exists</span><span class="p">(</span><span class="nv">$instance</span><span class="p">,</span><span class="s1">'terminate'</span><span class="p">))</span><span class="p">{</span><span class="nv">$instance</span><span class="o">-&gt;</span><span class="na">terminate</span><span class="p">(</span><span class="nv">$request</span><span class="p">,</span><span class="nv">$response</span><span class="p">);</span><span class="p">}</span><span class="p">}</span><span class="p">}</span></code></pre>
</div>
<h3>五、总结</h3>
<p>在Laravel 的整个生命周期中，加载项目依赖、创建应用实例、接收并响应请求，终止程序，内核都起到了串联作用。</p>
<p>首先，创建 Laravel 应用程序 阶段时，包含了注册项目基础服务、注册项目服务提供者别名、注册目录路径、异常类绑定等工作，同时在HTTP 内核中配置了引导程序。 接着，在 接收请求并响应 阶段时，会根据运行的环境解析出 HTTP 内核或 Console 内核。在 HTTP 内核中把中间件注册到路由器中。 然后，处理请求阶段的过程中，将请求的实例注册到app容器中，通过引导程序启动应用，最后发送请求到路由。 之后，通过Response类响应数据。 最后，通过terminate 方法终止程序。</p>
<p>以上就是关于 Laravel 生命周期的详细解析。</p>
<h3>References</h3>
<p><code>[1]</code> 深度挖掘 Laravel 生命周期: <a href="https://link.zhihu.com/?target=https%3A//learnku.com/articles/10421/depth-mining-of-laravel-life-cycle" class=" external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external"><span class="invisible">https://</span><span class="visible">learnku.com/articles/10</span><span class="invisible">421/depth-mining-of-laravel-life-cycle</span></a></p>
<p><code>[2]</code> Laravel 的生命周期: <a href="https://link.zhihu.com/?target=https%3A//learnku.com/articles/10421/depth-mining-of-laravel-life-cycle" class=" external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external"><span class="invisible">https://</span><span class="visible">learnku.com/articles/10</span><span class="invisible">421/depth-mining-of-laravel-life-cycle</span></a></p>
<p>ps：喜欢的朋友可以关注微信公众号（苏小怪的梦呓）和我一起成长。</p>
</div>
</div>
</article>
<p>The post <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com/software-engineering/laravel/21630/topic-353526842/" data-wpel-link="internal">Laravel的生命周期</a> appeared first on <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com" data-wpel-link="internal">成長駭客交流第一站 - HyperGrowths™</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>【PHP】23 个你应该知道的 Laravel 面试问题</title>
		<link>https://hypergrowths.com/software-engineering/laravel/21607/topic-340742883/</link>
		
		<dc:creator><![CDATA[marketer]]></dc:creator>
		<pubDate>Fri, 30 Apr 2021 09:08:40 +0000</pubDate>
				<category><![CDATA[Laravel]]></category>
		<category><![CDATA[进阶PHP月薪30k]]></category>
		<guid isPermaLink="false">https://hypergrowths.com/software-engineering/laravel/21607/topic-340742883/</guid>

					<description><![CDATA[<p>探索下一次技术面试之前应该了解的前20个 Laravel 面试问题。 Q1：什么是Laravel？主题: Laravel 难度: ⭐Laravel 是一个免费的开放源代码 PHP Web 框架，由 Taylor Otwell 创建，旨在遵循模型-视图-控制器(MVC)架…</p>
<p>The post <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com/software-engineering/laravel/21607/topic-340742883/" data-wpel-link="internal">【PHP】23 个你应该知道的 Laravel 面试问题</a> appeared first on <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com" data-wpel-link="internal">成長駭客交流第一站 - HyperGrowths™</a>.</p>
]]></description>
										<content:encoded><![CDATA[<article class="Post-Main Post-NormalMain">
<header class="Post-Header">
<h1 class="Post-Title">【PHP】23 个你应该知道的 Laravel 面试问题</h1>
<div class="Post-Author">
<div class="AuthorInfo"></div>
</div>
</header>
<div class="Post-RichTextContainer">
<div class="RichText ztext Post-RichText">
<p>探索下一次技术面试之前应该了解的前20个 Laravel 面试问题。</p>
<p><b>Q1：什么是Laravel？</b></p>
<blockquote><p>主题: Laravel<br />难度: <img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p></blockquote>
<p>Laravel 是一个免费的开放源代码 PHP Web 框架，由 Taylor Otwell 创建，旨在遵循模型-视图-控制器(MVC)架构模式开发 Web 应用程序。</p>
<p><b>Q2: Laravel 与其他 Php 框架相比有哪些好处？</b></p>
<blockquote><p>主题: Laravel<br />难度: <img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p></blockquote>
<ul>
<li>与其他框架相比，设置和自定义过程既简单又快速。</li>
<li>内置认证系统</li>
<li>支持多个文件系统</li>
<li>预装软件包，例如 Laravel Socialite，Laravel cashier，Laravel elixir，Passport，Laravel Scout</li>
<li>PHP active record 实现的 Eloquent ORM (对象关系映射)</li>
<li>内置命令行工具 “Artisan”，用于创建代码框架，数据库结构并构建其迁移</li>
</ul>
<p><b>Q3：解释 Laravel 中的迁移</b></p>
<blockquote><p>主题: Laravel<br />难度: <img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p></blockquote>
<p>Laravel Migrations 类似于数据库的版本控制，使团队可以轻松地修改和共享应用程序的数据库架构。迁移通常与 Laravel 的架构生成器搭配使用，以轻松构建应用程序的数据库架构。</p>
<p><b>Q4：Facade Pattern 有什么用？</b></p>
<blockquote><p>主题: Laravel<br />难度: <img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p></blockquote>
<p>Facades 为应用程序的服务容器中可用的类提供了一个 静态 接口。Laravel facades 作为服务容器中基础类的静态代理，提供了简洁、表达性强的语法的优势，同时保持了比传统静态方法更高的可测试性和灵活性。</p>
<p>所有的 Laravel facades 都是在 IlluminateSupportFacades 命名空间中定义。</p>
<p>查看:</p>
<div class="highlight">
<pre><code class="language-text">use IlluminateSupportFacadesCache;

Route::get('/cache', function () {
    return Cache::get('key');
});</code></pre>
</div>
<p><b>Q5：什么是服务容器？</b></p>
<blockquote><p>主题: Laravel<br />难度: <img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p></blockquote>
<p>Laravel 服务容器 是用于管理类依赖性和执行依赖性注入的工具。</p>
<p><b>Q6：什么是 Eloquent Models？</b></p>
<blockquote><p>主题: Laravel<br />难度: <img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p></blockquote>
<p>Laravel 附带的 Eloquent ORM 提供了一个漂亮、简单的 ActiveRecord 实现，用于处理数据库。每个数据库表都有一个对应的模型，用于与该表进行交互。通过模型，您可以查询表中的数据，以及将新记录插入表中。</p>
<p><b>Q7：什么是Laravel事件？</b></p>
<blockquote><p>主题: Laravel<br />难度: <img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p></blockquote>
<p>Laravel 事件提供了一个简单的观察者模式实现，允许订阅和监听应用程序中的事件。事件是程序检测并处理的事故或事情。</p>
<p>以下是 Laravel 中的一些事件範例：</p>
<ul>
<li>新用户注册</li>
<li>发布新评论</li>
<li>用户登录/注销</li>
<li>添加了新产品。</li>
</ul>
<p><b>Q8：你对 Laravel 中的查询生成器了解多少？</b></p>
<blockquote><p>主题: Laravel<br />难度: <img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p></blockquote>
<p>Laravel 的数据库查询构建器为创建和运行数据库查询提供了方便，流畅的接口。它可以用于在应用程序中执行大多数数据库操作，并且可以在所有支持的数据库系统上工作。</p>
<p>Laravel 查询构建器使用 PDO 参数绑定来保护应用程序免受 SQL 注入攻击。无需清除作为绑定传递的字符串。</p>
<p>查询生成器的一些功能：</p>
<ul>
<li>分块</li>
<li>聚合</li>
<li>Selects</li>
<li>原生方法</li>
<li>Joins</li>
<li>Unions</li>
<li>Where 语句</li>
<li>Ordering，Grouping，Limit，&amp; Offset</li>
</ul>
<p><b>Q9：如何生成迁移？</b></p>
<blockquote><p>主题: Laravel<br />难度: <img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p></blockquote>
<p>迁移就像您数据库的版本控制一样，使您的团队可以轻松地修改和共享应用程序的数据库架构。迁移通常与 Laravel 的架构构建器搭配使用，以轻松构建应用程序的数据库架构。</p>
<p>要创建迁移，使用 make：migration Artisan 命令：</p>
<div class="highlight">
<pre><code class="language-text">php artisan make:migration create_users_table</code></pre>
</div>
<p>新的迁移将放置在您的 database/migrations 目录中。每个迁移文件名都包含一个时间戳，该时间戳使 Laravel 可以确定迁移的顺序。</p>
<p><b>Q10：如何 mock 一个静态 facade 方法？</b></p>
<blockquote><p>主题：Laravel<br />难度：<img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p></blockquote>
<p>Facades 为应用程序的服务容器中可用的类提供“静态”接口。与传统的静态方法调用不同，Facades 是可被 mock 的。我们可以使用 shouldReceive 方法 mock 对静态外观方法的调用，该方法将返回 Mockery mock 的实例。</p>
<div class="highlight">
<pre><code class="language-text">// 实际代码
$value = Cache::get('key');

// 测试
Cache::shouldReceive('get')
                    -&gt;once()
                    -&gt;with('key')
                    -&gt;andReturn('value');</code></pre>
</div>
<p><b>Q11：Eager Loading 有什么好处，何时使用？</b></p>
<blockquote><p>主题: Laravel<br />难度: <img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p></blockquote>
<p>当访问 Eloquent 关系作为属性时，关系数据是 “Lazy Loaded” 的。这意味着直到您首次访问该属性，关系数据才被实际加载。但是，Eloquent 可以在查询父模型时 “Eager Load” 关系。</p>
<p>当我们有嵌套对象时(例如书本-&gt;作者)，Eager Loading 减轻了 N + 1 查询的问题。我们可以使用 Eager Loading 将此操作减少为仅2个查询。</p>
<p><b>Q12：本地作用域有何用？</b></p>
<blockquote><p>主题: Laravel<br />难度: <img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p></blockquote>
<p>Scopes 允许您轻松地在模型中复用查询逻辑。要定义 scope，只需在模型方法的前面加上 scope：</p>
<div class="highlight">
<pre><code class="language-text">class User extends Model {
    public function scopePopular($query)
    {
        return $query-&gt;where('votes', '&gt;', 100);
    }

    public function scopeWomen($query)
    {
        return $query-&gt;whereGender('W');
    }
}</code></pre>
</div>
<p>用法:</p>
<div class="highlight">
<pre><code class="language-text">$users = User::popular()-&gt;women()-&gt;orderBy('created_at')-&gt;get();</code></pre>
</div>
<p>有时您可能希望定义一个接受参数的 scope。Dynamic scopes 接受查询参数：</p>
<div class="highlight">
<pre><code class="language-text">class User extends Model {
    public function scopeOfType($query, $type)
    {
        return $query-&gt;whereType($type);
    }
}</code></pre>
</div>
<p>用法:</p>
<div class="highlight">
<pre><code class="language-text">$users = User::ofType('member')-&gt;get();</code></pre>
</div>
<p><b>Q13：Laravel中的路由命名是什么？</b></p>
<blockquote><p>主题: Laravel<br />难度: <img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p></blockquote>
<p>路由命名使得在生成重定向或者 URL 的时候更加方便地引用路由。您可以通过将 name 方法加到路由定义上来指定命名路由：</p>
<div class="highlight">
<pre><code class="language-text">Route::get('user/profile', function () {
    //
})-&gt;name('profile');</code></pre>
</div>
<p>您可以为控制器操作指定路由名称：</p>
<div class="highlight">
<pre><code class="language-text">Route::get('user/profile', 'UserController@showProfile')-&gt;name('profile');</code></pre>
</div>
<p>为路由分配名称后，您可以在生成 URL 或重定向时，通过全局路由功能使用路由名称：</p>
<div class="highlight">
<pre><code class="language-text">// Generating URLs...
$url = route('profile');

// Generating Redirects...
return redirect()-&gt;route('profile');</code></pre>
</div>
<p><b>Q14：Laravel中的闭包是什么？</b></p>
<blockquote><p>主题：Laravel<br />难度：<img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p></blockquote>
<p>闭包是一个匿名函数。闭包通常用作回调方法，并且可以用作函数中的参数</p>
<div class="highlight">
<pre><code class="language-text">function handle(Closure $closure) {
    $closure('Hello World!');
}

handle(function($value){
    echo $value;
});</code></pre>
</div>
<p><b>Q15：列出 Laravel 中查询构建器提供的一些聚合方法？</b></p>
<blockquote><p>主题: Laravel<br />难度: <img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p></blockquote>
<p>聚合函数是一种功能，能够将多行的值组合在一起，作为某些条件下的输入，以形成具有更重要含义或度量值(例如集合，包或列表)的单个值。</p>
<p>以下是 Laravel 查询构建器提供的一些聚合方法的列表：</p>
<ul>
<li>count()</li>
</ul>
<div class="highlight">
<pre><code class="language-text">$products = DB::table(‘products’)-&gt;count();</code></pre>
</div>
<ul>
<li>max()</li>
</ul>
<div class="highlight">
<pre><code class="language-text">$price = DB::table(‘orders’)-&gt;max(‘price’);</code></pre>
</div>
<ul>
<li>min()</li>
</ul>
<div class="highlight">
<pre><code class="language-text">$price = DB::table(‘orders’)-&gt;min(‘price’);</code></pre>
</div>
<ul>
<li>avg()</li>
</ul>
<div class="highlight">
<pre><code class="language-text">*$price = DB::table(‘orders’)-&gt;avg(‘price’);</code></pre>
</div>
<ul>
<li>sum()</li>
</ul>
<div class="highlight">
<pre><code class="language-text">$price = DB::table(‘orders’)-&gt;sum(‘price’);</code></pre>
</div>
<p><b>Q16：什么是 Laravel 中的反向路由？</b></p>
<blockquote><p>主题：Laravel<br />难度：<img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p></blockquote>
<p>在 Laravel 中，反向路由会根据路由声明生成 URL。反向路由使您的应用程序更加灵活。例如，下面的路由声明告诉 Laravel 当请求的 URI 为 “login” 时在 users 控制器中执行 “login” 操作。</p>
<p><a href="https://link.zhihu.com/?target=http%3A//mysite.com/login" class=" external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external"><span class="invisible">http://</span><span class="visible">mysite.com/login</span></a></p>
<div class="highlight">
<pre><code class="language-text">Route::get(‘login’, ‘users@login’);</code></pre>
</div>
<p>使用反向路由，我们可以创建到它的链接并传递我们定义的任何参数。如果未提供可选参数，则会从生成的链接中删除。</p>
<div class="highlight">
<pre><code class="language-text">{{ HTML::link_to_action('users@login') }}</code></pre>
</div>
<p>它将在视图中创建类似 <a href="https://link.zhihu.com/?target=http%3A//mysite.com/login" class=" external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external"><span class="invisible">http://</span><span class="visible">mysite.com/login</span></a> 的链接。</p>
<p><b>Q17: ：让我们为 PHP 创建枚举，提供一些代码範例。</b></p>
<blockquote><p>主题: PHP<br />难度: <img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p></blockquote>
<p>如果我们的代码需要对枚举常量和值进行更多验证，该怎么办？</p>
<p>根据使用情况，我通常会使用类似以下的简单内容：</p>
<div class="highlight">
<pre><code class="language-text">abstract class DaysOfWeek
{
    const Sunday = 0;
    const Monday = 1;
    // etc.
}

$today = DaysOfWeek::Sunday;</code></pre>
</div>
<p>这是一个扩展的範例，可以更好地服务于更广泛的案例：</p>
<div class="highlight">
<pre><code class="language-text">abstract class BasicEnum {
    private static $constCacheArray = NULL;

    private static function getConstants() {
        if (self::$constCacheArray == NULL) {
            self::$constCacheArray = [];
        }
        $calledClass = get_called_class();
        if (!array_key_exists($calledClass, self::$constCacheArray)) {
            $reflect = new ReflectionClass($calledClass);
            self::$constCacheArray[$calledClass] = $reflect - &gt; getConstants();
        }
        return self::$constCacheArray[$calledClass];
    }

    public static function isValidName($name, $strict = false) {
        $constants = self::getConstants();

        if ($strict) {
            return array_key_exists($name, $constants);
        }

        $keys = array_map('strtolower', array_keys($constants));
        return in_array(strtolower($name), $keys);
    }

    public static function isValidValue($value, $strict = true) {
        $values = array_values(self::getConstants());
        return in_array($value, $values, $strict);
    }
}</code></pre>
</div>
<p>我们可以将其用作：</p>
<div class="highlight">
<pre><code class="language-text">abstract class DaysOfWeek extends BasicEnum {
    const Sunday = 0;
    const Monday = 1;
    const Tuesday = 2;
    const Wednesday = 3;
    const Thursday = 4;
    const Friday = 5;
    const Saturday = 6;
}

DaysOfWeek::isValidName('Humpday');                  // false
DaysOfWeek::isValidName('Monday');                   // true
DaysOfWeek::isValidName('monday');                   // true
DaysOfWeek::isValidName('monday', $strict = true);   // false
DaysOfWeek::isValidName(0);                          // false

DaysOfWeek::isValidValue(0);                         // true
DaysOfWeek::isValidValue(5);                         // true
DaysOfWeek::isValidValue(7);                         // false
DaysOfWeek::isValidValue('Friday');                  // false</code></pre>
</div>
<p><b>Q18：什么是PHP自动加载类？</b></p>
<blockquote><p>主题: PHP<br />难度: <img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p></blockquote>
<p>使用自动加载器，PHP 允许在由于错误而失败之前最后一次加载类或接口。</p>
<p>PHP中的 spl_autoload_register()函数可以注册任意数量的自动加载器，即使未定义类和接口也可以自动加载。</p>
<div class="highlight">
<pre><code class="language-text">spl_autoload_register(function ($classname) {
    include  $classname . '.php';
});
$object  = new Class1();
$object2 = new Class2();</code></pre>
</div>
<p>在上面的範例中，我们不需要包含 Class1.php 和 Class2.php。spl_autoload_register() 函数将自动加载 Class1.php 和 Class2.php。</p>
<p><b>Q19：PHP是否支持方法重载？</b></p>
<blockquote><p>主题：PHP<br />难度：<img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p></blockquote>
<p>方法重载是使用具有不同签名的相同方法名称的现象。PHP 中函数签名仅基于它们的名称，并且不包含参数列表，因此不能有两个具有相同名称的函数，所以 PHP 不支持方法重载。</p>
<p>但是，您可以声明一个可变函数，它接受可变数量的参数。您可以使用 func_num_args() 和 func_get_arg() 来传递参数并正常使用它们。</p>
<div class="highlight">
<pre><code class="language-text">function myFunc() {
    for ($i = 0; $i &lt; func_num_args(); $i++) {
        printf("Argument %d: %sn", $i, func_get_arg($i));
    }
}

/*
Argument 0: a
Argument 1: 2
Argument 2: 3.5
*/
myFunc('a', 2, 3.5);</code></pre>
</div>
<p><b>Q20：Laravel 中为什么需要 Traits？</b></p>
<blockquote><p>主题: Laravel<br />难度: <img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p></blockquote>
<p>Traits 已被添加到 PHP 中，原因很简单s：PHP 不支持多重继承。简而言之，一个类不能一次性扩展至多个类。当你需要在其他类也使用的两个不同类中声明的功能时，这变得很费力，结果是你必须重复执行代码才能完成工作，而不会纠缠自己。</p>
<p>引入 Traits，它能使我们声明一种包含多个可复用方法的类。更好的是，它们的方法可以直接注入到你使用的任何类中，并且你可以在同一类中使用多个 Trait。让我们看一个简单的 Hello World 範例。</p>
<div class="highlight">
<pre><code class="language-text">trait SayHello
{
    private function hello()
    {
        return "Hello ";
    }

    private function world()
    {
        return "World";
    }
}

trait Talk
{
    private function speak()
    {
        echo $this-&gt;hello() . $this-&gt;world();
    }
}

class HelloWorld
{
    use SayHello;
    use Talk;

    public function __construct()
    {
        $this-&gt;speak();
    }
}

$message = new HelloWorld(); // returns "Hello World";</code></pre>
</div>
<p><b>Q21：PHP 中的 Autoloader 是什么？</b></p>
<blockquote><p>主题: Laravel<br />难度: <img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p></blockquote>
<p>自动加载器定义了自动在代码中包含 PHP 类的方法，而不必使用诸如 require 和 include 之类的语句。</p>
<p>PSR-4 将支持更简单的文件夹结构，但是将使我们仅通过查看完全限定的名称就无法知道类的确切路径。</p>
<p>PSR-0 在硬盘驱动器上比较混乱，但是支持念旧的开发人员(类名下划线用户)，并帮助我们通过以下方式辨别类的位置：看它的名字。</p>
<p><b>Q22：在 PHP 中 yield 是什么意思？</b></p>
<blockquote><p>主题: PHP<br />难度: <img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p></blockquote>
<p>解释此代码以及 yield 的作用：</p>
<div class="highlight">
<pre><code class="language-text">function a($items) {
    foreach ($items as $item) {
        yield $item + 1;
    }
}</code></pre>
</div>
<p>yield 关键字从生成器函数返回数据。生成器函数实际上是编写 Iterator 的更紧凑和有效的方式。它允许您定义一个函数，该函数将在您遍历该函数时计算并返回值。</p>
<p>因此，问题中的函数与以下内容的函数几乎相同：</p>
<div class="highlight">
<pre><code class="language-text">function b($items) {
    $result = [];
    foreach ($items as $item) {
        $result[] = $item + 1;
    }
    return $result;
}</code></pre>
</div>
<p>只有一个区别，a() 返回一个 generator，而 b() 只是一个简单的 数组。而且两者都可以被迭代。</p>
<p>函数的生成器版本未分配完整的数组，因此对内存的需求较少。生成器可用于解决内存限制。由于生成器仅按需计算其 yielded 值，因此它们用于代替计算成本昂贵或无法一次性计算的序列很有用。</p>
<p><b>Q23：$$$ 在 PHP 中是什么意思？</b></p>
<blockquote><p>主题: PHP<br />难度: <img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p></blockquote>
<p>类似 $$variable 的语法称为可变变量。</p>
<p>让我们尝试 $$$：</p>
<div class="highlight">
<pre><code class="language-text">$real_variable = 'test';
$name = 'real_variable'; // variable variable for real variable
$name_of_name = 'name'; // variable variable for variable variable

echo $name_of_name . '&lt;br /&gt;';
echo $$name_of_name . '&lt;br /&gt;';
echo $$$name_of_name . '&lt;br /&gt;';</code></pre>
</div>
<p>这是输出：</p>
<div class="highlight">
<pre><code class="language-text">name
real_variable
test</code></pre>
</div>
<h2>点关注，不迷路</h2>
<p>好了各位，以上就是程序员会在面试过程中碰到的问题，能看到这里的人呀，都是<b>人才</b>。如果你经常参加面试的话，就会发现以上面试题很熟悉。所谓“知己知彼，百战不殆”，充实自身技能，才能顺利进面。之前说过，PHP方面的技术点很多，也是因为太多了，实在是写不过来，写过来了大家也不会看的太多，所以我这里把它整理成了PDF和文档，如果有需要的可以</p>
<p><a href="https://link.zhihu.com/?target=https%3A//jq.qq.com/%3F_wv%3D1027%26k%3DVlP8r6aS" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">点击进入暗号: PHP+「平台」</a></p>
<figure data-size="normal"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-e6248a11572b53a04ec44f6408604d3f_r-1.jpg" data-caption="" data-size="normal" data-rawwidth="551" data-rawheight="359" class="origin_image zh-lightbox-thumb" width="551" data-original="https://pic4.zhimg.com/v2-e6248a11572b53a04ec44f6408604d3f_b.jpg" title="v2-e6248a11572b53a04ec44f6408604d3f_r-1"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-e6248a11572b53a04ec44f6408604d3f_r-1.jpg" data-caption="" data-size="normal" data-rawwidth="551" data-rawheight="359" class="origin_image zh-lightbox-thumb lazy" width="551" data-original="data:image/svg+xml;utf8,&lt;svg%20xmlns='http://www.w3.org/2000/svg'%20width='551'%20height='359'&gt;&lt;/svg&gt;" data-actualsrc="https://pic4.zhimg.com/v2-e6248a11572b53a04ec44f6408604d3f_b.jpg" title="v2-e6248a11572b53a04ec44f6408604d3f_r-1"></figure>
<figure data-size="normal"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-66ed359f2a56f8475fc09ef422c34f0c_r-1.jpg" data-caption="" data-size="normal" data-rawwidth="633" data-rawheight="515" class="origin_image zh-lightbox-thumb" width="633" data-original="https://pic1.zhimg.com/v2-66ed359f2a56f8475fc09ef422c34f0c_b.jpg" title="v2-66ed359f2a56f8475fc09ef422c34f0c_r-1"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-66ed359f2a56f8475fc09ef422c34f0c_r-1.jpg" data-caption="" data-size="normal" data-rawwidth="633" data-rawheight="515" class="origin_image zh-lightbox-thumb lazy" width="633" data-original="data:image/svg+xml;utf8,&lt;svg%20xmlns='http://www.w3.org/2000/svg'%20width='633'%20height='515'&gt;&lt;/svg&gt;" data-actualsrc="https://pic1.zhimg.com/v2-66ed359f2a56f8475fc09ef422c34f0c_b.jpg" title="v2-66ed359f2a56f8475fc09ef422c34f0c_r-1"></figure>
<hr>
<p>更多学习内容可以访问</p>
<p><b>以上内容希望帮助到大家</b>，很多PHPer在进阶的时候总会遇到一些问题和瓶颈，业务代码写多了没有方向感，不知道该从那里入手去提升，对此我整理了一些资料，包括但不限于：<b>分布式架构、高可扩展、高性能、高并发、服务器性能调优、TP6，laravel，YII2，Redis，Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx</b>等多个知识点高级进阶干货需要的可以免费分享给大家，需要的可以加入我的 <b><a href="https://link.zhihu.com/?target=https%3A//jq.qq.com/%3F_wv%3D1027%26k%3DVlP8r6aS" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">PHP技术交流群</a></b></p>
</div>
</div>
</article>
<p>The post <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com/software-engineering/laravel/21607/topic-340742883/" data-wpel-link="internal">【PHP】23 个你应该知道的 Laravel 面试问题</a> appeared first on <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com" data-wpel-link="internal">成長駭客交流第一站 - HyperGrowths™</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Laravel为什么会成为最优雅的PHP框架，你知道吗？</title>
		<link>https://hypergrowths.com/software-engineering/laravel/21229/topic-337972597/</link>
		
		<dc:creator><![CDATA[marketer]]></dc:creator>
		<pubDate>Fri, 30 Apr 2021 08:49:52 +0000</pubDate>
				<category><![CDATA[Laravel]]></category>
		<category><![CDATA[进阶PHP月薪30k]]></category>
		<guid isPermaLink="false">https://hypergrowths.com/software-engineering/laravel/21229/topic-337972597/</guid>

					<description><![CDATA[<p>Laravel最初的设计是为了面向MVC架构的，它可以满足如事件处理、用户身份验证等各种需求。另外它还有一个由管理数据库强力支持，用于管理模块化和可扩展性代码的软件包管理器。 Laravel以其简洁、优雅的特性赢得了…</p>
<p>The post <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com/software-engineering/laravel/21229/topic-337972597/" data-wpel-link="internal">Laravel为什么会成为最优雅的PHP框架，你知道吗？</a> appeared first on <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com" data-wpel-link="internal">成長駭客交流第一站 - HyperGrowths™</a>.</p>
]]></description>
										<content:encoded><![CDATA[<article class="Post-Main Post-NormalMain">
<header class="Post-Header">
<h1 class="Post-Title">Laravel为什么会成为最优雅的PHP框架，你知道吗？</h1>
<div class="Post-Author">
<div class="AuthorInfo"></div>
</div>
</header>
<div class="Post-RichTextContainer">
<div class="RichText ztext Post-RichText">
<p>Laravel最初的设计是为了面向MVC架构的，它可以满足如事件处理、用户身份验证等各种需求。另外它还有一个由管理数据库强力支持，用于管理模块化和可扩展性代码的软件包管理器。</p>
<p>Laravel以其简洁、优雅的特性赢得了大家的广泛关注，无论是专家还是新手，在开发PHP项目的时候，都会第一时间的想到Laravel。本文我们将讨论为什么Laravel会成为最成功的PHP框架。</p>
<h2>模块化和可扩展性</h2>
<p>Laravel注重代码的模块化和可扩展性。你可以在包含超过5500个程序包的Packalyst目录中找到你想要添加的任何文件。Laravel的目标是让你能够找到任何想要的文件。</p>
<h2>微服务和程序接口</h2>
<p>Lumen是一个由laravel衍生的专注于精简的微框架。它高性能的程序接口可让你更加简单快速的开发微型项目。Lumen使用最小的配置集成了所有laravel的重要特性，你可以通过将代码复制到laravel项目的方式将完整的框架迁移过来。</p>
<div class="highlight">
<pre><code class="language-text">get('/', function() {
return view('lumen');
});
$app&gt;post('framework/{id}', function($framework) {
$this&gt;dispatch(new Energy($framework));
});</code></pre>
</div>
<h2>HTTP路径</h2>
<p>Laravel拥有类似于Ruby on Rails的，快速、高效的路由系统。它可以让用户通过在浏览器上输入路径的方式让应用程序的各部分相关联。</p>
<div class="highlight">
<pre><code class="language-text">Route::get('/', function () {
return 'Hello World';
});</code></pre>
</div>
<h2>HTTP中间件</h2>
<p>应用程序可受到中间件的保护——中间件会处理分析和过滤服务器上的HTTP请求。你可以安装中间件，用于验证注册用户，并避免如跨站脚本(XSS)或其它的安全状况的问题。</p>
<div class="highlight">
<pre><code class="language-text">input('age') &lt;= 200) {
return redirect('home');
}
return $next($request);
}</code></pre>
</div>
<h2>缓存</h2>
<p>你的应用程序可得到一个健壮的缓存系统，通过对其进行调整，可以让应用程序的加载更加快速，这可以给你的用户提供最好的使用体验。</p>
<div class="highlight">
<pre><code class="language-text">Cache::extend('mongo', function($app) {
return Cache::repository(new MongoStore);
});</code></pre>
</div>
<h2>身份验证</h2>
<p>安全是至关重要的。Laravel自带对本地用户的身份验证，并可以使用“remember” 选项来记住用户。它还可以让你例如一些额外参数，例如显示是否为活跃的用户。</p>
<div class="highlight">
<pre><code class="language-text">if (Auth::attempt(['email' =&gt; $email, 'password' =&gt; $password, 'active' 
=&gt; 1 ], $remember)) {
// The user is being remembered...
}</code></pre>
</div>
<h2>种类集成</h2>
<p>Laravel Cashier可以满足你要开发支付系统所需要的一切需求。除此之外，它还同步并集成了用户身份验证系统。所以，你不再需要担心如何将计费系统集成到开发当中了。</p>
<div class="highlight">
<pre><code class="language-text">$user = User::find(1);
$user&gt;subscription('monthly')&gt;create($creditCardToken);</code></pre>
</div>
<h2>任务自动化</h2>
<p>Elixir是一个可让我们使用Gulp定义任务的Laravel程序接口，我们可以使用Elixir定义可精简CSS<br />和JavaScript的预处理器。</p>
<div class="highlight">
<pre><code class="language-text">elixir(function(mix) {
mix.browserify('main.js');
});</code></pre>
</div>
<h2>加密</h2>
<p>一个安全的应用程序应该做到可把数据进行加密。使用Laravel，可以启用OpenSSL安全加密算法AES256CBC来满足你所有的需求。另外，所有的加密值都是由检测加密訊息是否被改变的验证码所签署的。</p>
<div class="highlight">
<pre><code class="language-text">use IlluminateContractsEncryptionDecryptException;
try {
$decrypted = Crypt::decrypt($encryptedValue);
} catch (DecryptException $e) {
//
}</code></pre>
</div>
<h2>事件处理</h2>
<p>应用程序中事件的定义、记录和聆听都非常迅速。EventServiceProvider事件中的listen包含记录在你应用程序上所有事件的列表。</p>
<div class="highlight">
<pre><code class="language-text">protected $listen = [
'AppEventsPodcastWasPurchased' =&gt; [
'AppListenersEmailPurchaseConfirmation',
],
];</code></pre>
</div>
<h2>分页</h2>
<p>在Laravel中分页是非常容易的因为它能够根据用户的浏览器当前页面生成一系列链接。</p>
<div class="highlight">
<pre><code class="language-text">paginate(15);
return view('user.index', ['users' =&gt; $users]);
}
}</code></pre>
</div>
<h2>对象关系图(ORM)</h2>
<p>Laravel包含一个处理数据库的层，它的对象关系图被称为Eloquent。另外这个对象关系图也适用于PostgreSQL。</p>
<div class="highlight">
<pre><code class="language-text">$users = User::where('votes', '&gt;', 100)&gt;take(10)&gt;get();
foreach ($users as $user) {
var_dump($user&gt;name);
}</code></pre>
</div>
<h2>单元测试</h2>
<p>单元测试的开发是一个耗费大量时间的任务，但是它却是保证我们的应用程序保持正常工作的关键。Laravel中可使用PHPUnit执行单元测试。</p>
<div class="highlight">
<pre><code class="language-text">visit('/')
&gt;see('Laravel 5')
&gt;dontSee('Rails');
}
}</code></pre>
</div>
<h2>待办事项清单</h2>
<p>Laravel提供在后台使用待办事项清单(to do list)处理复杂、漫长流程的选择。它可以让我们异步处理某些流程而不需要用户的持续导航。</p>
<div class="highlight">
<pre><code class="language-text">Queue :: push ( new SendEmail ( $ message ));</code></pre>
</div>
<p>Laravel版本每半年都会更新一次，更多新特性还是需要大家进一步的去研究的。</p>
<p>最后留一个问题：laravel有哪些缺点？可留言交流！</p>
<h2>点关注，不迷路</h2>
<p>好了各位，以上就是这篇文章的全部内容了，能看到这里的人呀，都是<b>人才</b>。之前说过，PHP方面的技术点很多，也是因为太多了，实在是写不过来，写过来了大家也不会看的太多，所以我这里把它整理成了PDF和文档，如果有需要的可以</p>
<p><a href="https://link.zhihu.com/?target=https%3A//jq.qq.com/%3F_wv%3D1027%26k%3DVlP8r6aS" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">点击进入暗号: PHP+「平台」</a></p>
<figure data-size="normal"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-e6248a11572b53a04ec44f6408604d3f_r.jpg" data-caption="" data-size="normal" data-rawwidth="551" data-rawheight="359" class="origin_image zh-lightbox-thumb" width="551" data-original="https://pic4.zhimg.com/v2-e6248a11572b53a04ec44f6408604d3f_b.jpg" title="v2-e6248a11572b53a04ec44f6408604d3f_r"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-e6248a11572b53a04ec44f6408604d3f_r.jpg" data-caption="" data-size="normal" data-rawwidth="551" data-rawheight="359" class="origin_image zh-lightbox-thumb lazy" width="551" data-original="data:image/svg+xml;utf8,&lt;svg%20xmlns='http://www.w3.org/2000/svg'%20width='551'%20height='359'&gt;&lt;/svg&gt;" data-actualsrc="https://pic4.zhimg.com/v2-e6248a11572b53a04ec44f6408604d3f_b.jpg" title="v2-e6248a11572b53a04ec44f6408604d3f_r"></figure>
<figure data-size="normal"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-66ed359f2a56f8475fc09ef422c34f0c_r.jpg" data-caption="" data-size="normal" data-rawwidth="633" data-rawheight="515" class="origin_image zh-lightbox-thumb" width="633" data-original="https://pic1.zhimg.com/v2-66ed359f2a56f8475fc09ef422c34f0c_b.jpg" title="v2-66ed359f2a56f8475fc09ef422c34f0c_r"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-66ed359f2a56f8475fc09ef422c34f0c_r.jpg" data-caption="" data-size="normal" data-rawwidth="633" data-rawheight="515" class="origin_image zh-lightbox-thumb lazy" width="633" data-original="data:image/svg+xml;utf8,&lt;svg%20xmlns='http://www.w3.org/2000/svg'%20width='633'%20height='515'&gt;&lt;/svg&gt;" data-actualsrc="https://pic1.zhimg.com/v2-66ed359f2a56f8475fc09ef422c34f0c_b.jpg" title="v2-66ed359f2a56f8475fc09ef422c34f0c_r"></figure>
<hr>
<p>更多学习内容可以访问</p>
<p><b>以上内容希望帮助到大家</b>，很多PHPer在进阶的时候总会遇到一些问题和瓶颈，业务代码写多了没有方向感，不知道该从那里入手去提升，对此我整理了一些资料，包括但不限于：<b>分布式架构、高可扩展、高性能、高并发、服务器性能调优、TP6，laravel，YII2，Redis，Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx</b>等多个知识点高级进阶干货需要的可以免费分享给大家，需要的可以加入我的 <b><a href="https://link.zhihu.com/?target=https%3A//jq.qq.com/%3F_wv%3D1027%26k%3DVlP8r6aS" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">PHP技术交流</a></b></p>
</div>
</div>
</article>
<p>The post <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com/software-engineering/laravel/21229/topic-337972597/" data-wpel-link="internal">Laravel为什么会成为最优雅的PHP框架，你知道吗？</a> appeared first on <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com" data-wpel-link="internal">成長駭客交流第一站 - HyperGrowths™</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>laravel面试题（全网最全必考面试题）</title>
		<link>https://hypergrowths.com/software-engineering/laravel/21227/topic-275898988/</link>
		
		<dc:creator><![CDATA[marketer]]></dc:creator>
		<pubDate>Fri, 30 Apr 2021 08:49:39 +0000</pubDate>
				<category><![CDATA[Laravel]]></category>
		<category><![CDATA[架构师之路]]></category>
		<guid isPermaLink="false">https://hypergrowths.com/software-engineering/laravel/21227/topic-275898988/</guid>

					<description><![CDATA[<p>滑到最后有惊喜和福利哦！！！！1、什么是 HTTP 中间件？ HTTP 中间件是一种用于过滤 HTTP 请求的技术。Laravel 包含一个中间件，用于检查应用程序用户是否已通过身份验证。 2、聚合查询生成器的方法名称查询构建…</p>
<p>The post <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com/software-engineering/laravel/21227/topic-275898988/" data-wpel-link="internal">laravel面试题（全网最全必考面试题）</a> appeared first on <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com" data-wpel-link="internal">成長駭客交流第一站 - HyperGrowths™</a>.</p>
]]></description>
										<content:encoded><![CDATA[<article class="Post-Main Post-NormalMain">
<header class="Post-Header">
<h1 class="Post-Title">laravel面试题（全网最全必考面试题）</h1>
<div class="Post-Author">
<div class="AuthorInfo"></div>
</div>
</header>
<div class="Post-RichTextContainer">
<div class="RichText ztext Post-RichText">
<h2><b> 滑到最后有惊喜和福利哦！！！！</b></h2>
<h2><b>1、什么是 HTTP 中间件？</b></h2>
<p> HTTP 中间件是一种用于过滤 HTTP 请求的技术。Laravel 包含一个中间件，用于检查应用程序用户是否已通过身份验证。 </p>
<h3><b>2、聚合查询生成器的方法名称</b></h3>
<p>查询构建器的聚合方法是：1) max ()，2) min ()，3) sum ()，4) avg () 和 5) count ()。</p>
<h3><b>3、什么是 Route ?</b></h3>
<p>路由基本上是由 URI (统一资源标识符) 指定的端点。它在 Laravel 应用程序中充当指针。</p>
<p>最常见的是，路由指向控制器上的方法，还指出哪些 HTTP 方法可以访问该 URI。</p>
<h3><b>4、 解释 Laravel 中的反向路由。</b></h3>
<p>反向路由是一种基于符号或名称生成 URL 的方法。它使您的 Laravel 应用程序变得灵活。</p>
<h3><b>5、解释 Laravel 中 traits 的特征</b></h3>
<p>Laravel traits 是包含在另一个类中的一组函数。一个 trait 就像一个抽象类。您不能直接实例化它，但是可以在其他的类中试用它的方法。</p>
<h3><b>6、 解释 Laravel 中契约的概念。</b></h3>
<p>它们是 Laravel 框架的接口集合。这些契约提供核心服务。Laravel 中的契约包括相应的框架实现。</p>
<p><b>laravel跟tp都是PHP主流的框架，点击这里还有tp的面试题，感兴趣的小伙伴可以去了解一下。</b></p>
<h3><b>7、如何注册您的服务提供者？</b></h3>
<p>您可以在 config/app.php 配置文件中注册服务提供者，该配置文件包含一个数组，您可以在其中配置服务提供者的类名。</p>
<h3><b>8、如何定义 Laravel 的门面？</b></h3>
<p>所有的门面都定义在 Illuminate.upport.acades 命名空间当中。</p>
<h3><b>9、 Laravel 中的服务容器是什么</b></h3>
<p>服务容器是用于在 Laravel 中执行依赖注入的工具。用于存储各种注入到容器中的类库对象，首先会经过绑定到容器，然后在通过反射机制获取里面的对象，或者的时候会根据绑定的类型进行判断，例如有类、闭包、实例对象。会根据类型进行获取。</p>
<p>IOC:控制反转，从容器获取相关对象就为控制反转。控制正转就是自己实例自己的对象，给自己使用。而有了容器，就是由它帮助我们完整创建对象的过程。</p>
<p>DI:依赖注入，例如A类需要B类提供的功能，它们就存在依赖关系，而注入只是把对象B交给对象A。</p>
<h3><b>10、如何在 Laravel 中开启查询日志？</b></h3>
<p>您可以使用 enableQueryLog 方法在 Laravel 中启用查询日志。</p>
<h3><b>11、 解释 Laravel 中事件的概念。</b></h3>
<p>事件是一种动作或者操作，可以帮助您订阅和侦听 Laravel 应用程序中发生的事件。当发生任何活动时，Laravel 会自动出发某些事件。</p>
<h3><b>12、 说一下依赖注入和依赖注入的类型.</b></h3>
<p>它是‘其中一种对象依赖于另一个对象’的技术。<br />依赖注入有三种类型:</p>
<p>• 1) 构造函数注入</p>
<p>• 2) setter 注入</p>
<p>• 3) 接口注入.</p>
<h3><b>13、 使用 laravel 有什么优势吗？</b></h3>
<p>下面是 laravel 的主要优点:</p>
<p>• Laravel 具有 blade 模板引擎，可创建动态布局并增加编译任务.</p>
<p>• 可以很简单的复用代码.</p>
<p>• 您不需要手动维护和包含路径，因为 Laravel 具有自动加载功能.</p>
<p>• 该框架可帮助您使用 LOC 容器制作新工具.</p>
<p>• Laravel 提供了一个版本控制系统，可帮助简化迁移管理.</p>
<h3><b>14、 说明 Laravel 中验证的概念.</b></h3>
<p>在设计任何 Laravel 应用程序时，验证是一个重要的概念。它可以确保在将数据存储到数据库之前，数据始终采用预期的格式。Laravel 提供了多种验证数据的方法。<br />基础控制器特征是使用 ValidatesRequests 类，该类提供了一种有用的方法来验证来自客户端计算机的请求。</p>
<h3><b>15、 ORM 代表什么？</b></h3>
<p>ORM 代表对象关系映射，把数据库相关字段映射到对应的模型对象里面，相当于有多个一个抽象层。后面直接操作对象</p>
<h3><b>16、 如何减少 Laravel 中的内存使用？</b></h3>
<p>在处理大量数据时，可以使用 cursor 方法以减少内存使用量</p>
<h3><b>17、定义一下 Laravel 使用的模板引擎.*，加载原理是什么？</b></h3>
<p>Blade 是 Laravel 使用的功能强大的模板引擎。laravel根据路由检查到需要展示视图的时候，会根据请求文件的后缀找到对应的引擎，然后在进行渲染，并缓存为对应的静态文件。</p>
<h3><b>18、为什么迁移很重要？</b></h3>
<p>迁移非常重要是因为它允许您通过维护数据库一致性来共享应用程序。<br />如果不进行迁移，则很难共享任何 Laravel 应用程序。<br />它还允许您同步数据库。</p>
<h3><b>19、 解释 PHP artisan</b></h3>
<p>artisan 是 Laravel 的命令行工具。它提供的命令可帮助您轻松构建 Laravel 应用程序。</p>
<h3><b>20、 如何生成软链接？</b></h3>
<p>Laravel 用 php artisan storage:link 生成软链接。这样可以让不显示的目录供给公共请求的访问到资源。</p>
<h3><b>21、哪个类用于处理异常？</b></h3>
<p>Laravel 异常由 App.exceptions.handler 类处理。</p>
<h3><b>22、 什么是常见的 HTTP 错误代码？</b></h3>
<p>最常见的 HTTP 错误代码是：</p>
<p>- 错误 404 –未找到页面时显示。<br />- 错误 - 401 –未授权错误时显示</p>
<h3><b>23、 在 Laravel 中解释 Fluent 查询生成器。</b></h3>
<p>它是一个数据库查询生成器，它提供了方便，快捷的界面来创建和运行数据库查询。</p>
<h3><b>24、 列出 Laravel 中使用的常见 artisan 命令。</b></h3>
<p>Laravel 支持以下工匠命令：</p>
<p>• PHP artisan down;</p>
<p>• PHP artisan up;</p>
<p>• PHP artisan make:controller;</p>
<p>• PHP artisan make:model;</p>
<p>• PHP artisan make:migration;</p>
<p>• PHP artisan make:middleware;</p>
<h3><b>25、 在 Laravel 中 如何配置邮件发送？</b></h3>
<p>Laravel 提供了一些 API，可以在本地和实时服务器上发送电子邮件。</p>
<h3><b>26、授权是什么东西</b></h3>
<p>这是一种使用密码标识用户登录凭据的方法。在 Laravel 中，可以使用带有两个参数 1) 用户名和 2) 密码的会话来管理它。</p>
<h3><b>27、 delete ()：从数据库表中删除所有记录</b></h3>
<p>-delete ()：从数据库表中删除所有记录。<br />-softDeletes ()：不会从表中删除数据。它用于将任何记录标记为已删除。但需要安装好软删除。</p>
<h3><b>28、您将如何检查表是否在数据库中存在？</b></h3>
<p>使用 Laravel 中的 hasTable () 函数检查所需的表是否在数据库中存在。</p>
<p><b>29、 Laravel 中 insert () 和 insertGetId () 函数之间的显著区别是什么？</b></p>
<p>• Insert (): 此函数仅用于将记录插入数据库。不返回自增 ID</p>
<p>• InsertGetId (): 此函数会在表中插入一条记录，但当 ID 字段自动递增时使用。（插入记录并返回自增的 ID）</p>
<h3><b>30、 定义隐式控制器。</b></h3>
<p>隐式控制器可帮助您定义适当的路由来处理控制器操作。您可以使用 Route :: controller () 方法在 route.php 文件中定义它们。</p>
<h3><b>31、 如何在 Laravel 模型中自定义表名？</b></h3>
<p>自定义表名，您可以重写 protected 变量 $ table 的值。</p>
<h3><b>32、 定义 @include.</b></h3>
<p>@include 用于加载多个模板视图文件。它可以帮助您将视图包括在另一个视图中。用户还可以在一个视图中加载多个文件。</p>
<h3><b>33、 什么是 Eloquent?</b></h3>
<p>Eloquent 是 在 laravel 中使用的 ORM 。它提供了简单的 active record 实现， 配合数据库使用。每个数据库表都有其模型，该模型用于与表进行交互。</p>
<h3><b>34、 解释 Laravel guard (卫兵) </b></h3>
<p>Laravel Guard 是一个用于查找经过身份验用户的特殊组件。<br />最初将请求的传入路由通过此防护来验证用户输入的凭据。防护措施在../config/auth.php 文件中定义。</p>
<h3><b>35、 什么是 Laravel API 限流？</b></h3>
<p>这是 Laravel 的功能。它提供了限流处理功能。限流可帮助 Laravel 开发人员开发安全的应用程序并防止 DOS 攻击。</p>
<h3><b>36、 解释laravel 中的集合 Collections.</b></h3>
<p>集合 Collections 是用于数组的包装器类。Laravel Eloquent 的查询使用一组最常用的函数来返回数据库结果。</p>
<h3><b>37、 DB Facade 的用途是什么？</b></h3>
<p>DB Facade 用于运行 SQL 查询，例如创建，查询，更新，插入和删除。主要是用到了门面的静态代理，通过门面把相关类库代理到容器里面的操作类库。</p>
<h3><b>38、</b><b>对象关系映射的用途是什么？</b></h3>
<p>对象关系映射是一种技术，可帮助开发人员在不考虑对象及其数据源之间的关系的情况下寻址，访问和操纵对象。</p>
<h3><b>39、</b><b>解释 Laravel 中的路由概念。</b></h3>
<p>它允许将您所有的应用程序请求路由到控制器。Laravel 路由确认并接受带闭包的统一资源标识符。</p>
<h3><b>40、说明身份验证和授权之间的区别。</b></h3>
<p>认证是指通过凭据确认用户身份，而授权是指收集对系统的访问权限。</p>
<h3><b>41、什么监听器 - listeners，应用场景有哪些</b></h3>
<p>在EventServiceProvider的linsten数组里面加上事件和监听器，键名是事件，键值里面的数组是一个或者多个监听器，当某一个事件发生的时候，传送给数组里面的那些个监听器，在执行一系列相关的操作 </p>
<p>场景： 发送短信验证码事件、邮件、通知类相关 </p>
<h3><b>42、什么策略类？</b></h3>
<p>策略类包括 Laravel 应用程序的授权逻辑。这些类用于特定的模型或资源。</p>
<h3><b>43、什么是IOC(控制反转)？</b></h3>
<p>IOC是一种设计思想，它主要控制了外部资源获取（不只是对象包括比如文件等）。并且由容器帮我们查找及注入依赖对象，对象只是被动的接受依赖对象，所以叫控制反转。</p>
<h3><b>43、</b><b>具体讲讲依赖注入？</b></h3>
<p>由容器动态的将某个依赖关系注入到组件之中，依赖注入的目的并非为软件系统带来更多功能，而是为了提升组件重用的频率，并为系统搭建一个灵活、可扩展的平台。</p>
<p>“依赖注入”明确描述了“被注入对象依赖IoC容器配置依赖对象”。</p>
<h3><b>44、</b><b>什么是反射？</b></h3>
<p>       反射可以理解成根据类名返回该类的任何訊息，它主要用来动态地获取系统中类、实例对象、方法等语言构件的訊息，通过反射API函数可以实现对这些语言构件訊息的动态获取和动态操作等。同时反射添加了对类、接口、函数、方法和扩展进行反向工作的能力。在Laravel框架中，服务容器解析服务的过程中就用到了反射机制。</p>
<h3><b>45、</b><b>service服务容器是什么？</b></h3>
<p>服务容器是一个用于管理类依赖和执行依赖注入的强大工具，也可以理解为就是一个自动产生类的工厂。</p>
<h3><b>46、</b><b>Laravel+Redis广播如何实现？</b></h3>
<p>Redis 广播使用 Redis 的 pub/sub 功能进行广播；同时你需要将其和能够接受 Redis 消息的 Websocket 服务器进行配对以便将消息广播到 Websocket 频道。</p>
<p>当 Redis 广播发布事件时，事件将会被发布到指定的频道上，传递的数据是一个 JSON 格式的字符串，其中包含了事件名称、数据明细 data、以及生成事件socket ID 的用户。</p>
<p>在消息推送的场景下，我们可以使用 WebSocket 协议来处理实时交互，它是一种双向协议，允许服务端主动推送訊息到客户端。需要涉及内容如下：</p>
<p>1&gt;Laravel Event</p>
<p>2&gt;Redis</p>
<p>3&gt;<a href="https://link.zhihu.com/?target=http%3A//Socket.io" class=" external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external"><span class="invisible">http://</span><span class="visible">Socket.io</span></a></p>
<p>4&gt;Node.js</p>
<p>具体配置步骤如下：</p>
<p>1.安装Predis库</p>
<p>composer require predis/predis<br />2.安装 laravel-echo-server</p>
<p>npm install -g laravel-echo-server</p>
<p>3.初始化 Socket 服务：</p>
<p>laravel-echo-server init</p>
<p>4.启动服务</p>
<p>laravel-echo-server start  启动</p>
<p><b>其实这个广播可以拆解为几个部分，消息队列，发布订阅，广播，这些内容我都是有讲过对应的一些视频，有需要的小伙伴也可以关注私聊我获取。</b></p>
<h3><b>47、</b><b>任务调度是什么？</b></h3>
<p> Cron 脚本能使计划任务定期地在系统后台自动运行。一般会在队列场景应用。</p>
<p>可以定时周期的去进行实现，比如时间节点，比如每周一，周末，每十分钟这些。</p>
<h3><b>48、</b><b>Blade模板是什么？它的模板继承优势在哪？为什么要使用它？</b></h3>
<p>Blade模板是Laravel提供一个既简单又强大的模板引擎；</p>
<p>和其他流行的PHP模板引擎不一样，他并不限制你在视图里使用原生PHP代码；</p>
<p class="ztext-empty-paragraph"></p>
<p>祝小伙伴面试顺利，拿到心仪offer，奥利给！</p>
<p>如果你<b>喜欢</b>我写的<b>技术文章</b>以及<b>面试总结</b>，欢迎关注收看我的视频，并且<b>点赞、收藏、关注</b>我哦。</p>
<p>我是luke，感谢你的关注！</p>
<p><b>据说点赞，喜欢，收藏了的小伙伴面试必过，拿到心仪offer！</b></p>
</div>
</div>
</article>
<p>The post <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com/software-engineering/laravel/21227/topic-275898988/" data-wpel-link="internal">laravel面试题（全网最全必考面试题）</a> appeared first on <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com" data-wpel-link="internal">成長駭客交流第一站 - HyperGrowths™</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Laravel8使用swoole来取代nginx作为http服务器</title>
		<link>https://hypergrowths.com/software-engineering/laravel/21233/topic-269911276/</link>
		
		<dc:creator><![CDATA[marketer]]></dc:creator>
		<pubDate>Fri, 30 Apr 2021 08:49:24 +0000</pubDate>
				<category><![CDATA[Laravel]]></category>
		<category><![CDATA[程序媛学习圈]]></category>
		<guid isPermaLink="false">https://hypergrowths.com/software-engineering/laravel/21233/topic-269911276/</guid>

					<description><![CDATA[<p>1.是什么限制Laravel8框架的速度？Laravel框架启动的时候需要加载很多文件，再加上其出了名的生态环境好，所以在开发过程中我们就会发现有非常多的已经造好的轮子，这也就使得Laravel的一次启动的磁盘IO特别高（就…</p>
<p>The post <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com/software-engineering/laravel/21233/topic-269911276/" data-wpel-link="internal">Laravel8使用swoole来取代nginx作为http服务器</a> appeared first on <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com" data-wpel-link="internal">成長駭客交流第一站 - HyperGrowths™</a>.</p>
]]></description>
										<content:encoded><![CDATA[<article class="Post-Main Post-NormalMain">
<header class="Post-Header">
<h1 class="Post-Title">Laravel8使用swoole来取代nginx作为http服务器</h1>
<div class="Post-Author">
<div class="AuthorInfo"></div>
</div>
</header>
<div class="Post-RichTextContainer">
<div class="RichText ztext Post-RichText">
<p><b>1.是什么限制Laravel8框架的速度？</b></p>
<p>Laravel框架启动的时候需要加载很多文件，再加上其出了名的生态环境好，所以在开发过程中我们就会发现有非常多的已经造好的轮子，这也就使得Laravel的一次启动的磁盘IO特别高（就是要加载很多文件），现在的问题就是：每次启动Laravel的时候不都重新加载这些文件就好了，所以用swoole就能很好的解决。</p>
<p class="ztext-empty-paragraph"></p>
<p><b>2.Swoole</b></p>
<p>Swoole号称重新定义了PHP，它是一个PHP扩展，使得PHP可以使用异步的方式执行，就像node一样，而且还能使用socket，为PHP提供了一系列异步IO、事件驱动、并行数据结构功能。Swoole  可以广泛应用于互联网、移动通信、企业软件、云计算、网络游戏、物联网（IOT）、车联网、智能家居等领域。它可以大大提升项目的性能。</p>
<p class="ztext-empty-paragraph"></p>
<p><b>3.使用Swoole提升Laravel的性能</b></p>
<p>在现有的轮子中，感觉下面这两个还是非常不错的，可以自行选择</p>
<ul>
<li>swooletw/laravel-swoole</li>
<li>garveen/laravoole</li>
</ul>
<p class="ztext-empty-paragraph"></p>
<p>这里小编选择了<b>swooletw/laravel-swoole</b></p>
<p>使用composer安装：</p>
<div class="highlight">
<pre><code class="language-php"><span class="nx">composer</span><span class="k">require</span><span class="nx">swooletw</span><span class="o">/</span><span class="nx">laravel</span><span class="o">-</span><span class="nx">swoole</span><span class="nx">如果你使用的是laravel，那么在</span><span class="nx">config</span><span class="o">/</span><span class="nx">app</span><span class="o">.</span><span class="nx">php</span><span class="nx">的</span><span class="nx">providers</span><span class="nx">数组中加上</span><span class="nx">SwooleTWHttpLaravelServiceProvider</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="o">&lt;/</span><span class="nx">pre</span><span class="o">&gt;</span><span class="nx">如果你使用的是lumen，那么在</span><span class="nx">bootstrap</span><span class="o">/</span><span class="nx">app</span><span class="o">.</span><span class="nx">php</span><span class="nx">中加入如下代码</span><span class="nv">$app</span><span class="o">-&gt;</span><span class="na">register</span><span class="p">(</span><span class="nx">SwooleTWHttpLumenServiceProvider</span><span class="o">::</span><span class="na">class</span><span class="p">);</span><span class="nx">将配置文件导出到</span><span class="nx">config</span><span class="nx">目录下</span><span class="nx">php</span><span class="nx">artisan</span><span class="nx">vendor</span><span class="o">:</span><span class="nx">publish</span><span class="o">--</span><span class="nx">provider</span><span class="o">=</span><span class="s2">"SwooleTWHttpHttpServiceProvider"</span><span class="nx">然后可以去</span><span class="nx">config</span><span class="o">/</span><span class="nx">swoole_http</span><span class="o">.</span><span class="nx">php</span><span class="nx">中配置訊息</span><span class="s1">'server'</span><span class="o">=&gt;</span><span class="p">[</span><span class="s1">'host'</span><span class="o">=&gt;</span><span class="nx">env</span><span class="p">(</span><span class="s1">'SWOOLE_HTTP_HOST'</span><span class="p">,</span><span class="s1">'127.0.0.1'</span><span class="p">),</span><span class="s1">'port'</span><span class="o">=&gt;</span><span class="nx">env</span><span class="p">(</span><span class="s1">'SWOOLE_HTTP_PORT'</span><span class="p">,</span><span class="s1">'1215'</span><span class="p">),</span><span class="s1">'options'</span><span class="o">=&gt;</span><span class="p">[</span><span class="s1">'pid_file'</span><span class="o">=&gt;</span><span class="nx">env</span><span class="p">(</span><span class="s1">'SWOOLE_HTTP_PID_FILE'</span><span class="p">,</span><span class="nx">base_path</span><span class="p">(</span><span class="s1">'storage/logs/swoole_http.pid'</span><span class="p">)),</span><span class="s1">'log_file'</span><span class="o">=&gt;</span><span class="nx">env</span><span class="p">(</span><span class="s1">'SWOOLE_HTTP_LOG_FILE'</span><span class="p">,</span><span class="nx">base_path</span><span class="p">(</span><span class="s1">'storage/logs/swoole_http.log'</span><span class="p">)),</span><span class="s1">'daemonize'</span><span class="o">=&gt;</span><span class="nx">env</span><span class="p">(</span><span class="s1">'SWOOLE_HTTP_DAEMONIZE'</span><span class="p">,</span><span class="mi">1</span><span class="p">),</span><span class="p">],</span><span class="p">],</span><span class="nx">host和post不用多说，options里面的具体配置可以去swoole官网查看详细参数訊息。</span></code></pre>
</div>
<p>swoole_http.php 里还提供配置 providers 数组，</p>
<div class="highlight">
<pre><code class="language-text">'providers' =&gt; [
    // AppProvidersAuthServiceProvider::class,
]

因为使用swoole作为http后，这些providers会被存到内存中，所以这里配置的是每次
请求都想要重新注册和重新启动的providers。</code></pre>
</div>
<p><b>Artisan Commands</b></p>
<p>这个轮子完全使用artisan命令来操作。</p>
<p> php artisan swoole:http start|stop|restart|reload </p>
<p>依次是，启动/停止/重启/重载。</p>
<p>所以我们可以通过以下命令来启动<b>swoole_http_server</b></p>
<div class="highlight">
<pre><code class="language-php"><span class="nx">php</span><span class="nx">artisan</span><span class="nx">swoole</span><span class="o">:</span><span class="nx">http</span><span class="nx">start</span></code></pre>
</div>
<p>现在可以通过配置文件里的host和port去访问Laravel了，例如我的配置是： 127.0.0.1:1215 </p>
<p><b>注意</b>：该拓展是不支持热启动的，所以每次有代码更新都要重启服务 php artisan swoole:http restart 。当然你也可以在linux上写一个脚本，让 git pull 代码后自动重启服务。</p>
<p class="ztext-empty-paragraph"></p>
<p><b>4.性能测试</b></p>
<p>下面让我们来看两张图。</p>
<p>使用swoole前：</p>
<figure data-size="normal"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-5a1c9204250ed8969af7bcadc5be91e7_r.jpg" data-caption="" data-size="normal" data-rawwidth="525" data-rawheight="562" class="origin_image zh-lightbox-thumb" width="525" data-original="https://pic4.zhimg.com/v2-5a1c9204250ed8969af7bcadc5be91e7_b.jpg" title="v2-5a1c9204250ed8969af7bcadc5be91e7_r"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-5a1c9204250ed8969af7bcadc5be91e7_r.jpg" data-caption="" data-size="normal" data-rawwidth="525" data-rawheight="562" class="origin_image zh-lightbox-thumb lazy" width="525" data-original="data:image/svg+xml;utf8,&lt;svg%20xmlns='http://www.w3.org/2000/svg'%20width='525'%20height='562'&gt;&lt;/svg&gt;" data-actualsrc="https://pic4.zhimg.com/v2-5a1c9204250ed8969af7bcadc5be91e7_b.jpg" title="v2-5a1c9204250ed8969af7bcadc5be91e7_r"></figure>
<p>使用swoole后：</p>
<figure data-size="normal"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-986150fa40d7a35e03ddfe6cf1173f8e_r.jpg" data-caption="" data-size="normal" data-rawwidth="558" data-rawheight="564" class="origin_image zh-lightbox-thumb" width="558" data-original="https://pic3.zhimg.com/v2-986150fa40d7a35e03ddfe6cf1173f8e_b.jpg" title="v2-986150fa40d7a35e03ddfe6cf1173f8e_r"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-986150fa40d7a35e03ddfe6cf1173f8e_r.jpg" data-caption="" data-size="normal" data-rawwidth="558" data-rawheight="564" class="origin_image zh-lightbox-thumb lazy" width="558" data-original="data:image/svg+xml;utf8,&lt;svg%20xmlns='http://www.w3.org/2000/svg'%20width='558'%20height='564'&gt;&lt;/svg&gt;" data-actualsrc="https://pic3.zhimg.com/v2-986150fa40d7a35e03ddfe6cf1173f8e_b.jpg" title="v2-986150fa40d7a35e03ddfe6cf1173f8e_r"></figure>
<p>这里是使用Apache的ab测试工具</p>
<div class="highlight">
<pre><code class="language-php"><span class="nx">ab</span><span class="o">-</span><span class="nx">n1000</span><span class="o">-</span><span class="nx">c10</span><span class="nx">http</span><span class="o">://</span><span class="mf">127.0</span><span class="o">.</span><span class="mf">0.1</span><span class="o">:</span><span class="mi">1215</span></code></pre>
</div>
<p>我们可以惊奇的发现， Request per second 从原来的20多，提升到了600多。将近提升了30倍左右。啊，多么痛的领悟！！</p>
<p><b>5.使用Nginx代理</b></p>
<p>swoole在官网也提到过：swoole_http_server对Http协议的支持并不完整，建议仅作为应用服务器。并且在前端增加Nginx作为代理。</p>
<p>那么，我们就增加需要配置nginx.conf里的server：</p>
<div class="highlight">
<pre><code class="language-php"><span class="nx">server</span><span class="p">{</span><span class="nx">listen</span><span class="mi">80</span><span class="p">;</span><span class="nx">server_name</span><span class="nx">your</span><span class="o">.</span><span class="nx">domain</span><span class="o">.</span><span class="nx">com</span><span class="p">;</span><span class="nx">root</span><span class="o">/</span><span class="nx">path</span><span class="o">/</span><span class="nx">to</span><span class="o">/</span><span class="nx">laravel</span><span class="o">/</span><span class="k">public</span><span class="p">;</span><span class="nx">index</span><span class="nx">index</span><span class="o">.</span><span class="nx">php</span><span class="p">;</span><span class="nx">location</span><span class="o">=</span><span class="o">/</span><span class="nx">index</span><span class="o">.</span><span class="nx">php</span><span class="p">{</span><span class="c1"># Ensure that there is no such file named "not_exists"
</span><span class="c1"># in your "public" directory.
</span><span class="nx">try_files</span><span class="o">/</span><span class="nx">not_exists</span><span class="o">@</span><span class="nx">swoole</span><span class="p">;</span><span class="p">}</span><span class="nx">location</span><span class="o">/</span><span class="p">{</span><span class="nx">try_files</span><span class="nv">$uri</span><span class="nv">$uri</span><span class="o">/</span><span class="o">@</span><span class="nx">swoole</span><span class="p">;</span><span class="p">}</span><span class="nx">location</span><span class="o">@</span><span class="nx">swoole</span><span class="p">{</span><span class="nx">set</span><span class="nv">$suffix</span><span class="s2">""</span><span class="p">;</span><span class="k">if</span><span class="p">(</span><span class="nv">$uri</span><span class="o">=</span><span class="o">/</span><span class="nx">index</span><span class="o">.</span><span class="nx">php</span><span class="p">)</span><span class="p">{</span><span class="nx">set</span><span class="nv">$suffix</span><span class="s2">"/"</span><span class="p">;</span><span class="p">}</span><span class="nx">proxy_set_header</span><span class="nx">Host</span><span class="nv">$host</span><span class="p">;</span><span class="nx">proxy_set_header</span><span class="nx">SERVER_PORT</span><span class="nv">$server_port</span><span class="p">;</span><span class="nx">proxy_set_header</span><span class="nx">REMOTE_ADDR</span><span class="nv">$remote_addr</span><span class="p">;</span><span class="nx">proxy_set_header</span><span class="nx">X</span><span class="o">-</span><span class="nx">Forwarded</span><span class="o">-</span><span class="k">For</span><span class="nv">$proxy_add_x_forwarded_for</span><span class="p">;</span><span class="c1"># IF https
</span><span class="c1"># proxy_set_header HTTPS "on";
</span><span class="nx">proxy_pass</span><span class="nx">http</span><span class="o">://</span><span class="mf">127.0</span><span class="o">.</span><span class="mf">0.1</span><span class="o">:</span><span class="mi">1215</span><span class="nv">$suffix</span><span class="p">;</span><span class="p">}</span><span class="p">}</span></code></pre>
</div>
<p><b>至此，大功告成，你可以像平常一样访问你的网站了。</b></p>
<p><b>以上内容希望帮助到大家，需要更多文章可以关注公众号:PHP从入门到精通，</b>很多PHPer在进阶的时候总会遇到一些问题和瓶颈，业务代码写多了没有方向感，不知道该从那里入手去提升，对此我整理了一些PHP高级、架构视频资料和大厂PHP面试PDF免费获取,<b>需要戳这里<a href="https://link.zhihu.com/?target=https%3A//docs.qq.com/doc/DRkRsT3pvZXRmeHFK" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">PHP进阶架构师&gt;&gt;&gt;实战视频、大厂面试文档免费获取</a></b></p>
</div>
</div>
</article>
<p>The post <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com/software-engineering/laravel/21233/topic-269911276/" data-wpel-link="internal">Laravel8使用swoole来取代nginx作为http服务器</a> appeared first on <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com" data-wpel-link="internal">成長駭客交流第一站 - HyperGrowths™</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>laravel 8学习笔记</title>
		<link>https://hypergrowths.com/software-engineering/laravel/20819/topic-268450513/</link>
		
		<dc:creator><![CDATA[marketer]]></dc:creator>
		<pubDate>Fri, 30 Apr 2021 08:32:31 +0000</pubDate>
				<category><![CDATA[Laravel]]></category>
		<category><![CDATA[18岁少年编程之路]]></category>
		<guid isPermaLink="false">https://hypergrowths.com/software-engineering/laravel/20819/topic-268450513/</guid>

					<description><![CDATA[<p>菜，一如既往的菜，一些解决问题难点部分都没贴出来，可能都要私聊才会有回复。 laravel不知不觉更新到了8.x然后；也不再是5.6 ，5.8常用版本了，我们一直在学习 ~ 从未停止脚步，作为一名技术人员：见的人越来越…</p>
<p>The post <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com/software-engineering/laravel/20819/topic-268450513/" data-wpel-link="internal">laravel 8学习笔记</a> appeared first on <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com" data-wpel-link="internal">成長駭客交流第一站 - HyperGrowths™</a>.</p>
]]></description>
										<content:encoded><![CDATA[<article class="Post-Main Post-NormalMain">
<header class="Post-Header">
<h1 class="Post-Title">laravel 8学习笔记</h1>
<div class="Post-Author">
<div class="AuthorInfo"></div>
</div>
</header>
<div class="Post-RichTextContainer">
<div class="RichText ztext Post-RichText">
<p>菜，一如既往的菜，一些解决问题难点部分都没贴出来，可能都要私聊才会有回复。</p>
<p>laravel不知不觉更新到了8.x然后；也不再是5.6 ，5.8常用版本了，我们一直在学习 ~ 从未停止脚步，作为一名技术人员：见的人越来越杂了， 可是却从未碰见真正的<code>江湖</code> 。 由于下载了那些模拟器把win docker环境搞崩了，windows 装docker还是要开启虚拟化的。还好有另外一台电脑，人心险恶，包括软件也是。往往你认为稳定的环境就像在安装一个软件而崩溃的。</p>
<p> 本次会一起手写一个交易所（不上链）包括DAPP，冷链，第三方，热链等知识。不多时间定在一个月。持续更新，遇到问题会。学laravel是为了生存，也是热爱，反正没事做。 话不多说。 进入正题：</p>
<p>      1，laravel 本次更新；模型工厂类：</p>
<p>       1.1 ：模型工厂类 ：Eloquent <a href="https://link.zhihu.com/?target=https%3A//learnku.com/docs/laravel/8.x/database-testing%23creating-factories" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">模型工厂</a> 已完全重写为基于类的工厂，并有完美的关联支持。 例如 Laravel 中的 <code>UserFactory</code> 是这样写的：</p>
<p>       1.2： 怎么创建 ：适用 --model 属性 进行模型关联</p>
<div class="highlight">
<pre><code class="language-text">php artisan make:model Article
$ php artisan make:factory ArticleFactory --model Article</code></pre>
</div>
<p>        1.3：迁移压缩；压缩迁移的改进；为什么会有压缩迁移？ </p>
<p>我们开发中常常会遇到一个这样的问题：某些系统的数据库不进行对外开放链接这一措施 ；那该咋办 ？ 对就是数据库迁移文件；而且还可以有不用传输sql文件，通过版本管理更直观的看到修改者修改内容；但是缺点：你的同事也在修改这个文件，合并的时候就思密达；要求不高其实就是可以适用工具的结构合并和数据库迁移 </p>
<p>其实目的就是为了加快开发速度 ，</p>
<figure data-size="normal"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-0a82a1fc9581e9fad37833dfdeb7a51c_r.jpg" data-caption="" data-size="normal" data-rawwidth="1353" data-rawheight="505" class="origin_image zh-lightbox-thumb" width="1353" data-original="https://pic1.zhimg.com/v2-0a82a1fc9581e9fad37833dfdeb7a51c_b.jpg" title="v2-0a82a1fc9581e9fad37833dfdeb7a51c_r"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-0a82a1fc9581e9fad37833dfdeb7a51c_r.jpg" data-caption="" data-size="normal" data-rawwidth="1353" data-rawheight="505" class="origin_image zh-lightbox-thumb lazy" width="1353" data-original="data:image/svg+xml;utf8,&lt;svg%20xmlns='http://www.w3.org/2000/svg'%20width='1353'%20height='505'&gt;&lt;/svg&gt;" data-actualsrc="https://pic1.zhimg.com/v2-0a82a1fc9581e9fad37833dfdeb7a51c_b.jpg" title="v2-0a82a1fc9581e9fad37833dfdeb7a51c_r"></figure>
<div class="highlight">
<pre><code class="language-text">php artisan schema:dump  // 转储当前数据库模式并删除所有现有的迁移… 
php artisan schema:dump --prune</code></pre>
</div>
<figure data-size="normal"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-1f0030bc8d4f39985d1a8649b249d836_r.jpg" data-caption="" data-size="normal" data-rawwidth="1575" data-rawheight="608" class="origin_image zh-lightbox-thumb" width="1575" data-original="https://pic3.zhimg.com/v2-1f0030bc8d4f39985d1a8649b249d836_b.jpg" title="v2-1f0030bc8d4f39985d1a8649b249d836_r"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-1f0030bc8d4f39985d1a8649b249d836_r.jpg" data-caption="" data-size="normal" data-rawwidth="1575" data-rawheight="608" class="origin_image zh-lightbox-thumb lazy" width="1575" data-original="data:image/svg+xml;utf8,&lt;svg%20xmlns='http://www.w3.org/2000/svg'%20width='1575'%20height='608'&gt;&lt;/svg&gt;" data-actualsrc="https://pic3.zhimg.com/v2-1f0030bc8d4f39985d1a8649b249d836_b.jpg" title="v2-1f0030bc8d4f39985d1a8649b249d836_r"></figure>
<p>这不特意换的电脑；而且环境重装了 ，难受；mysqldump ？这就是mysql备份的指令了</p>
<p>把mysql 加入环境变量~ </p>
<div class="highlight">
<pre><code class="language-text">先运行创建命令行：$
php artisan migration install
php artisan make:migration create_table_article --create=aricle
php artisan make:migration update_table_article --table=aricle
--table 和 --create 选项也可用于确定表的名称以及是否在迁移中创建新的数据表。这些选项用指定的迁移模板预先填充指定的数据表：然后可以看到生成了数据迁移文件；
php artisan schema:dump

// 上面範例为转储但不删除原有迁移文件，下面範例为转储且删除原有迁移文件
php artisan schema:dump --prune</code></pre>
</div>
<p>这里如果生成了 这些.dump </p>
<p>php artisan migrate 先执行 dump 文件</p>
<figure data-size="normal"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-685f1cf754fb123db4949f05aff1223f_r.jpg" data-caption="" data-size="normal" data-rawwidth="614" data-rawheight="860" class="origin_image zh-lightbox-thumb" width="614" data-original="https://pic4.zhimg.com/v2-685f1cf754fb123db4949f05aff1223f_b.jpg" title="v2-685f1cf754fb123db4949f05aff1223f_r"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-685f1cf754fb123db4949f05aff1223f_r.jpg" data-caption="" data-size="normal" data-rawwidth="614" data-rawheight="860" class="origin_image zh-lightbox-thumb lazy" width="614" data-original="data:image/svg+xml;utf8,&lt;svg%20xmlns='http://www.w3.org/2000/svg'%20width='614'%20height='860'&gt;&lt;/svg&gt;" data-actualsrc="https://pic4.zhimg.com/v2-685f1cf754fb123db4949f05aff1223f_b.jpg" title="v2-685f1cf754fb123db4949f05aff1223f_r"></figure>
<p>如果没有.dump文件</p>
<div class="highlight">
<pre><code class="language-text">php artisan migrate 
 </code></pre>
</div>
<figure data-size="normal"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-bc567b15d8ad3910298eeb5d7ee1e2ed_r.jpg" data-caption="" data-size="normal" data-rawwidth="1084" data-rawheight="261" class="origin_image zh-lightbox-thumb" width="1084" data-original="https://pic2.zhimg.com/v2-bc567b15d8ad3910298eeb5d7ee1e2ed_b.jpg" title="v2-bc567b15d8ad3910298eeb5d7ee1e2ed_r"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-bc567b15d8ad3910298eeb5d7ee1e2ed_r.jpg" data-caption="" data-size="normal" data-rawwidth="1084" data-rawheight="261" class="origin_image zh-lightbox-thumb lazy" width="1084" data-original="data:image/svg+xml;utf8,&lt;svg%20xmlns='http://www.w3.org/2000/svg'%20width='1084'%20height='261'&gt;&lt;/svg&gt;" data-actualsrc="https://pic2.zhimg.com/v2-bc567b15d8ad3910298eeb5d7ee1e2ed_b.jpg" title="v2-bc567b15d8ad3910298eeb5d7ee1e2ed_r"></figure>
<p>2：队列批处理</p>
<figure data-size="normal"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-afc427418a46364037a2acb78f694524_r.jpg" data-caption="" data-size="normal" data-rawwidth="1269" data-rawheight="220" class="origin_image zh-lightbox-thumb" width="1269" data-original="https://pic1.zhimg.com/v2-afc427418a46364037a2acb78f694524_b.jpg" title="v2-afc427418a46364037a2acb78f694524_r"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-afc427418a46364037a2acb78f694524_r.jpg" data-caption="" data-size="normal" data-rawwidth="1269" data-rawheight="220" class="origin_image zh-lightbox-thumb lazy" width="1269" data-original="data:image/svg+xml;utf8,&lt;svg%20xmlns='http://www.w3.org/2000/svg'%20width='1269'%20height='220'&gt;&lt;/svg&gt;" data-actualsrc="https://pic1.zhimg.com/v2-afc427418a46364037a2acb78f694524_b.jpg" title="v2-afc427418a46364037a2acb78f694524_r"></figure>
<p>以前5.6，5.8的任务处理为 单处理，反正我接触到的是这样的</p>
<div class="highlight">
<pre><code class="language-text">$this-&gt;dispatch();//单任务处理
php artisan make:job Test1Job
php artisan make:job Test2Job
</code></pre>
</div>
<p>然后就生成队列的失败的数据库了，可以考虑用redis,</p>
<div class="highlight">
<pre><code class="language-text">1.生成队列数据库表与失败队列数据库表
本实例中是用群发email的实例，如果模仿，请配置自己的邮件服务
php artisan queue:table

php artisan queue:failed-table

php artisan migrate </code></pre>
</div>
<figure data-size="normal"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-f00030f3794dde6657d57ac3ab884c20_r.jpg" data-caption="" data-size="normal" data-rawwidth="568" data-rawheight="151" class="origin_image zh-lightbox-thumb" width="568" data-original="https://pic1.zhimg.com/v2-f00030f3794dde6657d57ac3ab884c20_b.jpg" title="v2-f00030f3794dde6657d57ac3ab884c20_r"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-f00030f3794dde6657d57ac3ab884c20_r.jpg" data-caption="" data-size="normal" data-rawwidth="568" data-rawheight="151" class="origin_image zh-lightbox-thumb lazy" width="568" data-original="data:image/svg+xml;utf8,&lt;svg%20xmlns='http://www.w3.org/2000/svg'%20width='568'%20height='151'&gt;&lt;/svg&gt;" data-actualsrc="https://pic1.zhimg.com/v2-f00030f3794dde6657d57ac3ab884c20_b.jpg" title="v2-f00030f3794dde6657d57ac3ab884c20_r"></figure>
<p>修改.env队列配置部分，并且重载配置</p>
<div class="highlight">
<pre><code class="language-text">BROADCAST_DRIVER=log
CACHE_DRIVER=file
QUEUE_CONNECTION=redis
SESSION_DRIVER=file
SESSION_LIFETIME=120

此处贴出test1job代码

&lt;?php

namespace AppJobs;

use AppModelsUser;
use IlluminateBusQueueable;
use IlluminateContractsQueueShouldQueue;
use IlluminateFoundationBusDispatchable;
use IlluminateQueueInteractsWithQueue;
use IlluminateQueueSerializesModels;

class Test1Job implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $user;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct(User $user)
    {
        //
        $this-&gt;user = $user;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        // Process uploaded podcast...
        dd(collect($this-&gt;user)-&gt;toArray());
    }

}
</code></pre>
</div>
<figure data-size="normal"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-1907213c4f6587da54519a3f9b5f0d90_r.jpg" data-caption="" data-size="normal" data-rawwidth="1441" data-rawheight="429" class="origin_image zh-lightbox-thumb" width="1441" data-original="https://pic1.zhimg.com/v2-1907213c4f6587da54519a3f9b5f0d90_b.jpg" title="v2-1907213c4f6587da54519a3f9b5f0d90_r"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-1907213c4f6587da54519a3f9b5f0d90_r.jpg" data-caption="" data-size="normal" data-rawwidth="1441" data-rawheight="429" class="origin_image zh-lightbox-thumb lazy" width="1441" data-original="data:image/svg+xml;utf8,&lt;svg%20xmlns='http://www.w3.org/2000/svg'%20width='1441'%20height='429'&gt;&lt;/svg&gt;" data-actualsrc="https://pic1.zhimg.com/v2-1907213c4f6587da54519a3f9b5f0d90_b.jpg" title="v2-1907213c4f6587da54519a3f9b5f0d90_r"></figure>
<p class="ztext-empty-paragraph"></p>
<p><b>3：然后看看 任务调度</b></p>
<p><b>先准备好数据库;</b></p>
<div class="highlight">
<pre><code class="language-text">php artisan queue:batches-table
php artisan migrate</code></pre>
</div>
<figure data-size="normal"><img decoding="async" src="" data-caption="" data-size="normal" data-rawwidth="418" data-rawheight="291" class="content_image" width="418" data-original="https://pic3.zhimg.com/v2-6c39afc4374209a13df61104bb68530a_b.jpg"><img decoding="async" src="" data-caption="" data-size="normal" data-rawwidth="418" data-rawheight="291" class="content_image lazy" width="418" data-actualsrc="https://pic3.zhimg.com/v2-6c39afc4374209a13df61104bb68530a_b.jpg" data-original="data:image/svg+xml;utf8,&lt;svg%20xmlns='http://www.w3.org/2000/svg'%20width='418'%20height='291'&gt;&lt;/svg&gt;"></figure>
<p>方法部分代码</p>
<div class="highlight">
<pre><code class="language-text">public function index(){
    $batch = Bus::batch([
        new Test1Job(User::find(1)),
        new Test2Job(User::find(2)),
    ])-&gt;then(function (Batch $batch){

    })-&gt;catch(function (Batch $batch,Throwable $e){

    })-&gt;finally(function (Batch $batch){

    })-&gt;dispatch();
    dump($batch-&gt;id);exit;
</code></pre>
</div>
<figure data-size="normal"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-528c24d7b3ce06695379777c74560af5_r.jpg" data-size="normal" data-rawwidth="1395" data-rawheight="343" class="origin_image zh-lightbox-thumb" width="1395" data-original="https://pic2.zhimg.com/v2-528c24d7b3ce06695379777c74560af5_b.jpg" title="v2-528c24d7b3ce06695379777c74560af5_r"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-528c24d7b3ce06695379777c74560af5_r.jpg" data-size="normal" data-rawwidth="1395" data-rawheight="343" class="origin_image zh-lightbox-thumb lazy" width="1395" data-original="data:image/svg+xml;utf8,&lt;svg%20xmlns='http://www.w3.org/2000/svg'%20width='1395'%20height='343'&gt;&lt;/svg&gt;" data-actualsrc="https://pic2.zhimg.com/v2-528c24d7b3ce06695379777c74560af5_b.jpg" title="v2-528c24d7b3ce06695379777c74560af5_r"><figcaption>哦豁完蛋</figcaption></figure>
<p>这里不过也是由于没有引入batchtable trait 导致的</p>
<p class="ztext-empty-paragraph"></p>
<figure data-size="normal"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-d83dd2875aff16344365bd64e906c6cb_r.jpg" data-caption="" data-size="normal" data-rawwidth="1093" data-rawheight="344" class="origin_image zh-lightbox-thumb" width="1093" data-original="https://pic4.zhimg.com/v2-d83dd2875aff16344365bd64e906c6cb_b.jpg" title="v2-d83dd2875aff16344365bd64e906c6cb_r"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-d83dd2875aff16344365bd64e906c6cb_r.jpg" data-caption="" data-size="normal" data-rawwidth="1093" data-rawheight="344" class="origin_image zh-lightbox-thumb lazy" width="1093" data-original="data:image/svg+xml;utf8,&lt;svg%20xmlns='http://www.w3.org/2000/svg'%20width='1093'%20height='344'&gt;&lt;/svg&gt;" data-actualsrc="https://pic4.zhimg.com/v2-d83dd2875aff16344365bd64e906c6cb_b.jpg" title="v2-d83dd2875aff16344365bd64e906c6cb_r"></figure>
<figure data-size="normal"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-711d819d4bfb2f867b52635eade6a3d6_r.jpg" data-caption="" data-size="normal" data-rawwidth="1345" data-rawheight="575" class="origin_image zh-lightbox-thumb" width="1345" data-original="https://pic3.zhimg.com/v2-711d819d4bfb2f867b52635eade6a3d6_b.jpg" title="v2-711d819d4bfb2f867b52635eade6a3d6_r"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-711d819d4bfb2f867b52635eade6a3d6_r.jpg" data-caption="" data-size="normal" data-rawwidth="1345" data-rawheight="575" class="origin_image zh-lightbox-thumb lazy" width="1345" data-original="data:image/svg+xml;utf8,&lt;svg%20xmlns='http://www.w3.org/2000/svg'%20width='1345'%20height='575'&gt;&lt;/svg&gt;" data-actualsrc="https://pic3.zhimg.com/v2-711d819d4bfb2f867b52635eade6a3d6_b.jpg" title="v2-711d819d4bfb2f867b52635eade6a3d6_r"></figure>
<p>设置队列处理失败</p>
<figure data-size="normal"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-a9b615fe17e39aa9c128cac57ac9b51b_r.jpg" data-caption="" data-size="normal" data-rawwidth="988" data-rawheight="340" class="origin_image zh-lightbox-thumb" width="988" data-original="https://pic4.zhimg.com/v2-a9b615fe17e39aa9c128cac57ac9b51b_b.jpg" title="v2-a9b615fe17e39aa9c128cac57ac9b51b_r"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-a9b615fe17e39aa9c128cac57ac9b51b_r.jpg" data-caption="" data-size="normal" data-rawwidth="988" data-rawheight="340" class="origin_image zh-lightbox-thumb lazy" width="988" data-original="data:image/svg+xml;utf8,&lt;svg%20xmlns='http://www.w3.org/2000/svg'%20width='988'%20height='340'&gt;&lt;/svg&gt;" data-actualsrc="https://pic4.zhimg.com/v2-a9b615fe17e39aa9c128cac57ac9b51b_b.jpg" title="v2-a9b615fe17e39aa9c128cac57ac9b51b_r"></figure>
<p class="ztext-empty-paragraph"></p>
<figure data-size="normal"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-9a23a8c823bde070b82860ff8fef738d_r.jpg" data-caption="" data-size="normal" data-rawwidth="944" data-rawheight="387" class="origin_image zh-lightbox-thumb" width="944" data-original="https://pic2.zhimg.com/v2-9a23a8c823bde070b82860ff8fef738d_b.jpg" title="v2-9a23a8c823bde070b82860ff8fef738d_r"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-9a23a8c823bde070b82860ff8fef738d_r.jpg" data-caption="" data-size="normal" data-rawwidth="944" data-rawheight="387" class="origin_image zh-lightbox-thumb lazy" width="944" data-original="data:image/svg+xml;utf8,&lt;svg%20xmlns='http://www.w3.org/2000/svg'%20width='944'%20height='387'&gt;&lt;/svg&gt;" data-actualsrc="https://pic2.zhimg.com/v2-9a23a8c823bde070b82860ff8fef738d_b.jpg" title="v2-9a23a8c823bde070b82860ff8fef738d_r"></figure>
<p class="ztext-empty-paragraph"></p>
<p>其他更多命令可以看看 <a href="https://link.zhihu.com/?target=https%3A//learnku.com/docs/laravel/8.x/queues/9398" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">队列 |《Laravel 8 中文文档 8.x》| Laravel China 社区</a>8.x文动态 </p>
<p class="ztext-empty-paragraph"></p>
<p>4，Blade 组件档 ；对于这个我根本灭有了解过laravel blade</p>
<figure data-size="normal"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-0f08d21eb0b0f514f5e61ff2a5e4625c_r.jpg" data-caption="" data-size="normal" data-rawwidth="1502" data-rawheight="1263" class="origin_image zh-lightbox-thumb" width="1502" data-original="https://pic1.zhimg.com/v2-0f08d21eb0b0f514f5e61ff2a5e4625c_b.jpg" title="v2-0f08d21eb0b0f514f5e61ff2a5e4625c_r"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-0f08d21eb0b0f514f5e61ff2a5e4625c_r.jpg" data-caption="" data-size="normal" data-rawwidth="1502" data-rawheight="1263" class="origin_image zh-lightbox-thumb lazy" width="1502" data-original="data:image/svg+xml;utf8,&lt;svg%20xmlns='http://www.w3.org/2000/svg'%20width='1502'%20height='1263'&gt;&lt;/svg&gt;" data-actualsrc="https://pic1.zhimg.com/v2-0f08d21eb0b0f514f5e61ff2a5e4625c_b.jpg" title="v2-0f08d21eb0b0f514f5e61ff2a5e4625c_r"></figure>
<h3>5,事件监听器优化 （有点像thinkphp的 hook 钩子 可以叫浩克，或者 ’狗子‘，这是我对这类的简称，监听，狗子耳朵最灵敏了 ，不然怎么会有狗仔队一说）</h3>
<p>未完待续。。。断断续续更新 。</p>
</div>
</div>
</article>
<p>The post <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com/software-engineering/laravel/20819/topic-268450513/" data-wpel-link="internal">laravel 8学习笔记</a> appeared first on <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com" data-wpel-link="internal">成長駭客交流第一站 - HyperGrowths™</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Laravel为什么这么受欢迎？</title>
		<link>https://hypergrowths.com/software-engineering/laravel/20772/topic-268327720/</link>
		
		<dc:creator><![CDATA[marketer]]></dc:creator>
		<pubDate>Fri, 30 Apr 2021 08:32:26 +0000</pubDate>
				<category><![CDATA[Laravel]]></category>
		<category><![CDATA[小师傅聊技术框架]]></category>
		<guid isPermaLink="false">https://hypergrowths.com/software-engineering/laravel/20772/topic-268327720/</guid>

					<description><![CDATA[<p>在所有的PHP web框架里面,Laravel公认是最强大的,那么,它到底厉害在哪里,有哪些特别之处,让其他框架,可以俯首称臣? 首先,传统web核心能提供的,laravel是肯定有的,例如这三个: MVC模式架构,把模型,视图和控制器解耦…</p>
<p>The post <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com/software-engineering/laravel/20772/topic-268327720/" data-wpel-link="internal">Laravel为什么这么受欢迎？</a> appeared first on <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com" data-wpel-link="internal">成長駭客交流第一站 - HyperGrowths™</a>.</p>
]]></description>
										<content:encoded><![CDATA[<article class="Post-Main Post-NormalMain">
<header class="Post-Header">
<h1 class="Post-Title">Laravel为什么这么受欢迎？</h1>
<div class="Post-Author">
<div class="AuthorInfo"></div>
</div>
</header>
<div class="Post-RichTextContainer">
<div class="RichText ztext Post-RichText">
<figure data-size="normal"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-8b64444fe91aaf611d14dd16e982b1c0_r.jpg" data-caption="" data-size="normal" data-rawwidth="750" data-rawheight="300" class="origin_image zh-lightbox-thumb" width="750" data-original="https://pic1.zhimg.com/v2-8b64444fe91aaf611d14dd16e982b1c0_b.jpg" title="v2-8b64444fe91aaf611d14dd16e982b1c0_r"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-8b64444fe91aaf611d14dd16e982b1c0_r.jpg" data-caption="" data-size="normal" data-rawwidth="750" data-rawheight="300" class="origin_image zh-lightbox-thumb lazy" width="750" data-original="data:image/svg+xml;utf8,&lt;svg%20xmlns='http://www.w3.org/2000/svg'%20width='750'%20height='300'&gt;&lt;/svg&gt;" data-actualsrc="https://pic1.zhimg.com/v2-8b64444fe91aaf611d14dd16e982b1c0_b.jpg" title="v2-8b64444fe91aaf611d14dd16e982b1c0_r"></figure>
<p>在所有的PHP web框架里面,Laravel公认是最强大的,那么,它到底厉害在哪里,有哪些特别之处,让其他框架,可以俯首称臣?</p>
<p>首先,传统web核心能提供的,laravel是肯定有的,例如这三个:</p>
<ul>
<li>MVC模式架构,把模型,视图和控制器解耦分离;</li>
<li>单文件入口,这保证了reuqest的简洁性;</li>
<li>ORM,也就是对数据库的快捷操作,这部分做得不好,是很消耗开发时间的;</li>
</ul>
<p>laravel是有两个外国人开发的,据说当初两个作者是使用了CakePHP等,觉得很不顺手,想要在这方面改进,于是就有了在2011年第一个版本发布的laravel.</p>
<p>2011年J2EE发展了很多年,Spring已经大行其道了,如果有对Java Web框架有过学习研究,相信这两个作者对IOC注入,完全配置化这些已经被证实很好的设计思想会感兴趣,从而把他们引进来.</p>
<p>确实,正如ThinkPHP参考了Struts的设计思想,Laravel应该也有对Spring的借鉴学习,毕竟在应用框架的定义与实践方面,Java一直是走在前头的,</p>
<p>laravel被流行还由于两位作者在laravel版本升级变迁的过程中,对开发者很好的照顾,让他们能够平衡提升,文档的完善,数据库迁移,以及它的blade模板机制引擎,同时,它还有着在当时已经很先进,在如今看起来很正常的开发思路:TTD, 测试驱动开发. Laravel本身集成了PHPUnit, 让开发人员可以很方便的编写测试用例.</p>
<p>除此之外, Laravel用户验证,分页这些最基本,但其实蛮繁琐的模块功能有很好的定义.用户验证它号称是开箱即用, 用户模型,登录,注册控制器,它实现的非常好,同时还提供对社交网络用户体系的直接集成,开发人员就通过配置,就能让本站引入社交平台的用户认证.</p>
</div>
</div>
</article>
<p>The post <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com/software-engineering/laravel/20772/topic-268327720/" data-wpel-link="internal">Laravel为什么这么受欢迎？</a> appeared first on <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com" data-wpel-link="internal">成長駭客交流第一站 - HyperGrowths™</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Laravel 8 新功能概览</title>
		<link>https://hypergrowths.com/software-engineering/laravel/20779/topic-257153952/</link>
		
		<dc:creator><![CDATA[marketer]]></dc:creator>
		<pubDate>Fri, 30 Apr 2021 08:32:07 +0000</pubDate>
				<category><![CDATA[Laravel]]></category>
		<category><![CDATA[PHP / Laravel / 全栈]]></category>
		<guid isPermaLink="false">https://hypergrowths.com/software-engineering/laravel/20779/topic-257153952/</guid>

					<description><![CDATA[<p>转载自 Laravel 论坛：https://learnku.com/laravel/t/49378 介绍书写这篇文章之时, Laraavel 8 尚未正式的发布出来, 但它刚刚在 Laracon Online上宣布了.这里是新的版本中将会提供的一些新增功能的列表 模型目录…</p>
<p>The post <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com/software-engineering/laravel/20779/topic-257153952/" data-wpel-link="internal">Laravel 8 新功能概览</a> appeared first on <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com" data-wpel-link="internal">成長駭客交流第一站 - HyperGrowths™</a>.</p>
]]></description>
										<content:encoded><![CDATA[<article class="Post-Main Post-NormalMain">
<header class="Post-Header">
<h1 class="Post-Title">Laravel 8 新功能概览</h1>
<div class="Post-Author">
<div class="AuthorInfo"></div>
</div>
</header>
<div class="Post-RichTextContainer">
<div class="RichText ztext Post-RichText">
<blockquote><p> 转载自 Laravel 论坛：<a href="https://link.zhihu.com/?target=https%3A//learnku.com/laravel/t/49378" class=" external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external"><span class="invisible">https://</span><span class="visible">learnku.com/laravel/t/4</span><span class="invisible">9378</span></a></p></blockquote>
<h2>介绍</h2>
<p>书写这篇文章之时, Laraavel 8 尚未正式的发布出来, 但它刚刚在<a href="https://link.zhihu.com/?target=https%3A//laracon.net/" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">Laracon Online</a>上宣布了.</p>
<p>这里是新的版本中将会提供的一些新增功能的列表  </p>
<h2>模型目录</h2>
<p>不久前, <a href="https://link.zhihu.com/?target=https%3A//twitter.com/taylorotwell" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">Taylor Otwell</a> 在Twitter上发起了一项民意调查, 询问社区是否要将所有的模型都放在<code>app/Models</code>文件夹中或者使用默认的<code>app/</code>目录, 大多数人表示他们将模型放在<code>app/Models</code>里.</p>
<p>多亏了这次调查, Laravel 8将默认包含<code>app/Models</code>目录.</p>
<p>如果您使用<code>php artisan make:model SomeModel</code>命令创建新模型, 该命令会将您的模型存放在<code>app/Models</code>目录中.</p>
<p>需要注意的是，如果你不喜欢 <code>app/Models</code> 目录并且删除了它，使用 <code>artisan</code> 命令创建新的模型的时候，会像之前的 Laravel 版本一样直接添加到 <code>app/</code> 目录下。</p>
<h2>路由缓存改善</h2>
<p>路由缓存工作的方式是将所有路由都放入到一个大型的 PHP 数组中，这样效率更高。</p>
<p>在之前，如果在路由文件中使用了 closure ，路由缓存不会启用，但是在 Laravel 8 中，路由缓存可以正常使用！</p>
<p>这样，就可以随时缓存路由！</p>
<h2>维护模式改进</h2>
<p><code>php artisan down</code>命令有了一些相当不错的改进。</p>
<p>对于以前的版本，为了只允许某些人访问该网站，必须使用白名单功能，如本文中此处所述：</p>
<p>而在 Laravel 8，有一个比IP白名单更方便使用的方法，你可以自定义一个 secret 。要配置它，你需要做的就是:</p>
<div class="highlight">
<pre><code class="language-text">php artisan down --secret=YOUR_SECRET_HERE</code></pre>
</div>
<p>确保使用安全字符串替换 <code>YOUR_SECRET_HERE</code> 部分！</p>
<p>之后要访问处于维护模式的站点，请访问 <code>yourdomain.com/YOUR_SECRET_HERE</code>，这会生成一个带有 secret 的 cookie 可让您像往常一样浏览网站！</p>
<p>这是一个让你的网站处于维护模式的好方法，但是仍然允许一些人可以访问它！</p>
<p><code>php artisan down</code> 命令的另一个很好的新增就是，你可以可以预渲染维护页面，这样，即使您运行 <code>composer update</code>，您的最终用户仍会看到您的维护页面，而不是一些错误。</p>
<p>为此，只需运行:</p>
<div class="highlight">
<pre><code class="language-text">php artisan down --render="errors::503"</code></pre>
</div>
<p>这样你可以更大刀阔斧的进行维护，用户只会看到更友好的维护页面而不是一堆报错页面！</p>
<p>更炫酷的就是，你还可以将标志组合在一起。例如，你运行以下命令，在给渲染的页面添加 secret 的同时还可以更改状态码:</p>
<div class="highlight">
<pre><code class="language-text">php artisan down --render="errors::503" --status=200 --secret=YOUR_SECRET_HERE</code></pre>
</div>
<h2>频率限制改进</h2>
<p>在 Laravel 8 中有一种新的方式订阅频率限制。他具有更大的灵活性，同时与之前发布的限流中间件 API 保持兼容.</p>
<p>他的工作原理首先是定义频率限制器：</p>
<div class="highlight">
<pre><code class="language-text">use IlluminateCacheRateLimitingLimit;
use IlluminateSupportFacadesRateLimiter;

RateLimiter::for('login', function (Request $request) {
    return Limit::perMinute(100);
});</code></pre>
</div>
<p>然后，你可以将 <code>RateLimitter</code> 当作一个标准中间件：</p>
<div class="highlight">
<pre><code class="language-text">Route::middleware(['throttle:login'])-&gt;group(function () {
    Route::post('/login', function () {
        //
    });
});</code></pre>
</div>
<p>这对于 APIs 也同样方便，例如你可以在其中限制用户每分钟可以发送的请求数量。</p>
<h2>模式转储</h2>
<p>模式转储大概是我最喜欢的特性之一，我可以借助 <a href="https://link.zhihu.com/?target=https%3A//voyager.devdojo.com/" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">Laravel Voyager</a> 轻松上手使用他。</p>
<p>你需要使用的 artisan 命令是:</p>
<div class="highlight">
<pre><code class="language-text">php artisan schema:dump</code></pre>
</div>
<p>以上命令将在 <code>database/schema</code> 文件夹中生成一个架构文件，该文件基本上是整个数据库的结构。</p>
<p>你还可以转储当前数据库模式，然后通过添加 <code>--prune</code> 标志来缩减所有现有的迁移：flag:</p>
<div class="highlight">
<pre><code class="language-text">php artisan schema:dump --prune</code></pre>
</div>
<p>以上内容将删除你所有的旧迁移，并生成一个架构转储文件。如果你有很多迁移文件，这是清除迁移文件的绝佳方法！</p>
<p>之后，你可以再次开始添加新的迁移，它将照常工作。一旦达到一定数量并想要清除迁移文件夹，就可以再次运行 <code>schema：dump</code> 命令并对其进行更新。</p>
<h2>Laravel Jetstream</h2>
<p>Laravel Jetstream 是 Laravel 的新应用程序支架。它是免费和开源的。</p>
<p>Jetstream 为您的新项目提供了更好的起点。它包括以下组件：</p>
<ul>
<li>注册登录功能</li>
<li>Email 验证</li>
<li>双因素验证</li>
<li>会话管理</li>
<li>通过 Laravel Sanctum 提供 API 支持</li>
</ul>
<p>Laravel Jetstream 取代了可用于先前 Laravel 版本的旧版 Laravel 身份验证 UI 。</p>
<p>Jetstream 使用 Tailwind CSS，你选择 Livewire 或 Inertia 。</p>
<h2>任务批处理</h2>
<p>我认为，最显着的改进之一是 Laravel 的 任务分批功能。</p>
<p>现在，它允许你运行一批任务 ，此后，一旦一批任务完成执行，就执行一些操作。例如:</p>
<div class="highlight">
<pre><code class="language-text">use AppJobsProcessPodcast;
use AppPodcast;
use IlluminateBusBatch;
use IlluminateSupportFacadesBatch;
use Throwable;

$batch = Bus::batch([
    new ProcessPodcast(Podcast::find(1)),
    new ProcessPodcast(Podcast::find(2)),
])-&gt;then(function (Batch $batch) {
    // 所有任务成功完成...
})-&gt;catch(function (Batch $batch, Throwable $e) {
    // 第一批任务失败...
})-&gt;finally(function (Batch $batch) {
    // 批处理执行完毕...
})-&gt;dispatch();

return $batch-&gt;id;</code></pre>
</div>
<p>任务批处理的更多相关訊息，你可以阅读官方的 <a href="https://link.zhihu.com/?target=https%3A//learnku.com/docs/laravel/8.x/queues%23job-batching." class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">[队列文档]</a> 。</p>
<h2>结论</h2>
<p>还有其他一些改进，例如默认分页现在使用 TailwindCSS ，改进了 <code>php artisan serve</code> 命令，新的模型工厂类等等。</p>
<p>看到 Laravel 付出了很多努力，这真是太棒了。</p>
<p>有关更多訊息，请确保在此处查看官方发行说明：</p>
<p><a href="https://link.zhihu.com/?target=https%3A//learnku.com/docs/laravel/8.x/releases/9351" class=" external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external"><span class="invisible">https://</span><span class="visible">learnku.com/docs/larave</span><span class="invisible">l/8.x/releases/9351</span></a></p>
<p>另外，请确保安装 Laravel 8 并使用新功能！</p>
<blockquote><p> 讨论请前往专业的 Laravel 论坛：<a href="https://link.zhihu.com/?target=https%3A//learnku.com/laravel/t/49378" class=" external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external"><span class="invisible">https://</span><span class="visible">learnku.com/laravel/t/4</span><span class="invisible">9378</span></a></p></blockquote>
</div>
</div>
</article>
<p>The post <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com/software-engineering/laravel/20779/topic-257153952/" data-wpel-link="internal">Laravel 8 新功能概览</a> appeared first on <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com" data-wpel-link="internal">成長駭客交流第一站 - HyperGrowths™</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>开源导航网站-WebStack-Laravel</title>
		<link>https://hypergrowths.com/software-engineering/laravel/20296/topic-222985783/</link>
		
		<dc:creator><![CDATA[marketer]]></dc:creator>
		<pubDate>Fri, 30 Apr 2021 08:15:49 +0000</pubDate>
				<category><![CDATA[Laravel]]></category>
		<guid isPermaLink="false">https://hypergrowths.com/software-engineering/laravel/20296/topic-222985783/</guid>

					<description><![CDATA[<p>前言：因为工作，需要使用的网站比较多，所以一直想为公司搭建一款私有的导航网站。本来想自己写，可是不会前端呀。只好去github上看看有没有大神分享的开源导航网站。 虽然不太好找但还是找到了。项目地址： http…</p>
<p>The post <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com/software-engineering/laravel/20296/topic-222985783/" data-wpel-link="internal">开源导航网站-WebStack-Laravel</a> appeared first on <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com" data-wpel-link="internal">成長駭客交流第一站 - HyperGrowths™</a>.</p>
]]></description>
										<content:encoded><![CDATA[<article class="Post-Main Post-NormalMain">
<header class="Post-Header">
<h1 class="Post-Title">开源导航网站-WebStack-Laravel</h1>
<div class="Post-Author">
<div class="AuthorInfo"></div>
</div>
</header>
<div class="Post-RichTextContainer">
<div class="RichText ztext Post-RichText">
<p>前言：因为工作，需要使用的网站比较多，所以一直想为公司搭建一款私有的导航网站。本来想自己写，可是不会前端呀。只好去github上看看有没有大神分享的开源导航网站。</p>
<p>虽然不太好找但还是找到了。项目地址：</p>
<figure data-size="normal"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-49929b263283cab1c49b6039052dc28b_r.jpg" data-caption="" data-size="normal" data-rawwidth="1600" data-rawheight="900" class="origin_image zh-lightbox-thumb" width="1600" data-original="https://pic4.zhimg.com/v2-49929b263283cab1c49b6039052dc28b_b.jpg" title="v2-49929b263283cab1c49b6039052dc28b_r"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-49929b263283cab1c49b6039052dc28b_r.jpg" data-caption="" data-size="normal" data-rawwidth="1600" data-rawheight="900" class="origin_image zh-lightbox-thumb lazy" width="1600" data-original="data:image/svg+xml;utf8,&lt;svg%20xmlns='http://www.w3.org/2000/svg'%20width='1600'%20height='900'&gt;&lt;/svg&gt;" data-actualsrc="https://pic4.zhimg.com/v2-49929b263283cab1c49b6039052dc28b_b.jpg" title="v2-49929b263283cab1c49b6039052dc28b_r"></figure>
<p>前端设计：<b><a href="https://link.zhihu.com/?target=https%3A//github.com/WebStackPage/WebStackPage.github.io" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">WebStackPage</a></b></p>
<p>后台框架：<b><a href="https://link.zhihu.com/?target=https%3A//github.com/z-song/laravel-admin" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">laravel-admin</a></b></p>
<p><b>首先这个导航网站给我自己个感觉就是干净。</b></p>
<p><b>后台可以随便添加分类。</b></p>
<figure data-size="normal"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-63441c279d76cd31af09910f9e99dd1f_r.jpg" data-caption="" data-size="normal" data-rawwidth="1600" data-rawheight="900" class="origin_image zh-lightbox-thumb" width="1600" data-original="https://pic4.zhimg.com/v2-63441c279d76cd31af09910f9e99dd1f_b.jpg" title="v2-63441c279d76cd31af09910f9e99dd1f_r"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-63441c279d76cd31af09910f9e99dd1f_r.jpg" data-caption="" data-size="normal" data-rawwidth="1600" data-rawheight="900" class="origin_image zh-lightbox-thumb lazy" width="1600" data-original="data:image/svg+xml;utf8,&lt;svg%20xmlns='http://www.w3.org/2000/svg'%20width='1600'%20height='900'&gt;&lt;/svg&gt;" data-actualsrc="https://pic4.zhimg.com/v2-63441c279d76cd31af09910f9e99dd1f_b.jpg" title="v2-63441c279d76cd31af09910f9e99dd1f_r"></figure>
<figure data-size="normal"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-f3ee32f2e3ba7ea18710c95687829755_r.jpg" data-caption="" data-size="normal" data-rawwidth="1600" data-rawheight="900" class="origin_image zh-lightbox-thumb" width="1600" data-original="https://pic2.zhimg.com/v2-f3ee32f2e3ba7ea18710c95687829755_b.jpg" title="v2-f3ee32f2e3ba7ea18710c95687829755_r"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-f3ee32f2e3ba7ea18710c95687829755_r.jpg" data-caption="" data-size="normal" data-rawwidth="1600" data-rawheight="900" class="origin_image zh-lightbox-thumb lazy" width="1600" data-original="data:image/svg+xml;utf8,&lt;svg%20xmlns='http://www.w3.org/2000/svg'%20width='1600'%20height='900'&gt;&lt;/svg&gt;" data-actualsrc="https://pic2.zhimg.com/v2-f3ee32f2e3ba7ea18710c95687829755_b.jpg" title="v2-f3ee32f2e3ba7ea18710c95687829755_r"></figure>
<p>安装部署：线上方式</p>
<p>1.安装<b><a href="https://link.zhihu.com/?target=https%3A//github.com/z-song/laravel-admin" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">laravel</a>环境</b></p>
<p><b>通过一键脚本安装：一键脚本来自：</b><a href="https://link.zhihu.com/?target=https%3A//github.com/summerblue/laravel-ubuntu-init" class=" external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external"><span class="invisible">https://</span><span class="visible">github.com/summerblue/l</span><span class="invisible">aravel-ubuntu-init</span></a></p>
<div class="highlight">
<pre><code class="language-text">wget -qO- https://raw.githubusercontent.com/summerblue/laravel-ubuntu-init/master/download.sh - | bash</code></pre>
</div>
<p>2.克隆代码：</p>
<div class="highlight">
<pre><code class="language-text">git clone https://github.com/hui-ho/WebStack-Laravel.git</code></pre>
</div>
<p>3.安装依赖：</p>
<div class="highlight">
<pre><code class="language-text">$ composer install</code></pre>
</div>
<p>4.编辑配置：</p>
<div class="highlight">
<pre><code class="language-text">$ cp .env.example .env
vim .env
...
DB_DATABASE=database
DB_USERNAME=username
DB_PASSWORD=password
...
这里需要填写数据库的一些訊息。
</code></pre>
</div>
<p class="ztext-empty-paragraph"></p>
<div class="highlight">
<pre><code class="language-bash">如果使用的是一键脚本安装的环境可以使用命令：
 新增 Mysql 用户、数据库 
./16.04/mysql_add_user.sh 
会提示输入 root 密码，如果错误将无法继续。输入需要创建的 Mysql 用户名，以及确认是否需要创建对应用户名的数据库。  创建完毕之后会将新用户的密码输出到屏幕上，请妥善保存。</code></pre>
</div>
<p>5.生成 KEY：</p>
<div class="highlight">
<pre><code class="language-text">$ php artisan key:generate</code></pre>
</div>
<p>迁移数据：</p>
<div class="highlight">
<pre><code class="language-text">php artisan migrate:refresh --seed</code></pre>
</div>
<p>6.本地测试：</p>
<div class="highlight">
<pre><code class="language-text">$ php artisan serve</code></pre>
</div>
<p>安装完成：<a href="https://link.zhihu.com/?target=http%3A//127.0.0.1%3A8000/" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">http://127.0.0.1:8000</a></p>
<blockquote><p>有些朋友对部署表示有压力，但这和一般的 Laravel 应用是没有区别的，线上环境可以参考：<a href="https://link.zhihu.com/?target=https%3A//github.com/summerblue/laravel-ubuntu-init" class=" external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external"><span class="invisible">https://</span><span class="visible">github.com/summerblue/l</span><span class="invisible">aravel-ubuntu-init</span></a></p></blockquote>
<h2>docker-compose方式</h2>
<h2>1.创建docker-compose目录：</h2>
<p>2.编辑文件 vim docker-compose.yml</p>
<p><b>先创建持久化目录：</b></p>
<div class="highlight">
<pre><code class="language-text">mkdir -p /data/service/webstacknet/images</code></pre>
</div>
<p class="ztext-empty-paragraph"></p>
<div class="highlight">
<pre><code class="language-text">version: '3'

services:
  db:
    image: mysql/mysql-server:5.6
    restart: always
    container_name: "mysql_wsl"
    environment:
      MYSQL_ROOT_PASSWORD: Tym8zrnNRpz4
      MYSQL_DATABASE: webstack
      MYSQL_USER: webstack
      MYSQL_PASSWORD: Xym8zrnNRpz
    command: --default-authentication-plugin=mysql_native_password
    networks:
      - "webstacknet"
  redis:
    image: redis:3
    container_name: "redis_wsl"
    restart: always
    networks:
      - "webstacknet"
  webstack:
    image: dmqk/webstack-laravel:v1.2.3
    volumes:
      - /data/service/webstacknet/images:/opt/navi/public/uploads/images
    container_name: "wsl"
    restart: always
    ports:
      - 9000:8000
    depends_on:
      - "redis"
    environment:
      LOGIN_COPTCHA: "false"
      DB_HOST: db
      DB_PORT: 3306
      DB_DATABASE: webstack
      DB_USERNAME: webstack
      DB_PASSWORD: Xym8zrnNRpz
    command: ['/entrypoint.sh','serve']
    networks:
      - "webstacknet"
networks:
  webstacknet:
    driver: bridge</code></pre>
</div>
<p>3.启动容器：</p>
<div class="highlight">
<pre><code class="language-text">docker-compose up -d</code></pre>
</div>
<h2>使用</h2>
<p>后台地址：<a href="https://link.zhihu.com/?target=http%3A//domain/admin" class=" external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external"><span class="invisible">http://</span><span class="visible">domain/admin</span></a></p>
<p>默认用户：admin</p>
<p>默认密码：admin</p>
</div>
</div>
</article>
<p>The post <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com/software-engineering/laravel/20296/topic-222985783/" data-wpel-link="internal">开源导航网站-WebStack-Laravel</a> appeared first on <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com" data-wpel-link="internal">成長駭客交流第一站 - HyperGrowths™</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
