<?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>PHP / Laravel / 全栈 Archives - 成長駭客交流第一站 - HyperGrowths™</title>
	<atom:link href="https://hypergrowths.com/tag/php-laravel-%E5%85%A8%E6%A0%88/feed/" rel="self" type="application/rss+xml" />
	<link>https://hypergrowths.com/tag/php-laravel-全栈/</link>
	<description>用SEO內容行銷加速增長? 企業發展遇到增長瓶頸？加入 HyperGrowths，學習突破性增長策略，優化行銷方案，助力企業飛躍式發展</description>
	<lastBuildDate>Fri, 30 Apr 2021 08:32:07 +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>PHP / Laravel / 全栈 Archives - 成長駭客交流第一站 - HyperGrowths™</title>
	<link>https://hypergrowths.com/tag/php-laravel-全栈/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<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>快速上手 Laravel 的 100 个小技巧</title>
		<link>https://hypergrowths.com/software-engineering/laravel/20053/topic-149228467/</link>
		
		<dc:creator><![CDATA[marketer]]></dc:creator>
		<pubDate>Fri, 30 Apr 2021 07:57:39 +0000</pubDate>
				<category><![CDATA[Laravel]]></category>
		<category><![CDATA[PHP / Laravel / 全栈]]></category>
		<guid isPermaLink="false">https://hypergrowths.com/software-engineering/laravel/20053/topic-149228467/</guid>

					<description><![CDATA[<p>转载自 Laravel 论坛：https://learnku.com/laravel/t/45370 Laravel 小技巧给大家提供一些 Laravel 使用的小技巧， 当然你有任何想法欢迎 PR ! Github 地址 摘要控制器模型模型关联数据迁移视图路由验证Policies…</p>
<p>The post <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com/software-engineering/laravel/20053/topic-149228467/" data-wpel-link="internal">快速上手 Laravel 的 100 个小技巧</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 的 100 个小技巧</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/45370" 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">5370</span></a></p></blockquote>
<h2>Laravel 小技巧</h2>
<p>给大家提供一些 Laravel 使用的小技巧， 当然你有任何想法欢迎 PR !  </p>
<blockquote><p><a href="https://link.zhihu.com/?target=https%3A//github.com/LaravelDaily/laravel-tips" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">Github 地址</a></p></blockquote>
<h2>摘要</h2>
<ul>
<li><a href="https://zhuanlan.zhihu.com/p/149228467/edit#%E6%8E%A7%E5%88%B6%E5%99%A8" class="internal" data-wpel-link="external" rel="nofollow external noopener noreferrer">控制器</a></li>
<li><a href="https://zhuanlan.zhihu.com/p/149228467/edit#%E6%A8%A1%E5%9E%8B" class="internal" data-wpel-link="external" rel="nofollow external noopener noreferrer">模型</a></li>
<li><a href="https://zhuanlan.zhihu.com/p/149228467/edit#%E6%A8%A1%E5%9E%8B%E5%85%B3%E8%81%94" class="internal" data-wpel-link="external" rel="nofollow external noopener noreferrer">模型关联</a></li>
<li><a href="https://zhuanlan.zhihu.com/p/149228467/edit#%E6%95%B0%E6%8D%AE%E8%BF%81%E7%A7%BB" class="internal" data-wpel-link="external" rel="nofollow external noopener noreferrer">数据迁移</a></li>
<li><a href="https://zhuanlan.zhihu.com/p/149228467/edit#%E8%A7%86%E5%9B%BE" class="internal" data-wpel-link="external" rel="nofollow external noopener noreferrer">视图</a></li>
<li><a href="https://zhuanlan.zhihu.com/p/149228467/edit#%E8%B7%AF%E7%94%B1" class="internal" data-wpel-link="external" rel="nofollow external noopener noreferrer">路由</a></li>
<li><a href="https://zhuanlan.zhihu.com/p/149228467/edit#%E9%AA%8C%E8%AF%81" class="internal" data-wpel-link="external" rel="nofollow external noopener noreferrer">验证</a></li>
<li><a href="https://zhuanlan.zhihu.com/p/149228467/edit#Policies" class="internal" data-wpel-link="external" rel="nofollow external noopener noreferrer">Policies</a></li>
<li><a href="https://zhuanlan.zhihu.com/p/149228467/edit#%E9%9B%86%E5%90%88" class="internal" data-wpel-link="external" rel="nofollow external noopener noreferrer">集合</a></li>
<li><a href="https://zhuanlan.zhihu.com/p/149228467/edit#%E9%89%B4%E6%9D%83" class="internal" data-wpel-link="external" rel="nofollow external noopener noreferrer">鉴权</a></li>
<li><a href="https://zhuanlan.zhihu.com/p/149228467/edit#%E9%82%AE%E4%BB%B6" class="internal" data-wpel-link="external" rel="nofollow external noopener noreferrer">邮件</a></li>
<li><a href="https://zhuanlan.zhihu.com/p/149228467/edit#Artisan" class="internal" data-wpel-link="external" rel="nofollow external noopener noreferrer">Artisan</a></li>
<li><a href="https://zhuanlan.zhihu.com/p/149228467/edit#%E6%95%B0%E6%8D%AE%E5%B7%A5%E5%8E%82" class="internal" data-wpel-link="external" rel="nofollow external noopener noreferrer">数据工厂</a></li>
<li><a href="https://zhuanlan.zhihu.com/p/149228467/edit#%E6%97%A5%E5%BF%97%E5%92%8C%E8%B0%83%E8%AF%95" class="internal" data-wpel-link="external" rel="nofollow external noopener noreferrer">日志和调试</a></li>
</ul>
<h2>控制器</h2>
<h3>单行为控制器</h3>
<p>当你的控制器仅有一个方法的时候，不妨尝试下 <code>__invoke()</code> 方法来，让当前控制器变身为 "invokable" 控制器。</p>
<p>想要了解单行为控制器的好处以及用法请参考： - <a href="https://link.zhihu.com/?target=https%3A//learnku.com/laravel/t/43185" 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">3185</span></a> - <a href="https://link.zhihu.com/?target=https%3A//learnku.com/laravel/t/44638" 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">4638</span></a></p>
<p>单行为控制器的简单使用：</p>
<p>定义路由，如下：</p>
<div class="highlight">
<pre><code class="language-php"><span class="nx">Route</span><span class="o">::</span><span class="na">get</span><span class="p">(</span><span class="s1">'user/{id}'</span><span class="p">,</span><span class="s1">'ShowProfile'</span><span class="p">);</span></code></pre>
</div>
<p>通过命令创建单行为控制器：</p>
<div class="highlight">
<pre><code class="language-bash">php artisan make:controller ShowProfile --invokable</code></pre>
</div>
<p>修改控制器代码，如下： </p>
<div class="highlight">
<pre><code class="language-php"><span class="k">class</span><span class="nc">ShowProfile</span><span class="k">extends</span><span class="nx">Controller</span><span class="p">{</span><span class="k">public</span><span class="k">function</span><span class="fm">__invoke</span><span class="p">(</span><span class="nv">$id</span><span class="p">)</span><span class="p">{</span><span class="k">return</span><span class="nx">view</span><span class="p">(</span><span class="s1">'user.profile'</span><span class="p">,</span><span class="p">[</span><span class="s1">'user'</span><span class="o">=&gt;</span><span class="nx">User</span><span class="o">::</span><span class="na">findOrFail</span><span class="p">(</span><span class="nv">$id</span><span class="p">)</span><span class="p">]);</span><span class="p">}</span><span class="p">}</span></code></pre>
</div>
<h3>重定向到指定控制器的指定方法</h3>
<p>你可以通过 <code>redirect()</code> 重定向到某个路由或者某个链接，但是当你希望重定向到一个特定方法，并且需要携带一些参数的时候，action 方法可以帮你实现，代码如下：</p>
<div class="highlight">
<pre><code class="language-php"><span class="k">return</span><span class="nx">redirect</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">action</span><span class="p">(</span><span class="s1">'SomeController@method'</span><span class="p">,</span><span class="p">[</span><span class="s1">'param'</span><span class="o">=&gt;</span><span class="nv">$value</span><span class="p">]);</span></code></pre>
</div>
<h3>接口操作成功而无返回的简单处理</h3>
<p>当你在接口执行了某些逻辑，但是不需要返回内容得时候，你可以直接返回 204 状态码。 在 Laravel 中这很容易实现：</p>
<blockquote><p> Tips: <a href="https://link.zhihu.com/?target=https%3A//developer.mozilla.org/zh-CN/docs/Web/HTTP/Status/204" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">204 状态码说明</a></p></blockquote>
<div class="highlight">
<pre><code class="language-php"><span class="k">public</span><span class="k">function</span><span class="nf">reorder</span><span class="p">(</span><span class="nx">Request</span><span class="nv">$request</span><span class="p">)</span><span class="p">{</span><span class="k">foreach</span><span class="p">(</span><span class="nv">$request</span><span class="o">-&gt;</span><span class="na">input</span><span class="p">(</span><span class="s1">'rows'</span><span class="p">,</span><span class="p">[])</span><span class="k">as</span><span class="nv">$row</span><span class="p">)</span><span class="p">{</span><span class="nx">Country</span><span class="o">::</span><span class="na">find</span><span class="p">(</span><span class="nv">$row</span><span class="p">[</span><span class="s1">'id'</span><span class="p">])</span><span class="o">-&gt;</span><span class="na">update</span><span class="p">([</span><span class="s1">'position'</span><span class="o">=&gt;</span><span class="nv">$row</span><span class="p">[</span><span class="s1">'position'</span><span class="p">]]);</span><span class="p">}</span><span class="k">return</span><span class="nx">response</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">noContent</span><span class="p">();</span><span class="p">}</span></code></pre>
</div>
<h2>模型</h2>
<h3>Eloquent 的日期筛选</h3>
<p>Laravel 的 Eloquent Orm 提供了 <code>whereDay()</code>, <code>whereMonth()</code>, <code>whereYear()</code>, <code>whereDate()</code> 和 <code>whereTime()</code> 供你对日期进行筛选。简单例子：</p>
<div class="highlight">
<pre><code class="language-php"><span class="nv">$products</span><span class="o">=</span><span class="nx">Product</span><span class="o">::</span><span class="na">whereDate</span><span class="p">(</span><span class="s1">'created_at'</span><span class="p">,</span><span class="s1">'2018-01-31'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">();</span><span class="nv">$products</span><span class="o">=</span><span class="nx">Product</span><span class="o">::</span><span class="na">whereMonth</span><span class="p">(</span><span class="s1">'created_at'</span><span class="p">,</span><span class="s1">'12'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">();</span><span class="nv">$products</span><span class="o">=</span><span class="nx">Product</span><span class="o">::</span><span class="na">whereDay</span><span class="p">(</span><span class="s1">'created_at'</span><span class="p">,</span><span class="s1">'31'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">();</span><span class="nv">$products</span><span class="o">=</span><span class="nx">Product</span><span class="o">::</span><span class="na">whereYear</span><span class="p">(</span><span class="s1">'created_at'</span><span class="p">,</span><span class="nx">date</span><span class="p">(</span><span class="s1">'Y'</span><span class="p">))</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">();</span><span class="nv">$products</span><span class="o">=</span><span class="nx">Product</span><span class="o">::</span><span class="na">whereTime</span><span class="p">(</span><span class="s1">'created_at'</span><span class="p">,</span><span class="s1">'='</span><span class="p">,</span><span class="s1">'14:13:58'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">();</span></code></pre>
</div>
<h3>Inter 类型数据的便捷操作 Increments（增加） 和 decrements（减少）</h3>
<p>你如果仅仅是操作数字类型字段的增加（减少），你可以尝试下  <code>increment()</code>（<code>decrements</code>） 方法：</p>
<div class="highlight">
<pre><code class="language-php"><span class="nx">Post</span><span class="o">::</span><span class="na">find</span><span class="p">(</span><span class="nv">$post_id</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">increment</span><span class="p">(</span><span class="s1">'view_count'</span><span class="p">);</span><span class="nx">User</span><span class="o">::</span><span class="na">find</span><span class="p">(</span><span class="nv">$user_id</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">increment</span><span class="p">(</span><span class="s1">'points'</span><span class="p">,</span><span class="mi">50</span><span class="p">);</span></code></pre>
</div>
<h3>获取设置当前用户登录的訊息</h3>
<p>你可以使用 <code>make:observer</code> 来创建一个观察者，然后通修改模型事件 <code>creating()</code> 来设定当前用户的訊息，代码如下 ： <a href="https://link.zhihu.com/?target=https%3A//learnku.com/articles/6657/model-events-and-observer-in-laravel" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">详细使用可以查阅 Laravel 中的模型事件与 Observer</a></p>
<div class="highlight">
<pre><code class="language-php"><span class="k">class</span><span class="nc">PostObserver</span><span class="p">{</span><span class="k">public</span><span class="k">function</span><span class="nf">creating</span><span class="p">(</span><span class="nx">Post</span><span class="nv">$post</span><span class="p">)</span><span class="p">{</span><span class="nv">$post</span><span class="o">-&gt;</span><span class="na">user_id</span><span class="o">=</span><span class="nx">auth</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">id</span><span class="p">();</span><span class="p">}</span><span class="p">}</span></code></pre>
</div>
<h3>软删除后的数据批量恢复</h3>
<p>当使用软删除删除数据之后，你可以通过以下方法批量恢复删除的数据：</p>
<div class="highlight">
<pre><code class="language-php"><span class="nx">Post</span><span class="o">::</span><span class="na">withTrashed</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">where</span><span class="p">(</span><span class="s1">'author_id'</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">restore</span><span class="p">();</span></code></pre>
</div>
<h3>特定模型字段的返回</h3>
<p>默认的 <code>Model::all()</code> 会返回所有字段，不管你是否有需要，当然你也可以通过给 <code>all()</code> 传递参数来指定返回的列。如下：</p>
<div class="highlight">
<pre><code class="language-php"><span class="nv">$users</span><span class="o">=</span><span class="nx">User</span><span class="o">::</span><span class="na">all</span><span class="p">([</span><span class="s1">'id'</span><span class="p">,</span><span class="s1">'name'</span><span class="p">,</span><span class="s1">'email'</span><span class="p">]);</span></code></pre>
</div>
<h3>失败或者成功的查询</h3>
<p><code>findOrFail()</code> 方法，可以在查询没有符合条件数据的时候直接抛出异常。</p>
<div class="highlight">
<pre><code class="language-php"><span class="nv">$user</span><span class="o">=</span><span class="nx">User</span><span class="o">::</span><span class="na">where</span><span class="p">(</span><span class="s1">'email'</span><span class="p">,</span><span class="s1">'povilas@laraveldaily.com'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">firstOrFail</span><span class="p">();</span></code></pre>
</div>
<h3>数据返回的列名称的自定义</h3>
<p>在 Eloquent 查询中使用 select 可以设置查询的字段，然后你可以通过 "as" 给字段重命名为你想要的名称：</p>
<div class="highlight">
<pre><code class="language-php"><span class="nv">$users</span><span class="o">=</span><span class="nx">DB</span><span class="o">::</span><span class="na">table</span><span class="p">(</span><span class="s1">'users'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">select</span><span class="p">(</span><span class="s1">'name'</span><span class="p">,</span><span class="s1">'email as user_email'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">();</span></code></pre>
</div>
<h3>查询结果的 Map 处理</h3>
<p>由于 Eloquent 中，get 方法将返回 Collection 类型的数据，所以在通过 get 方法获取数据之后，你可以直接通过 <code>map()</code> 方法来处理：</p>
<div class="highlight">
<pre><code class="language-php"><span class="nv">$users</span><span class="o">=</span><span class="nx">User</span><span class="o">::</span><span class="na">where</span><span class="p">(</span><span class="s1">'role_id'</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">map</span><span class="p">(</span><span class="k">function</span><span class="p">(</span><span class="nx">User</span><span class="nv">$user</span><span class="p">)</span><span class="p">{</span><span class="nv">$user</span><span class="o">-&gt;</span><span class="na">some_column</span><span class="o">=</span><span class="nx">some_function</span><span class="p">(</span><span class="nv">$user</span><span class="p">);</span><span class="k">return</span><span class="nv">$user</span><span class="p">;</span><span class="p">});</span></code></pre>
</div>
<h3>不使用 timestamps 相关字段</h3>
<p>默认的，laravel 会在 migration 以及 model 中添加 timestamps 相关字段（created_at，updated_at），如果你不想使用他，你可以在migrate 中移除相关字段，或者在 model 中设置 <code>timestamps</code>属性，将该属性设置为 <code>false</code> 即可实现：</p>
<div class="highlight">
<pre><code class="language-php"><span class="k">class</span><span class="nc">Company</span><span class="k">extends</span><span class="nx">Model</span><span class="p">{</span><span class="k">public</span><span class="nv">$timestamps</span><span class="o">=</span><span class="k">false</span><span class="p">;</span><span class="p">}</span></code></pre>
</div>
<h3>修改默认时间字段</h3>
<p>当你想要在已存在的数据库中使用 Laraevl 的 Eloquent Orm的时候，你的时间字段又不同于 Laravel 默认字段，这时候怎么处理呢？你可以通过给以下常量重新赋值来设置当前使用的时间戳字段：</p>
<div class="highlight">
<pre><code class="language-php"><span class="k">class</span><span class="nc">Role</span><span class="k">extends</span><span class="nx">Model</span><span class="p">{</span><span class="k">const</span><span class="no">CREATED_AT</span><span class="o">=</span><span class="s1">'create_time'</span><span class="p">;</span><span class="k">const</span><span class="no">UPDATED_AT</span><span class="o">=</span><span class="s1">'update_time'</span><span class="p">;</span><span class="p">}</span></code></pre>
</div>
<h3>快速通过 created_at 排序</h3>
<p>在此之前捏坑你是这样实现的：</p>
<div class="highlight">
<pre><code class="language-php"><span class="nx">User</span><span class="o">::</span><span class="na">orderBy</span><span class="p">(</span><span class="s1">'created_at'</span><span class="p">,</span><span class="s1">'desc'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">();</span></code></pre>
</div>
<p>当然，你也可以使用更简单的方式:</p>
<div class="highlight">
<pre><code class="language-php"><span class="nx">User</span><span class="o">::</span><span class="na">latest</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">();</span></code></pre>
</div>
<p>默认 <code>latest()</code> 会通过 <code>created_at</code> 进行排序。</p>
<p>这里还有个反方法可以用： <code>oldest()</code>  将会通过 <code>created_at</code> 字段进行升序排序。</p>
<div class="highlight">
<pre><code class="language-php"><span class="nx">User</span><span class="o">::</span><span class="na">oldest</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">();</span></code></pre>
</div>
<p>当然你也可以通过传递参数来执行想要进行排序的字段，如下：</p>
<div class="highlight">
<pre><code class="language-php"><span class="nv">$lastUpdatedUser</span><span class="o">=</span><span class="nx">User</span><span class="o">::</span><span class="na">newest</span><span class="p">(</span><span class="s1">'updated_at'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">first</span><span class="p">();</span></code></pre>
</div>
<h3>创建记录时的自增</h3>
<p>当你在创建记录的时候，你同时希望对某个字段进行自增操作的时候，你可以在  <code>boot()</code>  方法中注册 creating 方法来实现。举个例子，现在你有个 "position" 字段，你希望在你完成新增操作的时候同时对该字段 +1 ，实现代码如下：</p>
<div class="highlight">
<pre><code class="language-php"><span class="k">class</span><span class="nc">Country</span><span class="k">extends</span><span class="nx">Model</span><span class="p">{</span><span class="k">protected</span><span class="k">static</span><span class="k">function</span><span class="nf">boot</span><span class="p">()</span><span class="p">{</span><span class="k">parent</span><span class="o">::</span><span class="na">boot</span><span class="p">();</span><span class="nx">Country</span><span class="o">::</span><span class="na">creating</span><span class="p">(</span><span class="k">function</span><span class="p">(</span><span class="nv">$model</span><span class="p">)</span><span class="p">{</span><span class="nv">$model</span><span class="o">-&gt;</span><span class="na">position</span><span class="o">=</span><span class="nx">Country</span><span class="o">::</span><span class="na">max</span><span class="p">(</span><span class="s1">'position'</span><span class="p">)</span><span class="o">+</span><span class="mi">1</span><span class="p">;</span><span class="p">});</span><span class="p">}</span><span class="p">}</span></code></pre>
</div>
<h3>使用 <code>whereRaw()</code> 使查询效率更快</h3>
<p>使用 <code>whereRaw()</code> 方法，通常可以使查询效率更高。例如你想获取 30+ 天未登录的用户，你可以通过以下实现：</p>
<div class="highlight">
<pre><code class="language-php"><span class="nx">User</span><span class="o">::</span><span class="na">where</span><span class="p">(</span><span class="s1">'active'</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">whereRaw</span><span class="p">(</span><span class="s1">'TIMESTAMPDIFF(DAY, created_at, updated_at) &gt; ?'</span><span class="p">,</span><span class="mi">30</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">();</span></code></pre>
</div>
<h3>多个作用域</h3>
<p>你可以同时创建多个作用域，当然可以在一个查询中使用多个作用域。</p>
<p>模型中定义：</p>
<div class="highlight">
<pre><code class="language-php"><span class="k">public</span><span class="k">function</span><span class="nf">scopeActive</span><span class="p">(</span><span class="nv">$query</span><span class="p">)</span><span class="p">{</span><span class="k">return</span><span class="nv">$query</span><span class="o">-&gt;</span><span class="na">where</span><span class="p">(</span><span class="s1">'active'</span><span class="p">,</span><span class="mi">1</span><span class="p">);</span><span class="p">}</span><span class="k">public</span><span class="k">function</span><span class="nf">scopeRegisteredWithinDays</span><span class="p">(</span><span class="nv">$query</span><span class="p">,</span><span class="nv">$days</span><span class="p">)</span><span class="p">{</span><span class="k">return</span><span class="nv">$query</span><span class="o">-&gt;</span><span class="na">where</span><span class="p">(</span><span class="s1">'created_at'</span><span class="p">,</span><span class="s1">'&gt;='</span><span class="p">,</span><span class="nx">now</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">subDays</span><span class="p">(</span><span class="nv">$days</span><span class="p">));</span><span class="p">}</span></code></pre>
</div>
<p>controller 中使用：</p>
<div class="highlight">
<pre><code class="language-php"><span class="nv">$users</span><span class="o">=</span><span class="nx">User</span><span class="o">::</span><span class="na">registeredWithinDays</span><span class="p">(</span><span class="mi">30</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">active</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">();</span></code></pre>
</div>
<h3>Carbon自动转换</h3>
<p>如果你想使用 <code>whereDate()</code> 查询今天的记录，你可以通过直接 <code>now()</code> 而无需进行 <code>-&gt;toDateString()</code>，因为他会自动转换。</p>
<div class="highlight">
<pre><code class="language-php"><span class="c1">// Instead of
</span><span class="nv">$todayUsers</span><span class="o">=</span><span class="nx">User</span><span class="o">::</span><span class="na">whereDate</span><span class="p">(</span><span class="s1">'created_at'</span><span class="p">,</span><span class="nx">now</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">toDateString</span><span class="p">())</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">();</span><span class="c1">// 不需要转换 now()
</span><span class="nv">$todayUsers</span><span class="o">=</span><span class="nx">User</span><span class="o">::</span><span class="na">whereDate</span><span class="p">(</span><span class="s1">'created_at'</span><span class="p">,</span><span class="nx">now</span><span class="p">())</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">();</span></code></pre>
</div>
<h3>通过首字符分组</h3>
<p>你可以通过任意你想实现的方式进行分组，下面是通过对姓名首字符的分组方法：</p>
<div class="highlight">
<pre><code class="language-php"><span class="nv">$users</span><span class="o">=</span><span class="nx">User</span><span class="o">::</span><span class="na">all</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">groupBy</span><span class="p">(</span><span class="k">function</span><span class="p">(</span><span class="nv">$item</span><span class="p">)</span><span class="p">{</span><span class="k">return</span><span class="nv">$item</span><span class="o">-&gt;</span><span class="na">name</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span><span class="p">});</span></code></pre>
</div>
<h3>限制数据列的更新</h3>
<p>如果你希望设置一个不可更新的列，你可以通过以下方式实现：</p>
<div class="highlight">
<pre><code class="language-php"><span class="k">class</span><span class="nc">User</span><span class="k">extends</span><span class="nx">Model</span><span class="p">{</span><span class="k">public</span><span class="k">function</span><span class="nf">setEmailAttribute</span><span class="p">(</span><span class="nv">$value</span><span class="p">)</span><span class="p">{</span><span class="k">if</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">email</span><span class="p">)</span><span class="p">{</span><span class="k">return</span><span class="p">;</span><span class="p">}</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">attributes</span><span class="p">[</span><span class="s1">'email'</span><span class="p">]</span><span class="o">=</span><span class="nv">$value</span><span class="p">;</span><span class="p">}</span><span class="p">}</span></code></pre>
</div>
<h3>查询多个</h3>
<p>Eloquent 方法 <code>find()</code> 可以通过传递数组参数实现多个记录的查询：</p>
<div class="highlight">
<pre><code class="language-php"><span class="c1">// Will return Eloquent Model
</span><span class="nv">$user</span><span class="o">=</span><span class="nx">User</span><span class="o">::</span><span class="na">find</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span><span class="c1">// Will return Eloquent Collection
</span><span class="nv">$users</span><span class="o">=</span><span class="nx">User</span><span class="o">::</span><span class="na">find</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">]);</span></code></pre>
</div>
<h3>使用 UUID 替代 自增列</h3>
<p>如果你不想在数据表中使用自增列要怎么办？下面叫你如何实现</p>
<p>数据迁移：</p>
<div class="highlight">
<pre><code class="language-php"><span class="nx">Schema</span><span class="o">::</span><span class="na">create</span><span class="p">(</span><span class="s1">'users'</span><span class="p">,</span><span class="k">function</span><span class="p">(</span><span class="nx">Blueprint</span><span class="nv">$table</span><span class="p">)</span><span class="p">{</span><span class="c1">// $table-&gt;increments('id');
</span><span class="nv">$table</span><span class="o">-&gt;</span><span class="na">uuid</span><span class="p">(</span><span class="s1">'id'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">unique</span><span class="p">();</span><span class="p">});</span></code></pre>
</div>
<p>模型:</p>
<div class="highlight">
<pre><code class="language-php"><span class="k">class</span><span class="nc">User</span><span class="k">extends</span><span class="nx">Model</span><span class="p">{</span><span class="k">public</span><span class="nv">$incrementing</span><span class="o">=</span><span class="k">false</span><span class="p">;</span><span class="k">protected</span><span class="nv">$keyType</span><span class="o">=</span><span class="s1">'string'</span><span class="p">;</span><span class="k">protected</span><span class="k">static</span><span class="k">function</span><span class="nf">boot</span><span class="p">()</span><span class="p">{</span><span class="k">parent</span><span class="o">::</span><span class="na">boot</span><span class="p">();</span><span class="nx">User</span><span class="o">::</span><span class="na">creating</span><span class="p">(</span><span class="k">function</span><span class="p">(</span><span class="nv">$model</span><span class="p">)</span><span class="p">{</span><span class="nv">$model</span><span class="o">-&gt;</span><span class="na">setId</span><span class="p">();</span><span class="p">});</span><span class="p">}</span><span class="k">public</span><span class="k">function</span><span class="nf">setId</span><span class="p">()</span><span class="p">{</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">attributes</span><span class="p">[</span><span class="s1">'id'</span><span class="p">]</span><span class="o">=</span><span class="nx">Str</span><span class="o">::</span><span class="na">uuid</span><span class="p">();</span><span class="p">}</span><span class="p">}</span></code></pre>
</div>
<h2>模型关联</h2>
<h3>可排序的模型关联</h3>
<p>你可以在你的关联中使用 orderBy对关联进行排序：</p>
<div class="highlight">
<pre><code class="language-php"><span class="k">public</span><span class="k">function</span><span class="nf">products</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">hasMany</span><span class="p">(</span><span class="nx">Product</span><span class="o">::</span><span class="na">class</span><span class="p">);</span><span class="p">}</span><span class="k">public</span><span class="k">function</span><span class="nf">productsByName</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">hasMany</span><span class="p">(</span><span class="nx">Product</span><span class="o">::</span><span class="na">class</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">orderBy</span><span class="p">(</span><span class="s1">'name'</span><span class="p">);</span><span class="p">}</span></code></pre>
</div>
<h3>有条件的模型关联</h3>
<p>如果你在使用模型关联的时候经常需要额外的进行 where 查询，你可以直接通过对关联进行条件查询，实现方式如下：</p>
<p>Model:</p>
<div class="highlight">
<pre><code class="language-php"><span class="k">public</span><span class="k">function</span><span class="nf">comments</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">hasMany</span><span class="p">(</span><span class="nx">Comment</span><span class="o">::</span><span class="na">class</span><span class="p">);</span><span class="p">}</span><span class="k">public</span><span class="k">function</span><span class="nf">approved_comments</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">hasMany</span><span class="p">(</span><span class="nx">Comment</span><span class="o">::</span><span class="na">class</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">where</span><span class="p">(</span><span class="s1">'approved'</span><span class="p">,</span><span class="mi">1</span><span class="p">);</span><span class="p">}</span></code></pre>
</div>
<h3>对结果的筛选：havingRaw()</h3>
<p>你可以在各种地方使用 RAW DB 查询，包括  <code>groupBy()</code>  和 <code>havingRaw()</code> 后面：</p>
<div class="highlight">
<pre><code class="language-php"><span class="nx">Product</span><span class="o">::</span><span class="na">groupBy</span><span class="p">(</span><span class="s1">'category_id'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">havingRaw</span><span class="p">(</span><span class="s1">'COUNT(*) &gt; 1'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">();</span></code></pre>
</div>
<h3>Eloquent has() 方法可以作用于深层的关联</h3>
<p>Eloquent <code>has()</code> 方法可以通过 <code>books.ratings</code> 的方式，而使查询可以做用于更深层的关联上！</p>
<div class="highlight">
<pre><code class="language-php"><span class="c1">// Author -&gt; hasMany(Book::class);
</span><span class="c1">// Book -&gt; hasMany(Rating::class);
</span><span class="nv">$authors</span><span class="o">=</span><span class="nx">Author</span><span class="o">::</span><span class="na">has</span><span class="p">(</span><span class="s1">'books.ratings'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">();</span></code></pre>
</div>
<h3>通过 Has 方法对 hasMany 数据限制</h3>
<p>在一对多关联中， <code>hasMany()</code> 允许通过 <code>has()</code> 方法进行关联数据条数的限制：</p>
<div class="highlight">
<pre><code class="language-php"><span class="c1">// Author -&gt; hasMany(Book::class)
</span><span class="nv">$authors</span><span class="o">=</span><span class="nx">Author</span><span class="o">::</span><span class="na">has</span><span class="p">(</span><span class="s1">'books'</span><span class="p">,</span><span class="s1">'&gt;'</span><span class="p">,</span><span class="mi">5</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">();</span></code></pre>
</div>
<h3>模型默认值</h3>
<p>你可以通过 <code>belongsTo</code> 关联， to avoid fatal errors when calling it like <code>{{ $post-&gt;user-&gt;name }}</code> if $post-&gt;user doesn't exist.</p>
<div class="highlight">
<pre><code class="language-php"><span class="k">public</span><span class="k">function</span><span class="nf">user</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">belongsTo</span><span class="p">(</span><span class="s1">'AppUser'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">withDefault</span><span class="p">();</span><span class="p">}</span></code></pre>
</div>
<h3>一次性创建多条关联记录</h3>
<p>如果你定义了 <code>hasMany()</code>  关联，你可以通过 <code>saveMany()</code> 来一次性创建多条关联数据：</p>
<div class="highlight">
<pre><code class="language-php"><span class="nv">$post</span><span class="o">=</span><span class="nx">Post</span><span class="o">::</span><span class="na">find</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span><span class="nv">$post</span><span class="o">-&gt;</span><span class="na">comments</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">saveMany</span><span class="p">([</span><span class="k">new</span><span class="nx">Comment</span><span class="p">([</span><span class="s1">'message'</span><span class="o">=&gt;</span><span class="s1">'First comment'</span><span class="p">]),</span><span class="k">new</span><span class="nx">Comment</span><span class="p">([</span><span class="s1">'message'</span><span class="o">=&gt;</span><span class="s1">'Second comment'</span><span class="p">]),</span><span class="p">]);</span></code></pre>
</div>
<h3>快速且精确的加载</h3>
<p>通过 with 你可以获取关联表甚至特定字段訊息：</p>
<div class="highlight">
<pre><code class="language-php"><span class="nv">$users</span><span class="o">=</span><span class="nx">AppBook</span><span class="o">::</span><span class="na">with</span><span class="p">(</span><span class="s1">'author:id,name'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">();</span></code></pre>
</div>
<p>你可以使用他获取更深一层次的关联：</p>
<div class="highlight">
<pre><code class="language-php"><span class="nv">$users</span><span class="o">=</span><span class="nx">AppBook</span><span class="o">::</span><span class="na">with</span><span class="p">(</span><span class="s1">'author.country:id,name'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">();</span></code></pre>
</div>
<h3>上级訊息的级联更新</h3>
<p>例如你想在更新评论訊息的时候想同时更新上级关联的帖子訊息的 updated_at 字段，你可以通过指定 $touch 属性实现：</p>
<div class="highlight">
<pre><code class="language-php"><span class="k">class</span><span class="nc">Comment</span><span class="k">extends</span><span class="nx">Model</span><span class="p">{</span><span class="k">protected</span><span class="nv">$touches</span><span class="o">=</span><span class="p">[</span><span class="s1">'post'</span><span class="p">];</span><span class="p">}</span></code></pre>
</div>
<h3>总是检测关联是否存在</h3>
<p>永远不要在未检测关联是否存在的情况下使用 <code>$model-&gt;relationship-&gt;field</code> 。</p>
<p>It may be deleted for whatever reason, outside your code, by someone else's queued job etc.</p>
<p>可以通过 <code>if-else</code>，在 Blade 中使用 <code>{{ $model-&gt;relationship-&gt;field ?? '' }}</code> ， 或者 <code>{{ optional($model-&gt;relationship)-&gt;field }}</code> 进行检测。</p>
<h3>使用 withCount() 获取记录条数</h3>
<p>如果你定义了 <code>hasMany()</code> 关联，当你想要统计关联数据的数量的时候，<code>尝试下 withCount</code> 吧。例子， 假如你有一个 Post 模型，该模型会有多个 Comments 关联，看下如何使用 <code>withCount()</code> 吧：</p>
<div class="highlight">
<pre><code class="language-php"><span class="k">public</span><span class="k">function</span><span class="nf">index</span><span class="p">()</span><span class="p">{</span><span class="nv">$users</span><span class="o">=</span><span class="nx">User</span><span class="o">::</span><span class="na">withCount</span><span class="p">([</span><span class="s1">'posts'</span><span class="p">,</span><span class="s1">'comments'</span><span class="p">])</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">();</span><span class="k">return</span><span class="nx">view</span><span class="p">(</span><span class="s1">'users'</span><span class="p">,</span><span class="nx">compact</span><span class="p">(</span><span class="s1">'users'</span><span class="p">));</span><span class="p">}</span></code></pre>
</div>
<p>然后在模板文件中使用  <code>{relationship}_count</code> 属性就可以获取相应的数据统计了：</p>
<div class="highlight">
<pre><code class="language-text">@foreach ($users as $user)
&lt;tr&gt;
    &lt;td&gt;{{ $user-&gt;name }}&lt;/td&gt;
    &lt;td class="text-center"&gt;{{ $user-&gt;posts_count }}&lt;/td&gt;
    &lt;td class="text-center"&gt;{{ $user-&gt;comments_count }}&lt;/td&gt;
&lt;/tr&gt;
@endforeach</code></pre>
</div>
<h3>关联查询的筛选条件</h3>
<p>如果你想要在加载关联的时候做一些条件限制，可以通过回调函数实现。例如你想获取国家的前3个城市，可以通过以下代码实现：</p>
<div class="highlight">
<pre><code class="language-php"><span class="nv">$countries</span><span class="o">=</span><span class="nx">Country</span><span class="o">::</span><span class="na">with</span><span class="p">([</span><span class="s1">'cities'</span><span class="o">=&gt;</span><span class="k">function</span><span class="p">(</span><span class="nv">$query</span><span class="p">)</span><span class="p">{</span><span class="nv">$query</span><span class="o">-&gt;</span><span class="na">orderBy</span><span class="p">(</span><span class="s1">'population'</span><span class="p">,</span><span class="s1">'desc'</span><span class="p">);</span><span class="nv">$query</span><span class="o">-&gt;</span><span class="na">take</span><span class="p">(</span><span class="mi">3</span><span class="p">);</span><span class="p">}])</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">();</span></code></pre>
</div>
<h3>始终加载关联</h3>
<p>你即可以通过 <code>$with</code> 属性设置模型始终会加载的关联，也可以在构造函数中动态处理加载项：</p>
<div class="highlight">
<pre><code class="language-php"><span class="k">class</span><span class="nc">ProductTag</span><span class="k">extends</span><span class="nx">Model</span><span class="p">{</span><span class="k">protected</span><span class="nv">$with</span><span class="o">=</span><span class="p">[</span><span class="s1">'product'</span><span class="p">];</span><span class="k">public</span><span class="k">function</span><span class="fm">__construct</span><span class="p">()</span><span class="p">{</span><span class="k">parent</span><span class="o">::</span><span class="na">__construct</span><span class="p">();</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">with</span><span class="o">=</span><span class="p">[</span><span class="s1">'product'</span><span class="p">];</span><span class="k">if</span><span class="p">(</span><span class="nx">auth</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">check</span><span class="p">())</span><span class="p">{</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">with</span><span class="p">[]</span><span class="o">=</span><span class="s1">'user'</span><span class="p">;</span><span class="p">}</span><span class="p">}</span><span class="p">}</span></code></pre>
</div>
<h3>belongsTo 和 hasMany 的使用</h3>
<p>定义 <code>belongsTo</code> 关联和 <code>hasMany</code> 关联，这样可以在创建关联数据的时候有由系统填充关联字段訊息：</p>
<div class="highlight">
<pre><code class="language-php"><span class="c1">// 如果定义了 Post -&gt; belongsTo(User), and User -&gt; hasMany(Post)...
</span><span class="c1">// 以前你需要这样创建文章訊息...
</span><span class="nx">Post</span><span class="o">::</span><span class="na">create</span><span class="p">([</span><span class="s1">'user_id'</span><span class="o">=&gt;</span><span class="nx">auth</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">id</span><span class="p">(),</span><span class="s1">'title'</span><span class="o">=&gt;</span><span class="nx">request</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">input</span><span class="p">(</span><span class="s1">'title'</span><span class="p">),</span><span class="s1">'post_text'</span><span class="o">=&gt;</span><span class="nx">request</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">input</span><span class="p">(</span><span class="s1">'post_text'</span><span class="p">),</span><span class="p">]);</span><span class="c1">// 现在，你可以这样
</span><span class="nx">auth</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">user</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">posts</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">create</span><span class="p">([</span><span class="s1">'title'</span><span class="o">=&gt;</span><span class="nx">request</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">input</span><span class="p">(</span><span class="s1">'title'</span><span class="p">),</span><span class="s1">'post_text'</span><span class="o">=&gt;</span><span class="nx">request</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">input</span><span class="p">(</span><span class="s1">'post_text'</span><span class="p">),</span><span class="p">]);</span></code></pre>
</div>
<h3>自定义归属关联名称</h3>
<p>使用 as 可以重命名您的关联：</p>
<p>模型中定义:</p>
<div class="highlight">
<pre><code class="language-php"><span class="k">public</span><span class="k">function</span><span class="nf">podcasts</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">belongsToMany</span><span class="p">(</span><span class="s1">'AppPodcast'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">as</span><span class="p">(</span><span class="s1">'subscription'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">withTimestamps</span><span class="p">();</span><span class="p">}</span></code></pre>
</div>
<p>控制器中使用:</p>
<div class="highlight">
<pre><code class="language-php"><span class="nv">$podcasts</span><span class="o">=</span><span class="nv">$user</span><span class="o">-&gt;</span><span class="na">podcasts</span><span class="p">();</span><span class="k">foreach</span><span class="p">(</span><span class="nv">$podcasts</span><span class="k">as</span><span class="nv">$podcast</span><span class="p">)</span><span class="p">{</span><span class="c1">// instead of $podcast-&gt;pivot-&gt;created_at ...
</span><span class="k">echo</span><span class="nv">$podcast</span><span class="o">-&gt;</span><span class="na">subscription</span><span class="o">-&gt;</span><span class="na">created_at</span><span class="p">;</span><span class="p">}</span></code></pre>
</div>
<h2>数据迁移</h2>
<h3>迁移执行顺序</h3>
<p>通过修改迁移文件的时间戳前缀可以达到排序迁移执行数据的目的。例如：将<code>2018_08_04_070443_create_posts_table.php</code> 修改为 <code>2018_07_04_070443_create_posts_table.php</code> ( 修改 <code>2018_08_04</code> 为 <code>2018_07_04</code> ).</p>
<h3>Migration 设定时间戳时区</h3>
<p>迁移中 <code>timestamps()</code> 和 <code>timestampsTz()</code> 都可以设定时区。</p>
<div class="highlight">
<pre><code class="language-php"><span class="nx">Schema</span><span class="o">::</span><span class="na">create</span><span class="p">(</span><span class="s1">'employees'</span><span class="p">,</span><span class="k">function</span><span class="p">(</span><span class="nx">Blueprint</span><span class="nv">$table</span><span class="p">)</span><span class="p">{</span><span class="nv">$table</span><span class="o">-&gt;</span><span class="na">increments</span><span class="p">(</span><span class="s1">'id'</span><span class="p">);</span><span class="nv">$table</span><span class="o">-&gt;</span><span class="na">string</span><span class="p">(</span><span class="s1">'name'</span><span class="p">);</span><span class="nv">$table</span><span class="o">-&gt;</span><span class="na">string</span><span class="p">(</span><span class="s1">'email'</span><span class="p">);</span><span class="nv">$table</span><span class="o">-&gt;</span><span class="na">timestampsTz</span><span class="p">();</span><span class="p">});</span></code></pre>
</div>
<p>另外还有 <code>dateTimeTz()</code>, <code>timeTz()</code>, <code>timestampTz()</code>, <code>softDeletesTz()</code>.</p>
<h3>数据 Migrations 类型</h3>
<p>一些特定值得迁移类型：</p>
<div class="highlight">
<pre><code class="language-php"><span class="nv">$table</span><span class="o">-&gt;</span><span class="na">geometry</span><span class="p">(</span><span class="s1">'positions'</span><span class="p">);</span><span class="nv">$table</span><span class="o">-&gt;</span><span class="na">ipAddress</span><span class="p">(</span><span class="s1">'visitor'</span><span class="p">);</span><span class="nv">$table</span><span class="o">-&gt;</span><span class="na">macAddress</span><span class="p">(</span><span class="s1">'device'</span><span class="p">);</span><span class="nv">$table</span><span class="o">-&gt;</span><span class="na">point</span><span class="p">(</span><span class="s1">'position'</span><span class="p">);</span><span class="nv">$table</span><span class="o">-&gt;</span><span class="na">uuid</span><span class="p">(</span><span class="s1">'id'</span><span class="p">);</span></code></pre>
</div>
<p>更多类型查阅： <a href="https://link.zhihu.com/?target=https%3A//laravel.com/docs/master/migrations%23creating-columns" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">official documentation</a>.</p>
<h3>默认时间戳</h3>
<p>通过 <code>timestamp()</code> 设定列为时间戳类型，通过 <code>useCurrent()</code> 设定该列的默认值。</p>
<div class="highlight">
<pre><code class="language-php"><span class="nv">$table</span><span class="o">-&gt;</span><span class="na">timestamp</span><span class="p">(</span><span class="s1">'created_at'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">useCurrent</span><span class="p">();</span><span class="nv">$table</span><span class="o">-&gt;</span><span class="na">timestamp</span><span class="p">(</span><span class="s1">'updated_at'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">useCurrent</span><span class="p">();</span></code></pre>
</div>
<h2>视图</h2>
<h3>foreach 中 $loop 的使用</h3>
<p>通过 <code>$loop</code> 判断该数据是否是最先/最后的数据：</p>
<div class="highlight">
<pre><code class="language-text">@foreach ($users as $user)
     @if ($loop-&gt;first)
        This is the first iteration.
     @endif

     @if ($loop-&gt;last)
        This is the last iteration.
     @endif

     &lt;p&gt;This is user {{ $user-&gt;id }}&lt;/p&gt;
@endforeach</code></pre>
</div>
<p>当然他还有其他可用属性例如： <code>$loop-&gt;iteration</code> 和<code>$loop-&gt;count</code>. 详情阅读： <a href="https://link.zhihu.com/?target=https%3A//laravel.com/docs/master/blade%23the-loop-variable" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">official documentation</a>.</p>
<h3>如何判断 View 是否存在?</h3>
<p>在你加载 view 之前你可以判断 view 是否存在，从而避免不必要的错误显示。</p>
<div class="highlight">
<pre><code class="language-php"><span class="k">if</span><span class="p">(</span><span class="nx">view</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">exists</span><span class="p">(</span><span class="s1">'custom.page'</span><span class="p">))</span><span class="p">{</span><span class="c1">// Load the view
</span><span class="p">}</span></code></pre>
</div>
<p>你可以提供多个 view 供选择：</p>
<div class="highlight">
<pre><code class="language-php"><span class="k">return</span><span class="nx">view</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">first</span><span class="p">([</span><span class="s1">'custom.dashboard'</span><span class="p">,</span><span class="s1">'dashboard'</span><span class="p">],</span><span class="nv">$data</span><span class="p">);</span></code></pre>
</div>
<h3>错误模板页面</h3>
<p>快速创建特定错误的页面，你只要以该错误code命名并创建相应的 blade 即可。例如： 500（resources/views/errors/500.blade.php）/403（resources/views/errors/403.blade.php），系统会通过相应的 code 自动匹配错误显示页面。</p>
<h3>直接使用 view</h3>
<p>可以直接在路由中绑定需要显示的 view：</p>
<div class="highlight">
<pre><code class="language-php"><span class="c1">// 在 controller 绑定 view
</span><span class="nx">Route</span><span class="o">::</span><span class="na">get</span><span class="p">(</span><span class="s1">'about'</span><span class="p">,</span><span class="s1">'TextsController@about'</span><span class="p">);</span><span class="k">class</span><span class="nc">TextsController</span><span class="k">extends</span><span class="nx">Controller</span><span class="p">{</span><span class="k">public</span><span class="k">function</span><span class="nf">about</span><span class="p">()</span><span class="p">{</span><span class="k">return</span><span class="nx">view</span><span class="p">(</span><span class="s1">'texts.about'</span><span class="p">);</span><span class="p">}</span><span class="p">}</span><span class="c1">// 直接在路由中绑定
</span><span class="nx">Route</span><span class="o">::</span><span class="na">view</span><span class="p">(</span><span class="s1">'about'</span><span class="p">,</span><span class="s1">'texts.about'</span><span class="p">);</span></code></pre>
</div>
<h3>Blade <a href="https://link.zhihu.com/?target=https%3A//learnku.com/users/45051" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">[@auth](https://learnku.com/users/45051)</a></h3>
<p>在 Blade 中直接使用 <code>auth()</code> 可以判断以及获取当前登录的用户訊息：</p>
<p>例子：</p>
<div class="highlight">
<pre><code class="language-text">@if(auth()-&gt;user())
    // 用户已登录
@endif</code></pre>
</div>
<p>或者更简单的方式:</p>
<div class="highlight">
<pre><code class="language-text">@auth
    // 鉴权通过
@endauth</code></pre>
</div>
<p>相反的方法 <code>@guest</code>：</p>
<div class="highlight">
<pre><code class="language-text">@guest
    // 鉴权未通过
@endguest</code></pre>
</div>
<h3>Blade中循环嵌套中使用 $loop</h3>
<p>Blade 循环嵌套，可以通过 <code>$loop</code> 获取上层数据：</p>
<div class="highlight">
<pre><code class="language-text">@foreach ($users as $user)
    @foreach ($user-&gt;posts as $post)
        @if ($loop-&gt;parent-&gt;first)
            This is first iteration of the parent loop.
        @endif
    @endforeach
@endforeach</code></pre>
</div>
<h3>自定义 Blade 指令</h3>
<p>Laravel 提供了简单的方式自定义 Blade 指令，只需在  <code>app/Providers/AppServiceProvider.php</code> 注册自己的指令即可。例子：你想要使用新的标签替换 <code>&lt;br&gt;</code> 标签：</p>
<div class="highlight">
<pre><code class="language-text">&lt;textarea&gt;@br2nl($post-&gt;post_text)&lt;/textarea&gt;</code></pre>
</div>
<p>将该指令添加到 AppServiceProvider 的  <code>boot()</code> 方法中：</p>
<div class="highlight">
<pre><code class="language-php"><span class="k">public</span><span class="k">function</span><span class="nf">boot</span><span class="p">()</span><span class="p">{</span><span class="nx">Blade</span><span class="o">::</span><span class="na">directive</span><span class="p">(</span><span class="s1">'br2nl'</span><span class="p">,</span><span class="k">function</span><span class="p">(</span><span class="nv">$string</span><span class="p">)</span><span class="p">{</span><span class="k">return</span><span class="s2">"&lt;?php echo preg_replace('/&lt;br(s*)?/?&gt;/i', </span><span class="se">"n"</span><span class="s2">, </span><span class="si">$string</span><span class="s2">); ?&gt;"</span><span class="p">;</span><span class="p">});</span><span class="p">}</span></code></pre>
</div>
<h3>Blade 指令说明: IncludeIf, IncludeWhen, IncludeFirst</h3>
<p>当你不确定 Blade 的组件是否存在的时候可以使用一下方法：</p>
<p>仅仅在存在时加载该组件:</p>
<div class="highlight">
<pre><code class="language-text">@includeIf('partials.header')</code></pre>
</div>
<p>仅仅在有权限的时候加载该组件</p>
<div class="highlight">
<pre><code class="language-text">@includeWhen(auth()-&gt;user()-&gt;role_id == 1, 'partials.header')</code></pre>
</div>
<p>当该组件不存在时，会加载默认组件：</p>
<div class="highlight">
<pre><code class="language-text">@includeFirst('adminlte.header', 'default.header')</code></pre>
</div>
<h2>路由</h2>
<h3>路由组嵌套</h3>
<p>路由组可以使用嵌套：</p>
<div class="highlight">
<pre><code class="language-php"><span class="nx">Route</span><span class="o">::</span><span class="na">group</span><span class="p">([</span><span class="s1">'prefix'</span><span class="o">=&gt;</span><span class="s1">'account'</span><span class="p">,</span><span class="s1">'as'</span><span class="o">=&gt;</span><span class="s1">'account.'</span><span class="p">],</span><span class="k">function</span><span class="p">()</span><span class="p">{</span><span class="nx">Route</span><span class="o">::</span><span class="na">get</span><span class="p">(</span><span class="s1">'login'</span><span class="p">,</span><span class="s1">'AccountController@login'</span><span class="p">);</span><span class="nx">Route</span><span class="o">::</span><span class="na">get</span><span class="p">(</span><span class="s1">'register'</span><span class="p">,</span><span class="s1">'AccountController@register'</span><span class="p">);</span><span class="nx">Route</span><span class="o">::</span><span class="na">group</span><span class="p">([</span><span class="s1">'middleware'</span><span class="o">=&gt;</span><span class="s1">'auth'</span><span class="p">],</span><span class="k">function</span><span class="p">()</span><span class="p">{</span><span class="nx">Route</span><span class="o">::</span><span class="na">get</span><span class="p">(</span><span class="s1">'edit'</span><span class="p">,</span><span class="s1">'AccountController@edit'</span><span class="p">);</span><span class="p">});</span><span class="p">});</span></code></pre>
</div>
<h3>子域通配符</h3>
<p>你可以通过动态子域名创建相应的路由：</p>
<div class="highlight">
<pre><code class="language-php"><span class="nx">Route</span><span class="o">::</span><span class="na">domain</span><span class="p">(</span><span class="s1">'{username}.workspace.com'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">group</span><span class="p">(</span><span class="k">function</span><span class="p">()</span><span class="p">{</span><span class="nx">Route</span><span class="o">::</span><span class="na">get</span><span class="p">(</span><span class="s1">'user/{id}'</span><span class="p">,</span><span class="k">function</span><span class="p">(</span><span class="nv">$username</span><span class="p">,</span><span class="nv">$id</span><span class="p">)</span><span class="p">{</span><span class="c1">//
</span><span class="p">});</span><span class="p">});</span></code></pre>
</div>
<h3>What's behind the routes?</h3>
<p><code>Auth::routes()</code> 下包含了那些路由呢？ 你可以在 <code>/vendor/laravel/ui/src/AuthRouteMethods.php</code> 找到：</p>
<div class="highlight">
<pre><code class="language-php"><span class="k">public</span><span class="k">function</span><span class="nf">auth</span><span class="p">()</span><span class="p">{</span><span class="k">return</span><span class="k">function</span><span class="p">(</span><span class="nv">$options</span><span class="o">=</span><span class="p">[])</span><span class="p">{</span><span class="c1">// Authentication Routes...
</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">(</span><span class="s1">'login'</span><span class="p">,</span><span class="s1">'AuthLoginController@showLoginForm'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">name</span><span class="p">(</span><span class="s1">'login'</span><span class="p">);</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">post</span><span class="p">(</span><span class="s1">'login'</span><span class="p">,</span><span class="s1">'AuthLoginController@login'</span><span class="p">);</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">post</span><span class="p">(</span><span class="s1">'logout'</span><span class="p">,</span><span class="s1">'AuthLoginController@logout'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">name</span><span class="p">(</span><span class="s1">'logout'</span><span class="p">);</span><span class="c1">// Registration Routes...
</span><span class="k">if</span><span class="p">(</span><span class="nv">$options</span><span class="p">[</span><span class="s1">'register'</span><span class="p">]</span><span class="o">??</span><span class="k">true</span><span class="p">)</span><span class="p">{</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">(</span><span class="s1">'register'</span><span class="p">,</span><span class="s1">'AuthRegisterController@showRegistrationForm'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">name</span><span class="p">(</span><span class="s1">'register'</span><span class="p">);</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">post</span><span class="p">(</span><span class="s1">'register'</span><span class="p">,</span><span class="s1">'AuthRegisterController@register'</span><span class="p">);</span><span class="p">}</span><span class="c1">// Password Reset Routes...
</span><span class="k">if</span><span class="p">(</span><span class="nv">$options</span><span class="p">[</span><span class="s1">'reset'</span><span class="p">]</span><span class="o">??</span><span class="k">true</span><span class="p">)</span><span class="p">{</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">resetPassword</span><span class="p">();</span><span class="p">}</span><span class="c1">// Password Confirmation Routes...
</span><span class="k">if</span><span class="p">(</span><span class="nv">$options</span><span class="p">[</span><span class="s1">'confirm'</span><span class="p">]</span><span class="o">??</span><span class="nx">class_exists</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">prependGroupNamespace</span><span class="p">(</span><span class="s1">'AuthConfirmPasswordController'</span><span class="p">)))</span><span class="p">{</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">confirmPassword</span><span class="p">();</span><span class="p">}</span><span class="c1">// Email Verification Routes...
</span><span class="k">if</span><span class="p">(</span><span class="nv">$options</span><span class="p">[</span><span class="s1">'verify'</span><span class="p">]</span><span class="o">??</span><span class="k">false</span><span class="p">)</span><span class="p">{</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">emailVerification</span><span class="p">();</span><span class="p">}</span><span class="p">};</span><span class="p">}</span></code></pre>
</div>
<p>Laravel 7 之前, 存在与文件 <code>/vendor/laravel/framework/src/illuminate/Routing/Router.php</code>。</p>
<h3>路由注入绑定</h3>
<p>你可以通过绑定 user 参数 <code>Route::get('api/users/{user}', function (AppUser $user) { … }</code> - 不仅仅可以通过自增 ID 字段筛选，也可以使用 <code>{user}</code> 的 <code>username</code> 字段筛选，只要在模型中这样处理即可:</p>
<div class="highlight">
<pre><code class="language-php"><span class="k">public</span><span class="k">function</span><span class="nf">getRouteKeyName</span><span class="p">()</span><span class="p">{</span><span class="k">return</span><span class="s1">'username'</span><span class="p">;</span><span class="p">}</span></code></pre>
</div>
<h3>快速定义路由控制器</h3>
<p>在此之前，你可能这样写：</p>
<div class="highlight">
<pre><code class="language-php"><span class="nx">Route</span><span class="o">::</span><span class="na">get</span><span class="p">(</span><span class="s1">'page'</span><span class="p">,</span><span class="s1">'PageController@action'</span><span class="p">);</span></code></pre>
</div>
<p>上面写法在编辑器中无法从 route 直接跳转到相应的 controller 中，尝试一下方法：</p>
<div class="highlight">
<pre><code class="language-php"><span class="nx">Route</span><span class="o">::</span><span class="na">get</span><span class="p">(</span><span class="s1">'page'</span><span class="p">,</span><span class="p">[</span><span class="nx">AppHttpControllersPageController</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="s1">'action'</span><span class="p">]);</span></code></pre>
</div>
<p>现在你可以在编辑器中直接点击 <b>PageController</b> 编辑器会根据路径自动找到相关文件（这需要你的编辑器支持，像 phpstorm）。</p>
<h3>路由默认值</h3>
<p>如果你你不想在路由匹配失败时显示 404 错误页面，你可以通过回调函数设置默认显示内容，这样在路由匹配失败的时候会直接显示你自定义的内容：</p>
<div class="highlight">
<pre><code class="language-php"><span class="nx">Route</span><span class="o">::</span><span class="na">group</span><span class="p">([</span><span class="s1">'middleware'</span><span class="o">=&gt;</span><span class="p">[</span><span class="s1">'auth'</span><span class="p">],</span><span class="s1">'prefix'</span><span class="o">=&gt;</span><span class="s1">'admin'</span><span class="p">,</span><span class="s1">'as'</span><span class="o">=&gt;</span><span class="s1">'admin.'</span><span class="p">],</span><span class="k">function</span><span class="p">()</span><span class="p">{</span><span class="nx">Route</span><span class="o">::</span><span class="na">get</span><span class="p">(</span><span class="s1">'/home'</span><span class="p">,</span><span class="s1">'HomeController@index'</span><span class="p">);</span><span class="nx">Route</span><span class="o">::</span><span class="na">resource</span><span class="p">(</span><span class="s1">'tasks'</span><span class="p">,</span><span class="s1">'AdminTasksController'</span><span class="p">);</span><span class="p">});</span><span class="c1">// 其他路由
</span><span class="nx">Route</span><span class="o">::</span><span class="na">fallback</span><span class="p">(</span><span class="k">function</span><span class="p">()</span><span class="p">{</span><span class="k">return</span><span class="s1">'Hm, why did you land here somehow?'</span><span class="p">;</span><span class="p">});</span></code></pre>
</div>
<h3>使用正则验证路由参数</h3>
<p>我们可以直接在路由定义时使用  “where” 方法验证路由参数。一个非常典型的情况是在路由的前面加上语言设置， 像 <code>fr/blog</code> 和 <code>en/article/333</code> 这样。我们如何确保这两个首字母不用于语言以外的其他字符串？</p>
<p><code>routes/web.php</code>:</p>
<div class="highlight">
<pre><code class="language-php"><span class="nx">Route</span><span class="o">::</span><span class="na">group</span><span class="p">([</span><span class="s1">'prefix'</span><span class="o">=&gt;</span><span class="s1">'{locale}'</span><span class="p">,</span><span class="s1">'where'</span><span class="o">=&gt;</span><span class="p">[</span><span class="s1">'locale'</span><span class="o">=&gt;</span><span class="s1">'[a-zA-Z]{2}'</span><span class="p">]</span><span class="p">],</span><span class="k">function</span><span class="p">()</span><span class="p">{</span><span class="nx">Route</span><span class="o">::</span><span class="na">get</span><span class="p">(</span><span class="s1">'/'</span><span class="p">,</span><span class="s1">'HomeController@index'</span><span class="p">);</span><span class="nx">Route</span><span class="o">::</span><span class="na">get</span><span class="p">(</span><span class="s1">'article/{id}'</span><span class="p">,</span><span class="s1">'ArticleController@show'</span><span class="p">);</span><span class="p">});</span></code></pre>
</div>
<h3>全局，访客，用户的限流</h3>
<p>你可以通过 <code>throttle:60,1</code> 来限制单位时间内请求某个可连接的此处：</p>
<div class="highlight">
<pre><code class="language-php"><span class="nx">Route</span><span class="o">::</span><span class="na">middleware</span><span class="p">(</span><span class="s1">'auth:api'</span><span class="p">,</span><span class="s1">'throttle:60,1'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">group</span><span class="p">(</span><span class="k">function</span><span class="p">()</span><span class="p">{</span><span class="nx">Route</span><span class="o">::</span><span class="na">get</span><span class="p">(</span><span class="s1">'/user'</span><span class="p">,</span><span class="k">function</span><span class="p">()</span><span class="p">{</span><span class="c1">//
</span><span class="p">});</span><span class="p">});</span></code></pre>
</div>
<p>你可以针对不同用户组进行不同限制：</p>
<div class="highlight">
<pre><code class="language-php"><span class="c1">// maximum of 10 requests for guests, 60 for authenticated users
</span><span class="nx">Route</span><span class="o">::</span><span class="na">middleware</span><span class="p">(</span><span class="s1">'throttle:10|60,1'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">group</span><span class="p">(</span><span class="k">function</span><span class="p">()</span><span class="p">{</span><span class="c1">//
</span><span class="p">});</span></code></pre>
</div>
<p>Also, you can have a DB field users.rate_limit and limit the amount for specific user:</p>
<div class="highlight">
<pre><code class="language-php"><span class="nx">Route</span><span class="o">::</span><span class="na">middleware</span><span class="p">(</span><span class="s1">'auth:api'</span><span class="p">,</span><span class="s1">'throttle:rate_limit,1'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">group</span><span class="p">(</span><span class="k">function</span><span class="p">()</span><span class="p">{</span><span class="nx">Route</span><span class="o">::</span><span class="na">get</span><span class="p">(</span><span class="s1">'/user'</span><span class="p">,</span><span class="k">function</span><span class="p">()</span><span class="p">{</span><span class="c1">//
</span><span class="p">});</span><span class="p">});</span></code></pre>
</div>
<h3>路由的Query params 参数设置</h3>
<p>你可以通过 route 方法第二个参数，以数组的形式将query 参数绑定到路由：</p>
<div class="highlight">
<pre><code class="language-php"><span class="nx">Route</span><span class="o">::</span><span class="na">get</span><span class="p">(</span><span class="s1">'user/{id}/profile'</span><span class="p">,</span><span class="k">function</span><span class="p">(</span><span class="nv">$id</span><span class="p">)</span><span class="p">{</span><span class="c1">//
</span><span class="p">})</span><span class="o">-&gt;</span><span class="na">name</span><span class="p">(</span><span class="s1">'profile'</span><span class="p">);</span><span class="nv">$url</span><span class="o">=</span><span class="nx">route</span><span class="p">(</span><span class="s1">'profile'</span><span class="p">,</span><span class="p">[</span><span class="s1">'id'</span><span class="o">=&gt;</span><span class="mi">1</span><span class="p">,</span><span class="s1">'photos'</span><span class="o">=&gt;</span><span class="s1">'yes'</span><span class="p">]);</span><span class="c1">// Result: /user/1/profile?photos=yes
</span></code></pre>
</div>
<h2>验证</h2>
<h3>图片验证</h3>
<p>你可以验证上传图片的尺寸：</p>
<div class="highlight">
<pre><code class="language-php"><span class="p">[</span><span class="s1">'photo'</span><span class="o">=&gt;</span><span class="s1">'dimensions:max_width=4096,max_height=4096'</span><span class="p">]</span></code></pre>
</div>
<h3>自定义验证错误消息</h3>
<p>可以自定义现有规则的错误消息，只需要创建相应的语言文件即可 <code>resources/lang/xx/validation.php</code> ：</p>
<div class="highlight">
<pre><code class="language-php"><span class="s1">'custom'</span><span class="o">=&gt;</span><span class="p">[</span><span class="s1">'email'</span><span class="o">=&gt;</span><span class="p">[</span><span class="s1">'required'</span><span class="o">=&gt;</span><span class="s1">'We need to know your e-mail address!'</span><span class="p">,</span><span class="p">],</span><span class="p">],</span></code></pre>
</div>
<h3>时间验证中的 "now" 和 "yesterday"关键字</h3>
<p>您可以通过 <code>before/after</code> 规则来验证日期，并将各种字符串作为参数传递，例如：<code>tomorrow</code>, <code>now</code>, <code>yesterday</code>。 例如：<code>'start_date' =&gt; 'after:now'</code>。 它在底层使用 <code>strtotime（）</code> 验证。</p>
<div class="highlight">
<pre><code class="language-php"><span class="nv">$rules</span><span class="o">=</span><span class="p">[</span><span class="s1">'start_date'</span><span class="o">=&gt;</span><span class="s1">'after:tomorrow'</span><span class="p">,</span><span class="s1">'end_date'</span><span class="o">=&gt;</span><span class="s1">'after:start_date'</span><span class="p">];</span></code></pre>
</div>
<h3>有条件的验证规则</h3>
<p>如果你的验证规则需要同时满足额外的条件，在  <code>FormRequest</code> 方法中定义 <code>withValidator()</code>  添加你的条件即可：</p>
<div class="highlight">
<pre><code class="language-php"><span class="k">use</span><span class="nx">IlluminateValidationValidator</span><span class="p">;</span><span class="k">class</span><span class="nc">StoreBlogCategoryRequest</span><span class="k">extends</span><span class="nx">FormRequest</span><span class="p">{</span><span class="k">public</span><span class="k">function</span><span class="nf">withValidator</span><span class="p">(</span><span class="nx">Validator</span><span class="nv">$validator</span><span class="p">)</span><span class="p">{</span><span class="k">if</span><span class="p">(</span><span class="nx">auth</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">user</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">is_admin</span><span class="p">)</span><span class="p">{</span><span class="nv">$validator</span><span class="o">-&gt;</span><span class="na">addRules</span><span class="p">([</span><span class="s1">'some_secret_password'</span><span class="o">=&gt;</span><span class="s1">'required'</span><span class="p">]);</span><span class="p">}</span><span class="p">}</span><span class="p">}</span></code></pre>
</div>
<h3>自定义验证消息</h3>
<p>通过<code>FormRequest</code> 的 <code>messages()</code> 方法，你可以自定义验证错误提示訊息：</p>
<div class="highlight">
<pre><code class="language-php"><span class="k">class</span><span class="nc">StoreUserRequest</span><span class="k">extends</span><span class="nx">FormRequest</span><span class="p">{</span><span class="k">public</span><span class="k">function</span><span class="nf">rules</span><span class="p">()</span><span class="p">{</span><span class="k">return</span><span class="p">[</span><span class="s1">'name'</span><span class="o">=&gt;</span><span class="s1">'required'</span><span class="p">];</span><span class="p">}</span><span class="k">public</span><span class="k">function</span><span class="nf">messages</span><span class="p">()</span><span class="p">{</span><span class="k">return</span><span class="p">[</span><span class="s1">'name.required'</span><span class="o">=&gt;</span><span class="s1">'User name should be real name'</span><span class="p">];</span><span class="p">}</span><span class="p">}</span></code></pre>
</div>
<h3>验证前置操作</h3>
<p>验证前置操作，如果你需要在验证之前对某些字段做一些处理， <code>prepareForValidation()</code> 可以实现该功能：</p>
<div class="highlight">
<pre><code class="language-php"><span class="k">protected</span><span class="k">function</span><span class="nf">prepareForValidation</span><span class="p">()</span><span class="p">{</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">merge</span><span class="p">([</span><span class="s1">'slug'</span><span class="o">=&gt;</span><span class="nx">IlluminateSupportStr</span><span class="o">::</span><span class="na">slug</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">slug</span><span class="p">),</span><span class="p">]);</span><span class="p">}</span></code></pre>
</div>
<h3>遇到错误时终止验证</h3>
<p>默认情况下，laraevl 会在处理完成所有验证规则之后，将错误訊息一并返回；当然如果你想在遇到第一个错误的时候就终止继续往下的验证你可以通过添加一下规则： <code>bail</code></p>
<div class="highlight">
<pre><code class="language-php"><span class="nv">$request</span><span class="o">-&gt;</span><span class="na">validate</span><span class="p">([</span><span class="s1">'title'</span><span class="o">=&gt;</span><span class="s1">'bail|required|unique:posts|max:255'</span><span class="p">,</span><span class="s1">'body'</span><span class="o">=&gt;</span><span class="s1">'required'</span><span class="p">,</span><span class="p">]);</span></code></pre>
</div>
<h2>Policies</h2>
<h3>一次性检测多个权限</h3>
<p><code>@can</code> Blade 指令可以检测当前用户是否有某个权限，但是当场景复杂点要怎么处理？比如当我在同时拥有多个权限才能进行某个操作的时候？ <code>@canany</code> 指令了解下：</p>
<div class="highlight">
<pre><code class="language-text">@canany(['update', 'view', 'delete'], $post)
    // 当前用户拥有以下其权限： 更新,显示或者删除文章
@elsecanany(['create'], AppPost::class)
    // 当前用户无法创建文章
@endcanany</code></pre>
</div>
<h2>集合</h2>
<h3>不要在集合过滤中使用 NULL</h3>
<p>你可以在 Eloquent 中使用 Null  过滤，但是在集合（ <b>collection</b> ）中，Null 过滤将不会生效：</p>
<div class="highlight">
<pre><code class="language-php"><span class="c1">// 这样可以
</span><span class="nv">$messages</span><span class="o">=</span><span class="nx">Message</span><span class="o">::</span><span class="na">where</span><span class="p">(</span><span class="s1">'read_at is null'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">();</span><span class="c1">// 这样无法正常返回
</span><span class="nv">$messages</span><span class="o">=</span><span class="nx">Message</span><span class="o">::</span><span class="na">all</span><span class="p">();</span><span class="nv">$unread_messages</span><span class="o">=</span><span class="nv">$messages</span><span class="o">-&gt;</span><span class="na">where</span><span class="p">(</span><span class="s1">'read_at is null'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">count</span><span class="p">();</span><span class="c1">// 这样也可以
</span><span class="nv">$unread_messages</span><span class="o">=</span><span class="nv">$messages</span><span class="o">-&gt;</span><span class="na">where</span><span class="p">(</span><span class="s1">'read_at'</span><span class="p">,</span><span class="s1">''</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">count</span><span class="p">();</span></code></pre>
</div>
<h3>在集合上使用自定义 groupBy 回调</h3>
<p>如果你想根据某些条件对结果进行分组处理，并且该条件列并非数据库字段，你可以通过 GroupBy 回调实现。</p>
<p>例如，如果你想按注册日期对用户进行分组，代码如下:</p>
<div class="highlight">
<pre><code class="language-php"><span class="nv">$users</span><span class="o">=</span><span class="nx">User</span><span class="o">::</span><span class="na">all</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">groupBy</span><span class="p">(</span><span class="k">function</span><span class="p">(</span><span class="nv">$item</span><span class="p">)</span><span class="p">{</span><span class="k">return</span><span class="nv">$item</span><span class="o">-&gt;</span><span class="na">created_at</span><span class="o">-&gt;</span><span class="na">format</span><span class="p">(</span><span class="s1">'Y-m-d'</span><span class="p">);</span><span class="p">});</span></code></pre>
</div>
<p><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Notice: <code>User::all()</code> 将返回集合类型数据，因此这是在集合上进行的 <code>GroupBy</code> 操作</p>
<h3>集合的复用</h3>
<p>当你在查询结果上使用  <code>-&gt;all()</code> 或者 <code>-&gt;get()</code> 方法的时候，该操作是针对结果集合进行的操作，不会再额外的进行查询操作。</p>
<div class="highlight">
<pre><code class="language-php"><span class="nv">$users</span><span class="o">=</span><span class="nx">User</span><span class="o">::</span><span class="na">all</span><span class="p">();</span><span class="k">echo</span><span class="s1">'Max ID: '</span><span class="o">.</span><span class="nv">$users</span><span class="o">-&gt;</span><span class="na">max</span><span class="p">(</span><span class="s1">'id'</span><span class="p">);</span><span class="k">echo</span><span class="s1">'Average age: '</span><span class="o">.</span><span class="nv">$users</span><span class="o">-&gt;</span><span class="na">avg</span><span class="p">(</span><span class="s1">'age'</span><span class="p">);</span><span class="k">echo</span><span class="s1">'Total budget: '</span><span class="o">.</span><span class="nv">$users</span><span class="o">-&gt;</span><span class="na">sum</span><span class="p">(</span><span class="s1">'budget'</span><span class="p">);</span></code></pre>
</div>
<h2>鉴权</h2>
<h3>你链接 Auth::once() 吗?</h3>
<p><code>Auth::once()</code> 可以用于构建无状态请求，他不会产生任何 cookie訊息，这很有利于接口的开发：</p>
<div class="highlight">
<pre><code class="language-php"><span class="k">if</span><span class="p">(</span><span class="nx">Auth</span><span class="o">::</span><span class="na">once</span><span class="p">(</span><span class="nv">$credentials</span><span class="p">))</span><span class="p">{</span><span class="c1">//
</span><span class="p">}</span></code></pre>
</div>
<h3>更新密码同时更新用户 token</h3>
<p>在更新用户密码的同时更新用户 token 很有必要：</p>
<p>模型:</p>
<div class="highlight">
<pre><code class="language-php"><span class="k">public</span><span class="k">function</span><span class="nf">setPasswordAttribute</span><span class="p">(</span><span class="nv">$value</span><span class="p">)</span><span class="p">{</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">attributes</span><span class="p">[</span><span class="s1">'password'</span><span class="p">]</span><span class="o">=</span><span class="nv">$value</span><span class="p">;</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">attributes</span><span class="p">[</span><span class="s1">'api_token'</span><span class="p">]</span><span class="o">=</span><span class="nx">Str</span><span class="o">::</span><span class="na">random</span><span class="p">(</span><span class="mi">100</span><span class="p">);</span><span class="p">}</span></code></pre>
</div>
<h2>邮件</h2>
<h3>将测试邮件存储到 laravel.log</h3>
<p>开发过程中，你可能需要测试邮件发送，但是你有不希望测试邮件真正发送到客户邮箱，这时候你可以通过配置 <code>.env</code> 参数 <code>MAIL_DRIVER=log</code> 这样，邮件将会以文本的形式存储到 <code>storage/logs/laravel.log</code> ，而不会真正发送出去。</p>
<h3>邮件预览</h3>
<p>如果你使用 Mailables 为发送邮件提供服务，那么你可以直接在浏览器中浏览邮件预览，而不必真正的发送：</p>
<div class="highlight">
<pre><code class="language-php"><span class="nx">Route</span><span class="o">::</span><span class="na">get</span><span class="p">(</span><span class="s1">'/mailable'</span><span class="p">,</span><span class="k">function</span><span class="p">()</span><span class="p">{</span><span class="nv">$invoice</span><span class="o">=</span><span class="nx">AppInvoice</span><span class="o">::</span><span class="na">find</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span><span class="k">return</span><span class="k">new</span><span class="nx">AppMailInvoicePaid</span><span class="p">(</span><span class="nv">$invoice</span><span class="p">);</span><span class="p">});</span></code></pre>
</div>
<h3>Laravel 通知的默认主题（subject）</h3>
<p>如果你在使用 <b>toMail()</b> 发送邮件通知的时候，未指定相关主题（subject）laravel 提供了默认参数可以使用：</p>
<p>因此，你只需要有：</p>
<div class="highlight">
<pre><code class="language-php"><span class="k">class</span><span class="nc">UserRegistrationEmail</span><span class="k">extends</span><span class="nx">Notification</span><span class="p">{</span><span class="c1">//
</span><span class="p">}</span></code></pre>
</div>
<p>然后你就可以在注册完成收到一封注册邮件提醒。</p>
<h3>发送通知</h3>
<p>你可以通过 <code>$user-&gt;notify()</code> 发送通知给特定用户，你也可以通过 <code>Notification::route()</code> 发送给任何其他需要通知的地方：</p>
<div class="highlight">
<pre><code class="language-php"><span class="nx">Notification</span><span class="o">::</span><span class="na">route</span><span class="p">(</span><span class="s1">'mail'</span><span class="p">,</span><span class="s1">'taylor@example.com'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">route</span><span class="p">(</span><span class="s1">'nexmo'</span><span class="p">,</span><span class="s1">'5555555555'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">route</span><span class="p">(</span><span class="s1">'slack'</span><span class="p">,</span><span class="s1">'https://hooks.slack.com/services/...'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">notify</span><span class="p">(</span><span class="k">new</span><span class="nx">InvoicePaid</span><span class="p">(</span><span class="nv">$invoice</span><span class="p">));</span></code></pre>
</div>
<h2>Artisan</h2>
<h3>Artisan 命令参数</h3>
<p>当我们创建我们的 Artisan 命令的时候，可以通过 <code>$this-&gt;confirm()</code>, <code>$this-&gt;anticipate()</code>, <code>$this-&gt;choice()</code>  等方法询问并要求输入参数：</p>
<div class="highlight">
<pre><code class="language-php"><span class="c1">// 确认框
</span><span class="k">if</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">confirm</span><span class="p">(</span><span class="s1">'Do you wish to continue?'</span><span class="p">))</span><span class="p">{</span><span class="c1">//
</span><span class="p">}</span><span class="c1">// 附加可选项
</span><span class="nv">$name</span><span class="o">=</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">anticipate</span><span class="p">(</span><span class="s1">'What is your name?'</span><span class="p">,</span><span class="p">[</span><span class="s1">'Taylor'</span><span class="p">,</span><span class="s1">'Dayle'</span><span class="p">]);</span><span class="c1">// 附加默认值
</span><span class="nv">$name</span><span class="o">=</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">choice</span><span class="p">(</span><span class="s1">'What is your name?'</span><span class="p">,</span><span class="p">[</span><span class="s1">'Taylor'</span><span class="p">,</span><span class="s1">'Dayle'</span><span class="p">],</span><span class="nv">$defaultIndex</span><span class="p">);</span></code></pre>
</div>
<h3>维护模式</h3>
<p>页面维护模式实现如下：</p>
<div class="highlight">
<pre><code class="language-bash">php artisan down</code></pre>
</div>
<p>执行上面命令后，再访问站点的时候会得到 503 错误訊息。</p>
<p>你也可以通过提供参数实现而外的效果： - message 参数指定显示訊息 - retry 参数设定页面重载时间 - allow 参数社会请求白名单</p>
<div class="highlight">
<pre><code class="language-bash">php artisan down --message<span class="o">=</span><span class="s2">"Upgrading Database"</span> --retry<span class="o">=</span><span class="m">60</span> --allow<span class="o">=</span>127.0.0.1</code></pre>
</div>
<p>当维护完成，运行一下命令上线吧！</p>
<div class="highlight">
<pre><code class="language-bash">php artisan up</code></pre>
</div>
<h2>数据工厂</h2>
<h3>Factory 的回调方法</h3>
<p>有时候，你某些数据的插入/修改需要基于其他数据的完成，这时你可以通过回调方法实现，例子如下：</p>
<div class="highlight">
<pre><code class="language-php"><span class="nv">$factory</span><span class="o">-&gt;</span><span class="na">afterCreating</span><span class="p">(</span><span class="nx">AppUser</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="k">function</span><span class="p">(</span><span class="nv">$user</span><span class="p">,</span><span class="nv">$faker</span><span class="p">)</span><span class="p">{</span><span class="nv">$user</span><span class="o">-&gt;</span><span class="na">accounts</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">save</span><span class="p">(</span><span class="nx">factory</span><span class="p">(</span><span class="nx">AppAccount</span><span class="o">::</span><span class="na">class</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">make</span><span class="p">());</span><span class="p">});</span></code></pre>
</div>
<h3>通过 Seeds/Factories 生成图片</h3>
<p>Faker能生成的不仅仅是文本，还可以生成指定大小的图像：</p>
<div class="highlight">
<pre><code class="language-php"><span class="nv">$factory</span><span class="o">-&gt;</span><span class="na">define</span><span class="p">(</span><span class="nx">User</span><span class="o">::</span><span class="na">class</span><span class="p">,</span><span class="k">function</span><span class="p">(</span><span class="nx">Faker</span><span class="nv">$faker</span><span class="p">)</span><span class="p">{</span><span class="k">return</span><span class="p">[</span><span class="s1">'name'</span><span class="o">=&gt;</span><span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">name</span><span class="p">,</span><span class="s1">'email'</span><span class="o">=&gt;</span><span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">unique</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">safeEmail</span><span class="p">,</span><span class="s1">'email_verified_at'</span><span class="o">=&gt;</span><span class="nx">now</span><span class="p">(),</span><span class="s1">'password'</span><span class="o">=&gt;</span><span class="nx">bcrypt</span><span class="p">(</span><span class="s1">'password'</span><span class="p">),</span><span class="s1">'remember_token'</span><span class="o">=&gt;</span><span class="nx">Str</span><span class="o">::</span><span class="na">random</span><span class="p">(</span><span class="mi">10</span><span class="p">),</span><span class="s1">'avatar'</span><span class="o">=&gt;</span><span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">image</span><span class="p">(</span><span class="nx">storage_path</span><span class="p">(</span><span class="s1">'images'</span><span class="p">),</span><span class="mi">50</span><span class="p">,</span><span class="mi">50</span><span class="p">)</span><span class="p">];</span><span class="p">});</span></code></pre>
</div>
<h2>日志和调试</h2>
<h3>给日志记录传递参数</h3>
<p>你可以通过 <code>Log::info()</code> 来记录日志，或者 <code>info()</code> 快捷方法可以实现同样的效果。</p>
<div class="highlight">
<pre><code class="language-php"><span class="nx">Log</span><span class="o">::</span><span class="na">info</span><span class="p">(</span><span class="s1">'User failed to login.'</span><span class="p">,</span><span class="p">[</span><span class="s1">'id'</span><span class="o">=&gt;</span><span class="nv">$user</span><span class="o">-&gt;</span><span class="na">id</span><span class="p">]);</span></code></pre>
</div>
<h3>更方便的方法 DD</h3>
<p>你可以直接通过在查询结果之后的 <code>-&gt;dd()</code> 操作来打印结果。</p>
<div class="highlight">
<pre><code class="language-php"><span class="c1">// Instead of
</span><span class="nv">$users</span><span class="o">=</span><span class="nx">User</span><span class="o">::</span><span class="na">where</span><span class="p">(</span><span class="s1">'name'</span><span class="p">,</span><span class="s1">'Taylor'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">();</span><span class="nx">dd</span><span class="p">(</span><span class="nv">$users</span><span class="p">);</span><span class="c1">// Do this
</span><span class="nv">$users</span><span class="o">=</span><span class="nx">User</span><span class="o">::</span><span class="na">where</span><span class="p">(</span><span class="s1">'name'</span><span class="p">,</span><span class="s1">'Taylor'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">dd</span><span class="p">();</span></code></pre>
</div>
<blockquote><p> 讨论请前往 Laravel 论坛：<a href="https://link.zhihu.com/?target=https%3A//learnku.com/laravel/t/45370" 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">5370</span></a></p></blockquote>
</div>
</div>
</article>
<p>The post <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com/software-engineering/laravel/20053/topic-149228467/" data-wpel-link="internal">快速上手 Laravel 的 100 个小技巧</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/19387/topic-137243018/</link>
		
		<dc:creator><![CDATA[marketer]]></dc:creator>
		<pubDate>Fri, 30 Apr 2021 07:39:15 +0000</pubDate>
				<category><![CDATA[Laravel]]></category>
		<category><![CDATA[PHP / Laravel / 全栈]]></category>
		<guid isPermaLink="false">https://hypergrowths.com/software-engineering/laravel/19387/topic-137243018/</guid>

					<description><![CDATA[<p>原文链接：https://learnku.com/laravel/t/43776 讨论请前往专业的 Laravel 开发者论坛：https://learnku.com/Laravel 作为一个以Laravel为主的PHP全栈开发人员，我会经常去寻找一些框架中、可以为我所用的、有效…</p>
<p>The post <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com/software-engineering/laravel/19387/topic-137243018/" 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">
<blockquote><p> 原文链接：<a href="https://link.zhihu.com/?target=https%3A//learnku.com/laravel/t/43776" 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">3776</span></a><br />讨论请前往专业的 Laravel 开发者论坛：<a href="https://link.zhihu.com/?target=https%3A//learnku.com/Laravel" class=" external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external"><span class="invisible">https://</span><span class="visible">learnku.com/Laravel</span></a></p></blockquote>
<p>作为一个以Laravel为主的PHP全栈开发人员，我会经常去寻找一些框架中、可以为我所用的、有效减少开发时间或者减少代码复杂性的方法。</p>
<p>下面是我整理的在平常会经常用到的一些不错的辅助方法。文中方法大都基于Laravel7以及更早的版本。（如果遇到问题，请先检查是否是版本兼容问题）</p>
<p>让我们一探究竟吧 <img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2728.png" alt="✨" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<h3>Str::limit()</h3>
<p>我们的第一个辅助函数 <b>获取一个字符串并用一个设定的字符长度限制截断它</b> 。它有两个必须参数：你想截断的字符串，以及返回的被截断的字符串的字符长度限制。</p>
<div class="highlight">
<pre><code class="language-text">use IlluminateSupportStr;

$truncated = Str::limit('The quick brown fox jumps over the lazy dog', 20);

// The quick brown fox ...</code></pre>
</div>
<p>你也可以传入第三个可选参数来控制返回的字符串后显示什么。</p>
<div class="highlight">
<pre><code class="language-text">use IlluminateSupportStr;

$truncated = Str::limit('The quick brown fox jumps over the lazy dog', 20, '[...]');

// The quick brown fox [...]</code></pre>
</div>
<p>我发现这用于把一大段文本缩短为摘要或文章列表的帖子预览是完美的。</p>
<h3>head()</h3>
<p>这个功能超赞。 一个简单的方法通常由几个嵌套的原始PHP函数组成，head()会<b>返回数组的第一个元素</b>。 由于其全局性和无处不在的性质，我已经在许多不同的应用程序中使用了它。</p>
<div class="highlight">
<pre><code class="language-text">$array = [100, 200, 300];

$first = head($array);

// 100</code></pre>
</div>
<p>想要反着来吗？ 使用<code>last</code>方法可以获取数组的最后一个元素。</p>
<div class="highlight">
<pre><code class="language-text">$array = [100, 200, 300];

$last = last($array);

// 300</code></pre>
</div>
<p>这是关于使用head和last方法的最佳方法，因为它们根本不影响原始数组。</p>
<h3>Str::between()</h3>
<p>顾名思义， Str::between() 会 <b>返回字符串中的内容</b>。如果没有找到指定字符串，返回 <code>null</code> 。</p>
<div class="highlight">
<pre><code class="language-text">use IlluminateSupportStr;

$slice = Str::between('My name is Inigo Montoya.', 'My name is ', '.');

// 'Inigo Montoya'</code></pre>
</div>
<p>我喜欢用这种方式从 <code>()</code> 或 <code>[]</code> 之间获取訊息、返回 url 中的特定部分、甚至是从 html 标签中解析数据。</p>
<h3>blank()</h3>
<p>它 <b>和<code>empty()</code>差不多，但是更好用</b>。它根据你传入的参数是否包含实际数据，来返回一个布尔值。</p>
<div class="highlight">
<pre><code class="language-text">// all of these return true
blank('');
blank('   ');
blank(null);
blank(collect());

// all of these return false
blank(true);
blank(false);
blank(0);</code></pre>
</div>
<p>这个辅助函数在结合表单验证、除去 API 中没有规范输入的数据时，特别有用。 它比 <code>empty(trim())</code> 更好用。</p>
<h3>Str::contains()</h3>
<p>我们期待已久的辅助函数, <b>确定一个字符串中是否包含另一个字符串</b>. 这个问题在 <a href="https://link.zhihu.com/?target=https%3A//stackoverflow.com/questions/4366730/how-do-i-check-if-a-string-contains-a-specific-word" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">StackOverflow</a> 和其他编程论坛上已经被问过很多次了, 因为目前在普通PHP程序中只能使用 <code>strpos</code>.</p>
<div class="highlight">
<pre><code class="language-text">use IlluminateSupportStr;

$contains = Str::contains('My name is Inigo Montoya.', 'Inigo');

// true

$contains = Str::contains('My name is Inigo Montoya.', 'Andrew');

// false</code></pre>
</div>
<p>随着最近的rfc的批准，PHP将很快拥有自己的str_contains方法，这将使该方法过时。不过在此之前，它是Laravel中最有用的辅助函数之一。</p>
<h3>Arr::pluck()</h3>
<p>该方法可以说是我在本文中列出的更强大的方法之一，Arr::pluck <b>遍历多维数组并检索给定键的所有值</b>。</p>
<p>让我们来看一个简单的例子：</p>
<div class="highlight">
<pre><code class="language-text">use IlluminateSupportArr;

$array = [
    ['website' =&gt; ['id' =&gt; 1, 'url' =&gt; 'reddit.com']],
    ['website' =&gt; ['id' =&gt; 2, 'url' =&gt; 'twitter.com']],
    ['website' =&gt; ['id' =&gt; 3, 'url' =&gt; 'dev.to']],
];

$names = Arr::pluck($array, 'website.url');

// ['reddit.com', 'twitter.com', 'dev.to']</code></pre>
</div>
<p>传入一个数组和一个点符号字符串来确定我们想要的键值，然后遍历多维数组，并将指定键所对应值的一维数组返回给我们。</p>
<p>我在返回的API数据中多次使用过该方法（当我觉得不需要使用整个的集合时）。它使获得ID，名称或其他属性的数组变得非常容易，而无需创建整个foreach循环。</p>
<h3>collect()</h3>
<p>一旦发现集合有关的訊息，我就不会停止使用它们。 这可能是我发现自己最常使用的助手函数，它可以让您 <b>将数组转换为<a href="https://link.zhihu.com/?target=https%3A//laravel.com/docs/7.x/collections" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">集合</a></b>。</p>
<p>为什么这很重要？ 因为集合带有大量的<a href="https://link.zhihu.com/?target=https%3A//laravel.com/docs/7.x/collections%23available-methods" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">便捷方法</a>，您可以将它们组合在一起用最简单的闭包参数对数组执行各种过滤，排序和修改等操作。 没有foreach 循环，没有中间变量，只是干净的代码。</p>
<p>看看这个简单的例子：</p>
<div class="highlight">
<pre><code class="language-text">$collection = collect(['Keys', 'Krates']);

return $collection-&gt;map(function ($value) {
    return Str::upper($value);
});

// ['KEYS', 'KRATES']

return $collection-&gt;filter(function ($value) {
    return strlen($value) &gt; 4;
});

// ['Krates']</code></pre>
</div>
<p>老实说，这只是集合的冰山一角。 我在项目中都使用了它们，尤其是当我要处理不是来自数据库模型的庞大而复杂的数据集时。 CSV 数据，外部API请求和目录结构都可以从放入集合中使用。</p>
<p><b>这就是我现在所了解的！</b></p>
<blockquote><p> 原文链接：<a href="https://link.zhihu.com/?target=https%3A//learnku.com/laravel/t/43776" 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">3776</span></a><br />讨论请前往专业的 Laravel 开发者论坛：<a href="https://link.zhihu.com/?target=https%3A//learnku.com/Laravel" class=" external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external"><span class="invisible">https://</span><span class="visible">learnku.com/Laravel</span></a></p></blockquote>
</div>
</div>
</article>
<p>The post <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com/software-engineering/laravel/19387/topic-137243018/" 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 框架的核心：服务容器（Service Container）</title>
		<link>https://hypergrowths.com/software-engineering/laravel/19385/topic-113573141/</link>
		
		<dc:creator><![CDATA[marketer]]></dc:creator>
		<pubDate>Fri, 30 Apr 2021 07:39:09 +0000</pubDate>
				<category><![CDATA[Laravel]]></category>
		<category><![CDATA[PHP / Laravel / 全栈]]></category>
		<guid isPermaLink="false">https://hypergrowths.com/software-engineering/laravel/19385/topic-113573141/</guid>

					<description><![CDATA[<p>原文链接：https://learnku.com/laravel/t/41734 讨论请前往专业的 Laravel 开发者论坛：https://learnku.com/Laravel 在理解服务容器之前，我们需要知道什么是容器，从名称上可以解释这一切，因为容器是我们存储…</p>
<p>The post <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com/software-engineering/laravel/19385/topic-113573141/" data-wpel-link="internal">分解 Laravel 框架的核心：服务容器（Service Container）</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 框架的核心：服务容器（Service Container）</h1>
<div class="Post-Author">
<div class="AuthorInfo"></div>
</div>
</header>
<div class="Post-RichTextContainer">
<div class="RichText ztext Post-RichText">
<blockquote><p> 原文链接：<a href="https://link.zhihu.com/?target=https%3A//learnku.com/laravel/t/41734" 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">1734</span></a><br />讨论请前往专业的 Laravel 开发者论坛：<a href="https://link.zhihu.com/?target=https%3A//learnku.com/Laravel" class=" external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external"><span class="invisible">https://</span><span class="visible">learnku.com/Laravel</span></a></p></blockquote>
<p>在理解服务容器之前，我们需要知道什么是容器，从名称上可以解释这一切，因为容器是我们存储东西的地方，当我们需要时我们从那里获取它。下面是代码範例。</p>
<div class="highlight">
<pre><code class="language-text">class container{

    public $bindings =[];

    public function bind($name, Callable $resource){

       $this-&gt;bindings[$name]=resource;

    }

    public function make($name){

       $this-&gt;bindings[$name]();

    }

}

$container = new container();

$container-&gt;bind('Game',function(){
    return 'Football';
});

print_r($container-&gt;make('Game'));

//输出

'Football'</code></pre>
</div>
<p>正如您所看到的，我创建了一个容器类，其中有两个方法</p>
<p>1) Bind 2) Make</p>
<p>在 bind 方法中将我们的函数注册到一个容器中，然后在 make 方法中调用这个函数。 这是 Laravel 中服务容器的基本概念</p>
<p>正如已经阅读了 Laravel 文档一样，Service Container 帮助我们管理依赖关系。让我们看一个例子</p>
<div class="highlight">
<pre><code class="language-text">app()-&gt;bind('Game',function(){

    return new Game();

});

dd(app()-&gt;make('Game'));

// 输出

Game{}  // class</code></pre>
</div>
<p>在上面的代码中 app()-&gt;bind() 将我们的服务绑定起来。。然后我们就可以调用 make() 方法来使用它，接着我们可以将它作为一个类输出。。但是如果类 Game 依赖于类 Football，如下面的代码所示。它将会有错误抛出</p>
<div class="highlight">
<pre><code class="language-text">Class Game{

    public function __construct(Football $football){

        $this-&gt;football =$football;

    }
}

app()-&gt;bind('Game',function(){

    return new Game();

});

dd(app()-&gt;make('Game'));

// 输出</code></pre>
</div>
<p>将抛出类 football not found 的错误訊息，因此我们要创建一个 football 类，如下代码所示。</p>
<div class="highlight">
<pre><code class="language-text">class Football{

}

Class Game{

    public function __construct(Football $football){

        $this-&gt;football =$football;

    }
}

app()-&gt;bind('Game',function(){

    return new Game(new Football);

});</code></pre>
</div>
<p>但是，如果类 Football 需要依赖一个体育场的类等等，Laravel 都可以通过服务容器处理依赖。</p>
<div class="highlight">
<pre><code class="language-text">class Football{

}

class Game{

    public function __construct(Football $football){
        $this-&gt;football =$football;
    }
}

/*app()-&gt;bind('Game',function(){

    return new Game(new Football);
});*/

dd(resolve('Game'));

// 输出

Game{
  football {}
}</code></pre>
</div>
<p>因此，我们可以说 Service Container 是管理类依赖项和执行依赖项注入的强大工具。。。:)</p>
<blockquote><p> 原文链接：<a href="https://link.zhihu.com/?target=https%3A//learnku.com/laravel/t/41734" 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">1734</span></a><br />讨论请前往专业的 Laravel 开发者论坛：<a href="https://link.zhihu.com/?target=https%3A//learnku.com/Larav" class=" external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external"><span class="invisible">https://</span><span class="visible">learnku.com/Larav</span></a></p></blockquote>
</div>
</div>
</article>
<p>The post <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com/software-engineering/laravel/19385/topic-113573141/" data-wpel-link="internal">分解 Laravel 框架的核心：服务容器（Service Container）</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>23 个你应该知道的 Laravel 面试问题</title>
		<link>https://hypergrowths.com/software-engineering/laravel/19415/topic-112146503/</link>
		
		<dc:creator><![CDATA[marketer]]></dc:creator>
		<pubDate>Fri, 30 Apr 2021 07:39:07 +0000</pubDate>
				<category><![CDATA[Laravel]]></category>
		<category><![CDATA[PHP / Laravel / 全栈]]></category>
		<guid isPermaLink="false">https://hypergrowths.com/software-engineering/laravel/19415/topic-112146503/</guid>

					<description><![CDATA[<p>原文链接：https://learnku.com/laravel/t/41264 讨论请前往专业的 Laravel 开发者论坛：https://learnku.com/Laravel 探索下一次技术面试之前应该了解的前20个 Laravel 面试问题。 Q1：什么是Laravel？ 主题: Lar…</p>
<p>The post <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com/software-engineering/laravel/19415/topic-112146503/" data-wpel-link="internal">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">23 个你应该知道的 Laravel 面试问题</h1>
<div class="Post-Author">
<div class="AuthorInfo"></div>
</div>
</header>
<div class="Post-RichTextContainer">
<div class="RichText ztext Post-RichText">
<blockquote><p> 原文链接：<a href="https://link.zhihu.com/?target=https%3A//learnku.com/laravel/t/41264" 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">1264</span></a><br />讨论请前往专业的 Laravel 开发者论坛：<a href="https://link.zhihu.com/?target=https%3A//learnku.com/Laravel" class=" external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external"><span class="invisible">https://</span><span class="visible">learnku.com/Laravel</span></a></p></blockquote>
<p>探索下一次技术面试之前应该了解的前20个 Laravel 面试问题。</p>
<h3>Q1：什么是Laravel？</h3>
<blockquote><p> 主题: <b>Laravel</b> 难度: <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><b>Laravel</b> 是一个免费的开放源代码 PHP Web 框架，由 Taylor Otwell 创建，旨在遵循模型-视图-控制器(MVC)架构模式开发 Web 应用程序。</p>
<p><b>来源:</b><a href="https://link.zhihu.com/?target=https%3A//codingcompiler.com/laravel-interview-questions-answers/" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">codingcompiler.com</a></p>
<h3>Q2: Laravel 与其他 Php 框架相比有哪些好处？</h3>
<blockquote><p> 主题: <b>Laravel</b> 难度: <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>来源:</b><a href="https://link.zhihu.com/?target=https%3A//www.mytectra.com/interview-question/laravel-interview-questions-and-answers/" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">mytectra.com</a></p>
<h3>Q3：解释 Laravel 中的迁移</h3>
<blockquote><p> 主题: <b>Laravel</b> 难度: <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><b>Laravel Migrations</b> 类似于数据库的版本控制，使团队可以轻松地修改和共享应用程序的数据库架构。迁移通常与 Laravel 的架构生成器搭配使用，以轻松构建应用程序的数据库架构。</p>
<p><b>来源：</b><a href="https://link.zhihu.com/?target=http%3A//www.laravelinterviewquestions.com/laravel-interview-questions-and-answers/page/4%23sthash.pQAzAunW.dpbs" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">laravelinterviewquestions.com</a></p>
<h3>Q4：Facade Pattern 有什么用？</h3>
<blockquote><p> 主题: <b>Laravel</b> 难度: <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><b>Facades</b> 为应用程序的服务容器中可用的类提供了一个 <i>静态</i> 接口。Laravel facades 作为服务容器中基础类的<i>静态代理</i>，提供了简洁、表达性强的语法的优势，同时保持了比传统静态方法更高的可测试性和灵活性。</p>
<p>所有的 Laravel facades 都是在 <code>IlluminateSupportFacades</code> 命名空间中定义。 查看:</p>
<div class="highlight">
<pre><code class="language-text">use IlluminateSupportFacadesCache;

Route::get('/cache', function () {
    return Cache::get('key');
});</code></pre>
</div>
<p><b>来源：</b><a href="https://link.zhihu.com/?target=https%3A//laravel.com/docs/5.6/facades" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">laravel.com</a></p>
<h3>Q5：什么是服务容器？</h3>
<blockquote><p> 主题: <b>Laravel</b> 难度: <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 <b>服务容器</b> 是用于管理类依赖性和执行依赖性注入的工具。</p>
<p><b>来源：</b><a href="https://link.zhihu.com/?target=https%3A//laravel.com/docs/5.7/eloquent%23query-scopes" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">laravel.com</a></p>
<h3>Q6：什么是 Eloquent Models？</h3>
<blockquote><p> 主题: <b>Laravel</b> 难度: <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 实现，用于处理数据库。每个数据库表都有一个对应的<b>模型</b>，用于与该表进行交互。通过模型，您可以查询表中的数据，以及将新记录插入表中。</p>
<p><b>来源：</b><a href="https://link.zhihu.com/?target=https%3A//laravel.com/docs/5.7/eloquent" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">laravel.com</a></p>
<h3>Q7：什么是Laravel事件？</h3>
<blockquote><p> 主题: <b>Laravel</b> 难度: <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 事件提供了一个简单的<b>观察者模式</b>实现，允许订阅和监听应用程序中的事件。事件是程序检测并处理的事故或事情。</p>
<p>以下是 Laravel 中的一些事件範例：</p>
<ul>
<li>新用户注册</li>
<li>发布新评论</li>
<li>用户登录/注销</li>
<li>添加了新产品。</li>
</ul>
<p><b>来源：</b><a href="https://link.zhihu.com/?target=https%3A//www.mytectra.com/interview-question/laravel-interview-questions-and-answers/" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">mytectra.com</a></p>
<h3>Q8：你对 Laravel 中的查询生成器了解多少？</h3>
<blockquote><p> 主题: <b>Laravel</b> 难度: <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>Source:</b><a href="https://link.zhihu.com/?target=https%3A//laravel.com/docs/5.7/queries%23raw-expressions" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">laravel.com</a></p>
<h3>Q9：如何生成迁移？</h3>
<blockquote><p> 主题: <b>Laravel</b> 难度: <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><b>迁移</b>就像您数据库的版本控制一样，使您的团队可以轻松地修改和共享应用程序的数据库架构。迁移通常与 Laravel 的架构构建器搭配使用，以轻松构建应用程序的数据库架构。</p>
<p>要创建迁移，使用 <code>make：migration</code> Artisan 命令：</p>
<div class="highlight">
<pre><code class="language-text">php artisan make:migration create_users_table</code></pre>
</div>
<p>新的迁移将放置在您的 <code>database/migrations</code> 目录中。每个迁移文件名都包含一个时间戳，该时间戳使 Laravel 可以确定迁移的顺序。</p>
<p><b>来源：</b><a href="https://link.zhihu.com/?target=https%3A//laravel.com/docs/5.7/migrations" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">laravel.com</a></p>
<h3>Q10：如何 mock 一个静态 facade 方法？</h3>
<blockquote><p> 主题：<b>Laravel</b> 难度：<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 是<i>可被 mock 的</i>。我们可以使用 <code>shouldReceive</code> 方法 mock 对静态外观方法的调用，该方法将返回 <code>Mockery</code> 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>来源：</b><a href="https://link.zhihu.com/?target=https%3A//laravel.com/docs/5.7/mocking" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">laravel.com</a></p>
<h3>Q11：Eager Loading 有什么好处，何时使用？</h3>
<blockquote><p> 主题: <b>Laravel</b> 难度: <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 减轻了 <code>N + 1</code> 查询的问题。我们可以使用 Eager Loading 将此操作减少为仅2个查询。</p>
<p><b>来源：</b><a href="https://link.zhihu.com/?target=https%3A//www.fullstack.cafe/" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">FullStack.Cafe</a></p>
<h3>Q12：本地作用域有何用？</h3>
<blockquote><p> 主题: <b>Laravel</b> 难度: <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><b>Scopes</b> 允许您轻松地在模型中复用查询逻辑。要定义 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。<b>Dynamic scopes</b> 接受查询参数：</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>来源：</b><a href="https://link.zhihu.com/?target=https%3A//laravel.com/docs/5.0/eloquent%23query-scopes" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">laravel.com</a></p>
<h3>Q13：Laravel中的路由命名是什么？</h3>
<blockquote><p> Topic: <b>Laravel</b> Difficulty: <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>来源：</b><a href="https://link.zhihu.com/?target=http%3A//www.laravelinterviewquestions.com/laravel-interview-questions-and-answers/page/10%23sthash.6MpaOmkG.dpbs" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">laravelinterviewquestions.com</a></p>
<h3>Q14：Laravel中的闭包是什么？</h3>
<blockquote><p> 主题：<b>Laravel</b> 难度：<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>来源：</b><a href="https://link.zhihu.com/?target=https%3A//stackoverflow.com/questions/47348081/what-is-closure-in-laravel" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">stackoverflow.com</a></p>
<h3>Q15：列出 Laravel 中查询构建器提供的一些聚合方法？</h3>
<blockquote><p> 主题: <b>Laravel</b> 难度: <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>来源：</b><a href="https://link.zhihu.com/?target=http%3A//www.laravelinterviewquestions.com/laravel-interview-questions-and-answers/page/3%23sthash.Pa7vkxua.dpbs" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">laravelinterviewquestions.com</a></p>
<h3>Q16：什么是 Laravel 中的反向路由？</h3>
<blockquote><p> 主题：<b>Laravel</b> 难度：<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>来源：</b><a href="https://link.zhihu.com/?target=https%3A//stackoverflow.com/questions/30287896/rollback-one-specific-migration-in-laravel" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">stackoverflow.com</a></p>
<h3>Q17: ：让我们为 PHP 创建枚举，提供一些代码範例。</h3>
<blockquote><p> 主题: <b>PHP</b> 难度: <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>
<hr>
<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>来源：</b><a href="https://link.zhihu.com/?target=https%3A//stackoverflow.com/questions/254514/php-and-enumerations" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">stackoverflow.com</a></p>
<h3>Q18：什么是PHP自动加载类？</h3>
<blockquote><p> 主题: <b>PHP</b> 难度: <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中的 <code>spl_autoload_register()</code>函数可以注册任意数量的自动加载器，即使未定义类和接口也可以自动加载。</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。<code>spl_autoload_register()</code> 函数将自动加载 Class1.php 和 Class2.php。</p>
<p><b>来源：</b><a href="https://link.zhihu.com/?target=https%3A//github.com/Bootsity/cracking-php-interviews-book" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">github.com/Bootsity</a></p>
<h3>Q19：PHP是否支持方法重载？</h3>
<blockquote><p> 主题：<b>PHP</b> 难度：<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><b>方法重载</b>是使用具有不同签名的相同方法名称的现象。PHP 中函数签名仅基于它们的名称，并且不包含参数列表，因此不能有两个具有相同名称的函数，所以 PHP 不支持方法重载。</p>
<p>但是，您可以声明一个<b>可变函数</b>，它接受可变数量的参数。您可以使用 <code>func_num_args()</code> 和 <code>func_get_arg()</code> 来传递参数并正常使用它们。</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>来源：</b><a href="https://link.zhihu.com/?target=https%3A//github.com/Bootsity/cracking-php-interviews-book" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">github.com/Bootsity</a></p>
<h3>Q20：Laravel 中为什么需要 Traits？</h3>
<blockquote><p> 主题: <b>Laravel</b> 难度: <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><b>Traits</b> 已被添加到 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>来源：</b><a href="https://link.zhihu.com/?target=https%3A//www.conetix.com.au/blog/simple-guide-using-traits-laravel-5" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">conetix.com.au</a></p>
<h3>Q21：PHP 中的 Autoloader 是什么？</h3>
<blockquote><p> 主题: <b>Laravel</b> 难度: <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>
<ul>
<li><b>PSR-4</b> 将支持更简单的文件夹结构，但是将使我们仅通过查看完全限定的名称就无法知道类的确切路径。</li>
<li><b>PSR-0</b> 在硬盘驱动器上比较混乱，但是支持恋旧的开发人员(类名下划线用户)，并帮助我们通过以下方式辨别类的位置：看它的名字。</li>
</ul>
<p><b>来源：</b><a href="https://link.zhihu.com/?target=https%3A//www.sitepoint.com/battle-autoloaders-psr-0-vs-psr-4/" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">sitepoint.com</a></p>
<h3>Q22：在 PHP 中 yield 是什么意思？</h3>
<blockquote><p> 主题: <b>PHP</b> 难度: <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>解释此代码以及 <code>yield</code> 的作用：</p>
<div class="highlight">
<pre><code class="language-text">function a($items) {
    foreach ($items as $item) {
        yield $item + 1;
    }
}</code></pre>
</div>
<hr>
<p><code>yield</code> 关键字从生成器函数返回数据。生成器函数实际上是编写 <code>Iterator</code> 的更紧凑和有效的方式。它允许您定义一个函数，该函数将在您遍历该函数时计算并返回值。</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>只有一个区别，<code>a()</code> 返回一个 <code>generator</code>，而 <code>b()</code> 只是一个简单的 <code>数组</code>。而且两者都可以被迭代。</p>
<p>函数的生成器版本未分配完整的数组，因此对内存的需求较少。生成器可用于解决内存限制。由于生成器仅按需计算其 <i>yielded</i> 值，因此它们用于代替计算成本昂贵或无法一次性计算的序列很有用。</p>
<p><b>来源：</b><a href="https://link.zhihu.com/?target=https%3A//stackoverflow.com/questions/17483806/what-does-yield-mean-in-php" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">stackoverflow.com</a></p>
<h3>Q23：$$$ 在 PHP 中是什么意思？</h3>
<blockquote><p> 主题: <b>PHP</b> 难度: <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>类似 <code>$$variable</code> 的语法称为可变变量。</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>
<p><b>来源：</b><a href="https://link.zhihu.com/?target=https%3A//stackoverflow.com/questions/2715654/what-does-dollar-dollar-or-double-dollar-mean-in-php" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">guru99.com</a></p>
<blockquote><p> 原文链接：<a href="https://link.zhihu.com/?target=https%3A//learnku.com/laravel/t/41264" 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">1264</span></a><br />讨论请前往专业的 Laravel 开发者论坛：<a href="https://link.zhihu.com/?target=https%3A//learnku.com/Laravel" class=" external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external"><span class="invisible">https://</span><span class="visible">learnku.com/Laravel</span></a></p></blockquote>
</div>
</div>
</article>
<p>The post <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com/software-engineering/laravel/19415/topic-112146503/" data-wpel-link="internal">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 7 正式发布，路由速度提高两倍</title>
		<link>https://hypergrowths.com/software-engineering/laravel/18839/topic-110800331/</link>
		
		<dc:creator><![CDATA[marketer]]></dc:creator>
		<pubDate>Fri, 30 Apr 2021 07:18:43 +0000</pubDate>
				<category><![CDATA[Laravel]]></category>
		<category><![CDATA[PHP / Laravel / 全栈]]></category>
		<guid isPermaLink="false">https://hypergrowths.com/software-engineering/laravel/18839/topic-110800331/</guid>

					<description><![CDATA[<p>原文链接：https://learnku.com/laravel/t/41076 讨论请前往专业的 Laravel 开发者论坛：https://learnku.com/Laravel Laravel 7 现在 发布并包括许多新功能，包括 Laravel Airlock，更快的路由速度，自定义 Eloqu…</p>
<p>The post <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com/software-engineering/laravel/18839/topic-110800331/" data-wpel-link="internal">Laravel 7 正式发布，路由速度提高两倍</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 7 正式发布，路由速度提高两倍</h1>
<div class="Post-Author">
<div class="AuthorInfo"></div>
</div>
</header>
<div class="Post-RichTextContainer">
<div class="RichText ztext Post-RichText">
<blockquote><p> 原文链接：<a href="https://link.zhihu.com/?target=https%3A//learnku.com/laravel/t/41076" 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">1076</span></a><br />讨论请前往专业的 Laravel 开发者论坛：<a href="https://link.zhihu.com/?target=https%3A//learnku.com/Laravel" class=" external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external"><span class="invisible">https://</span><span class="visible">learnku.com/Laravel</span></a></p></blockquote>
<p>Laravel 7 现在<a href="https://link.zhihu.com/?target=https%3A//learnku.com/docs/laravel/7.x/releases" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">发布</a>并包括许多新功能，包括 Laravel Airlock，更快的路由速度，自定义 Eloquent Casts，Blade 组件标签，流畅的字符串操作，新的 HTTP 客户端，CORS 支持以及更多功能。</p>
<p>在我们介绍新功能之前，我们要指出的是，从版本 6 开始，Laravel 现在遵循 semver，并将每六个月发布一个新的主要版本。您可以查看<a href="https://link.zhihu.com/?target=https%3A//learnku.com/laravel/wikis/25513" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">发布过程在这里</a>。</p>
<h2>Laravel Airlock</h2>
<p>Laravel Airlock 为 SPA (单页应用程序)、移动应用程序和基于令牌的简单 API 提供了轻巧的身份验证系统。 Airlock 允许您的应用程序的每个用户为其帐户生成多个 API 令牌。这些令牌可以被授予功能 / 作用域，指定了允许令牌执行哪些动作。</p>
<h2>自定义 Eloquent 转换</h2>
<p>Laravel 有多种内置的，有用的强制类型。但是，您有时可能需要定义自己的强制类型。现在，您可以通过定义实现 CastsAttributes 接口的类来实现此目的。</p>
<p>实现此接口的类必须定义 get 和 set 方法。 get 方法负责将数据库中的原始值转换为强制转换值，而 set 方法应将强制值转换为可以存储在数据库中的原始值。</p>
<h2>Blade 组件标签 &amp; 改进</h2>
<p>Blade 组件已进行了大修，以允许基于标签的渲染，属性管理，组件类，内联视图组件等。由于 Blade 组件的改动非常广泛，因此请查阅完整的 Blade 组件文档以了解此功能。</p>
<h2>HTTP 客户端</h2>
<p>现在，Laravel 为 Guzzle HTTP 客户端相关提供了一种表达能力极强的 API，使您可以快速发出 HTTP 请求以与其他 Web 应用程序进行通信。<a href="https://link.zhihu.com/?target=https%3A//learnku.com/laravel/t/40771" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">Laravel 的 Guzzle 相关 wrapper</a> 专注于其最常见的用例和良好的开发人员体验。</p>
<h2>路由缓存速度改进</h2>
<p>Laravel 7 提供了一种新方法，用于匹配已使用 Artisan 的 route:cache 命令已缓存的路由。在大型应用程序 (例如，具有 800 条或更多路由的应用程序) 上，这些改进可以使简单的 “Hello World” 基准每秒请求速度提高 2 倍，而无需更改您的应用程序。</p>
<h2>了解有关 Laravel v7 的更多訊息…</h2>
<p>这些只是 Laravel 7 所有新功能中的少量，要查看完整列表，请查看<a href="https://link.zhihu.com/?target=https%3A//learnku.com/docs/laravel/7.x/releases" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">发行说明</a>以及<a href="https://link.zhihu.com/?target=https%3A//learnku.com/docs/laravel/7.x/upgrade" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">升级指南</a>。</p>
<p>Taylor 还在<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>上提供了其中一些功能的演练，如果你想看的话现在还可以买票，以及<a href="https://link.zhihu.com/?target=https%3A//laracasts.com/series/whats-new-in-laravel-7" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">Laracasts</a>关于此次发布也有一个新系列。</p>
<p>与所有版本一样，众人拾柴成就了 Laravel，我们要感谢做出贡献的每一个提交 PR、分享想法以及使用框架的人。Laravel 是一支真正的全球团队。</p>
<blockquote><p> 原文链接：<a href="https://link.zhihu.com/?target=https%3A//learnku.com/laravel/t/41076" 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">1076</span></a><br />讨论请前往专业的 Laravel 开发者论坛：<a href="https://link.zhihu.com/?target=https%3A//learnku.com/Laravel" class=" external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external"><span class="invisible">https://</span><span class="visible">learnku.com/Laravel</span></a></p></blockquote>
</div>
</div>
</article>
<p>The post <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com/software-engineering/laravel/18839/topic-110800331/" data-wpel-link="internal">Laravel 7 正式发布，路由速度提高两倍</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>[扩展推荐] Laravue —— 漂亮的 Laravel 管理界面</title>
		<link>https://hypergrowths.com/software-engineering/laravel/18831/topic-94765430/</link>
		
		<dc:creator><![CDATA[marketer]]></dc:creator>
		<pubDate>Fri, 30 Apr 2021 07:18:16 +0000</pubDate>
				<category><![CDATA[Laravel]]></category>
		<category><![CDATA[PHP / Laravel / 全栈]]></category>
		<guid isPermaLink="false">https://hypergrowths.com/software-engineering/laravel/18831/topic-94765430/</guid>

					<description><![CDATA[<p>文章转发自专业的Laravel开发者社区，原始链接：https://learnku.com/laravel/t/37417 介绍几个月前我尝试为我的项目寻找新的解决方案, 我已经使用 Vue 构建了一个 单页应用 (使用这个 非常棒的框架, 使用 Laravel…</p>
<p>The post <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com/software-engineering/laravel/18831/topic-94765430/" data-wpel-link="internal">[扩展推荐] Laravue —— 漂亮的 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">[扩展推荐] Laravue —— 漂亮的 Laravel 管理界面</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/37417" 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/3</span><span class="invisible">7417</span></a></p></blockquote>
<h3>介绍</h3>
<p>几个月前我尝试为我的项目寻找新的解决方案, 我已经使用 Vue  构建了一个 单页应用 (使用这个 <a href="https://link.zhihu.com/?target=https%3A//github.com/PanJiaChen/vue-element-admin" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">非常棒的框架</a>, 使用 Laravel <a href="https://link.zhihu.com/?target=https%3A//lumen.laravel.com/" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">Lumen</a> 作为 API 网关, 使用 Laravel <a href="https://link.zhihu.com/?target=https%3A//laravel.com/docs/5.7/passport" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">Passport</a> 作为 SSO 服务器)。经过几周的工作, 我发现那个框架有一些限制, 尤其是在部署和难以开源方面 (因为涉及许多组件, CORS 设置 ...)。突然有一天我有了一个新的想法:</p>
<blockquote><p> 为什么我们不用 Laravel 内置的 VueJS 去构建 SPA 仪表板?</p></blockquote>
<p>Laravel + VueJS = <a href="https://link.zhihu.com/?target=https%3A//github.com/tuandm/laravue" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">Laravue</a></p>
<p>例子: <a href="https://link.zhihu.com/?target=https%3A//laravue.dev/" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">https://laravue.dev</a> 文档: <a href="https://link.zhihu.com/?target=https%3A//doc.laravue.dev/" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">https://doc.laravue.dev</a></p>
<p class="ztext-empty-paragraph"></p>
<figure data-size="normal"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-60700f1de3b854b3417517628602b67d_r.jpg" data-caption="" data-size="normal" data-rawwidth="880" data-rawheight="480" class="origin_image zh-lightbox-thumb" width="880" data-original="https://pic2.zhimg.com/v2-60700f1de3b854b3417517628602b67d_b.jpg" title="v2-60700f1de3b854b3417517628602b67d_r"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-60700f1de3b854b3417517628602b67d_r.jpg" data-caption="" data-size="normal" data-rawwidth="880" data-rawheight="480" class="origin_image zh-lightbox-thumb lazy" width="880" data-original="data:image/svg+xml;utf8,&lt;svg%20xmlns='http://www.w3.org/2000/svg'%20width='880'%20height='480'&gt;&lt;/svg&gt;" data-actualsrc="https://pic2.zhimg.com/v2-60700f1de3b854b3417517628602b67d_b.jpg" title="v2-60700f1de3b854b3417517628602b67d_r"></figure>
<p class="ztext-empty-paragraph"></p>
<p><a href="https://link.zhihu.com/?target=https%3A//github.com/tuandm/laravue" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">Laravue</a> 是一个受 <a href="https://link.zhihu.com/?target=https%3A//github.com/PanJiaChen/vue-element-admin" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">vue-element-admin</a> 启发的漂亮的仪表盘。它提供了所有构建企业应用所必须的组件, 管理员可以控制业务并管理其他人。 我的计划是将 Laravel/Vue 最新的 技术/库/组件 应用于该项目, 并且易于使用. 在这个範例中, API 由 Laravel 提供, 大多数 API 都是假的 - 但是易于实现。</p>
<h3>开始</h3>
<div class="highlight">
<pre><code class="language-text"># 使用 composer 克隆项目
composer create-project tuandm/laravue
cd laravue

# 迁移数据 (在 .env 文件设置了数据库訊息之后)
php artisan migrate --seed

# 生成 JWT 秘钥
php artisan jwt:secret

# 安装依赖
yarn install

# 构建(开发环境)
yarn run dev # 或者 yarn run watch

# 启动本地服务
php artisan serve</code></pre>
</div>
<h3>下一步</h3>
<ul>
<li> 这个项目正在大力开发中, 还没有被构建为 Laravel 插件(应该是这样)。下一步将会将此项目构建为一个独立的 Laravel 插件, 使得现有的 Laravel 网站可以很好的集成。</li>
<li> 提供完善的文档和严格的代码规范。PHP/Laravel 有优秀的代码规范 <a href="https://link.zhihu.com/?target=https%3A//www.php-fig.org/psr/" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">PSR</a> , VueJS 也有很好的标准 <a href="https://link.zhihu.com/?target=https%3A//vuejs.org/v2/style-guide/" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">这里</a> 但这太基础了, 还不够。</li>
<li> 完善的测试。</li>
</ul>
</div>
</div>
</article>
<p>The post <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com/software-engineering/laravel/18831/topic-94765430/" data-wpel-link="internal">[扩展推荐] Laravue —— 漂亮的 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 传送到 vue 的四种方式</title>
		<link>https://hypergrowths.com/software-engineering/laravel/18844/topic-87086010/</link>
		
		<dc:creator><![CDATA[marketer]]></dc:creator>
		<pubDate>Fri, 30 Apr 2021 07:18:13 +0000</pubDate>
				<category><![CDATA[Laravel]]></category>
		<category><![CDATA[PHP / Laravel / 全栈]]></category>
		<guid isPermaLink="false">https://hypergrowths.com/software-engineering/laravel/18844/topic-87086010/</guid>

					<description><![CDATA[<p>文章转发自专业的Laravel开发者社区，原始链接：https://learnku.com/laravel/t/34951 在过去的两三年里，我一直在研究同时使用 Vue 和 Laravel 的项目，在每个项目开发的开始阶段，我必须问自己 “我将如何将数据…</p>
<p>The post <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com/software-engineering/laravel/18844/topic-87086010/" data-wpel-link="internal">将数据从 Laravel 传送到 vue 的四种方式</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 传送到 vue 的四种方式</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/34951" 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/3</span><span class="invisible">4951</span></a></p></blockquote>
<p>在过去的两三年里，我一直在研究同时使用 Vue 和 Laravel 的项目，在每个项目开发的开始阶段，我必须问自己 “我将如何将数据从 Laravel 传递到 Vue ？”。这适用于 Vue 前端组件与Blade模板紧密耦合的两个应用程序，以及运行完全独立于 Laravel 后端的单页应用程序。</p>
<p>这里有四种不同的方法从一个到另一个获取数据。</p>
<h2>直接回显到数据对象或组件属性中</h2>
<p class="ztext-empty-paragraph"></p>
<figure data-size="normal"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-10dc760f20c097e20fe557c655dec766_r.jpg" data-caption="" data-size="normal" data-rawwidth="1240" data-rawheight="640" class="origin_image zh-lightbox-thumb" width="1240" data-original="https://pic3.zhimg.com/v2-10dc760f20c097e20fe557c655dec766_b.jpg" title="v2-10dc760f20c097e20fe557c655dec766_r"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-10dc760f20c097e20fe557c655dec766_r.jpg" data-caption="" data-size="normal" data-rawwidth="1240" data-rawheight="640" class="origin_image zh-lightbox-thumb lazy" width="1240" data-original="data:image/svg+xml;utf8,&lt;svg%20xmlns='http://www.w3.org/2000/svg'%20width='1240'%20height='640'&gt;&lt;/svg&gt;" data-actualsrc="https://pic3.zhimg.com/v2-10dc760f20c097e20fe557c655dec766_b.jpg" title="v2-10dc760f20c097e20fe557c655dec766_r"></figure>
<p class="ztext-empty-paragraph"></p>
<ul>
<li><b>赞成</b>: 简单明了</li>
<li><b>反对</b>: 必须与嵌入到Blade模板中的Vue应用程序一起使用</li>
</ul>
<p>可以说是将数据从 Laravel 应用程序移动到 Vue 前端的最简单方法。使用上面的任何一种方法，您都可以将 JSON 编码的数据回送给您的应用程序或其组件。</p>
<p>然而，最大的缺点是可扩展性。您的 JavaScript 需要直接暴露在模板文件中，以便引擎可以呈现您的数据。如果您使用 Vue 向 Laravel 站点的页面或区域添加一些基本的交互，这应该不是问题，但是您很容易就会遇到将数据强制放入压缩脚本的困难。</p>
<p class="ztext-empty-paragraph"></p>
<figure data-size="normal"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-136fbd530ff98219fb952cbf764a7969_r.jpg" data-caption="" data-size="normal" data-rawwidth="1240" data-rawheight="359" class="origin_image zh-lightbox-thumb" width="1240" data-original="https://pic2.zhimg.com/v2-136fbd530ff98219fb952cbf764a7969_b.jpg" title="v2-136fbd530ff98219fb952cbf764a7969_r"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-136fbd530ff98219fb952cbf764a7969_r.jpg" data-caption="" data-size="normal" data-rawwidth="1240" data-rawheight="359" class="origin_image zh-lightbox-thumb lazy" width="1240" data-original="data:image/svg+xml;utf8,&lt;svg%20xmlns='http://www.w3.org/2000/svg'%20width='1240'%20height='359'&gt;&lt;/svg&gt;" data-actualsrc="https://pic2.zhimg.com/v2-136fbd530ff98219fb952cbf764a7969_b.jpg" title="v2-136fbd530ff98219fb952cbf764a7969_r"></figure>
<p class="ztext-empty-paragraph"></p>
<p>对于 Laravel 5.5+ 使用 json 指令：</p>
<p>使用自定义组件和 Laravel 自身的 <code>json</code> blade指令可以让您轻松地将数据移动到道具中。此方法允许您划分 Vue 代码，将脚本与 Webpack 或 Mix 捆绑在一起，同时仍可以直接向其中注入数据。</p>
<h2>将属性作为全局窗口注入</h2>
<p class="ztext-empty-paragraph"></p>
<figure data-size="normal"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-773d043bee9c9ee5f19b8b9ac96d8a96_r.jpg" data-caption="" data-size="normal" data-rawwidth="1240" data-rawheight="471" class="origin_image zh-lightbox-thumb" width="1240" data-original="https://pic3.zhimg.com/v2-773d043bee9c9ee5f19b8b9ac96d8a96_b.jpg" title="v2-773d043bee9c9ee5f19b8b9ac96d8a96_r"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-773d043bee9c9ee5f19b8b9ac96d8a96_r.jpg" data-caption="" data-size="normal" data-rawwidth="1240" data-rawheight="471" class="origin_image zh-lightbox-thumb lazy" width="1240" data-original="data:image/svg+xml;utf8,&lt;svg%20xmlns='http://www.w3.org/2000/svg'%20width='1240'%20height='471'&gt;&lt;/svg&gt;" data-actualsrc="https://pic3.zhimg.com/v2-773d043bee9c9ee5f19b8b9ac96d8a96_b.jpg" title="v2-773d043bee9c9ee5f19b8b9ac96d8a96_r"></figure>
<p class="ztext-empty-paragraph"></p>
<ul>
<li><b>赞成</b>: 在整个Vue应用程序和任何其他脚本中全局可用</li>
<li><b>反对</b>: 可能很混乱，通常不建议用于大型数据集</li>
</ul>
<p>虽然这看起来有点老生常谈，但将数据添加到窗口对象中可以轻松地创建全局变量，这些变量可以从应用程序中使用的任何其他脚本或组件访问。在过去，我用它作为存储和访问 API 基 URL、公钥、特定模型 ID 和各种其他需要在整个前端使用的小数据项的方法。</p>
<p>不过，使用此方法有一点需要注意，这就是访问 Vue 组件内部数据的方式。在模板内部，您将无法使用以下内容，因为 Vue 假定您尝试访问的窗口对象位于同一组件内：</p>
<div class="highlight">
<pre><code class="language-text">// 不会起作用
&lt;template&gt;
    &lt;div v-if="window.showSecretWindow"&gt;
        &lt;h1&gt;这是个秘密窗口，别告诉任何人！&lt;/h1&gt;
    &lt;/div&gt;
&lt;/template&gt;</code></pre>
</div>
<p>相反，您需要使用返回值的计算方法：</p>
<div class="highlight">
<pre><code class="language-text">// 会起作用
&lt;template&gt;
    &lt;div v-if="showSecretWindow"&gt;
        &lt;h1&gt;这是个秘密窗口，别告诉任何人！&lt;/h1&gt;
    &lt;/div&gt;
&lt;/template&gt;
&lt;script&gt;
    export default {
        computed: {
            showSecretWindow() {
                return window.showSecretWindow;
            }
        }
    }
&lt;/script&gt;</code></pre>
</div>
<p>如果这个方法的用例是较小的字符串或数值，并且使用 Laravel自身的 mix 来编译，那么事情实际上会变得非常简单。您可以使用 process.env 对象引用 JavaScript 中 <code>.env</code> 文件中的值。例如，如果我的环境变量文件中有 <code>API_DOMAIN=example.com</code>，我可以在我的 Vue 组件（或使用 mix 编译的其他 JavaScript ）中使用<code>process.env.API_DOMAIN</code>。</p>
<h2>将 API 与 Laravel 自身的 web 中间件和 CSRF 令牌一起使用</h2>
<p class="ztext-empty-paragraph"></p>
<figure data-size="normal"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-a2db05e78849804a911c9e86437d3480_r.jpg" data-caption="" data-size="normal" data-rawwidth="1240" data-rawheight="528" class="origin_image zh-lightbox-thumb" width="1240" data-original="https://pic1.zhimg.com/v2-a2db05e78849804a911c9e86437d3480_b.jpg" title="v2-a2db05e78849804a911c9e86437d3480_r"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-a2db05e78849804a911c9e86437d3480_r.jpg" data-caption="" data-size="normal" data-rawwidth="1240" data-rawheight="528" class="origin_image zh-lightbox-thumb lazy" width="1240" data-original="data:image/svg+xml;utf8,&lt;svg%20xmlns='http://www.w3.org/2000/svg'%20width='1240'%20height='528'&gt;&lt;/svg&gt;" data-actualsrc="https://pic1.zhimg.com/v2-a2db05e78849804a911c9e86437d3480_b.jpg" title="v2-a2db05e78849804a911c9e86437d3480_r"></figure>
<p class="ztext-empty-paragraph"></p>
<ul>
<li><b>赞成</b>: 易于启动，非常适合单页应用程序</li>
<li><b>反对</b>: 要求前端由 Blade 模板呈现</li>
</ul>
<p>对我来说，这个解决方案是 Vue 前端 + Laravel 后端世界中最简单的入门方法。 Laravel 提供了两个不同的路由文件：web.php 和 api.php。它们被拉入并通过应用程序<b>Providers</b>目录中的 <code>RouteServiceProvider.php</code> 文件映射。默认情况下，web 组的中间件设置为 web，api 组的中间件设置为api。</p>
<p>追溯到 <code>app/Http/Kernel.php</code>；您会注意到，在第30行左右，有两个组被映射到一个数组中，这个 web 组包含会话、 cookie 加密和 CSRF 令牌验证等内容。同时，api 组只有一个基本的限制和一些绑定。如果您的目标只是通过一个基本的、轻量级的 api 将訊息拉入 Vue ，而这个 api 不需要身份验证或 post 请求，那么您可以到此为止。否则，可以进行一次修改，以确保在几秒钟内与 Vue 完全兼容。</p>
<p>回到上面的  <code>RouteServiceProvider</code>, 交换出 <b>web</b> 方法中的 <b>api</b> 中间件。我们为什么要这样做？这样做有什么作用吗？它使我们通过 api 拉入的路由也可以包含应用程序的常规网络路由通常会使用到的所有会话标量和令牌。当使用 axios 或者其他异步 JavaScript http 调用的时候，我们可以在后端使 Auth::user() 或者其他的验证技术，而默认的 api 就无法做到这些。</p>
<p>这个方法唯一警告的是，你必须使用 Laravel 和 一个 blade 模板来渲染前端。这样框架可以将必要的会话令牌和变量注入到请求当中。</p>
<h2>使用 JWT 认证的 API 调用</h2>
<p class="ztext-empty-paragraph"></p>
<figure data-size="normal"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-6386d9b06bb95d8c1eacb00485d2a960_r.jpg" data-caption="" data-size="normal" data-rawwidth="1240" data-rawheight="556" class="origin_image zh-lightbox-thumb" width="1240" data-original="https://pic1.zhimg.com/v2-6386d9b06bb95d8c1eacb00485d2a960_b.jpg" title="v2-6386d9b06bb95d8c1eacb00485d2a960_r"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-6386d9b06bb95d8c1eacb00485d2a960_r.jpg" data-caption="" data-size="normal" data-rawwidth="1240" data-rawheight="556" class="origin_image zh-lightbox-thumb lazy" width="1240" data-original="data:image/svg+xml;utf8,&lt;svg%20xmlns='http://www.w3.org/2000/svg'%20width='1240'%20height='556'&gt;&lt;/svg&gt;" data-actualsrc="https://pic1.zhimg.com/v2-6386d9b06bb95d8c1eacb00485d2a960_b.jpg" title="v2-6386d9b06bb95d8c1eacb00485d2a960_r"></figure>
<p class="ztext-empty-paragraph"></p>
<ul>
<li><b>赞成</b>: 最安全和解耦的选项</li>
<li><b>反对</b>: 需要安装以及配置第三方程序包</li>
</ul>
<p><b>J</b>SON <b>W</b>eb <b>T</b>okens 是安全的，易于使用的方法来锁定对API 端点的访问，并使用了 Tymon’s <b><a href="https://link.zhihu.com/?target=https%3A//github.com/tymondesigns/jwt-auth" class=" wrap external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">jwt-auth</a></b> 扩展包，在这个基础上，用来构建新的项目或者在现有的 Laravel 应用中使用绝对是一件简单的事情。</p>
<p>要在 API 上安装和配置此功能，只需要几个简单的步骤：</p>
<ol>
<li>在你的应用根目录运行  <code>composer require tymon/jwt-auth</code>。在写这篇文章的时候正处于过渡时期，因此你可能需要指定版本(例如 1.0.0-rc.5)。</li>
<li>如果你使用的是 Laravel5.4 及更低的版本，将该行 <code>TymonJWTAuthProvidersLaravelServiceProvider::class,</code> 加入 config/app.php 的 providers 数组当中。</li>
<li>通过运行 <code>php artisan vendor:publish</code> 来选择  jwt-auth 软件包发布配置文件。</li>
<li>运行 <code>php artisan jwt:secret</code> 以生成签名应用程序令牌所需要的密钥。</li>
</ol>
<p>完成之后，你需要决定哪些路由将受 JWT 保护并针对 JWT 进行身份验证。你可以使用内置的 api auth 中间件来执行此操作,或者也可以自己滚动在发送请求的过程中获取令牌。在 API 的登录方法中，你将使用相同的  <code>auth()-&gt;attempt</code> 方法作为默认的Laravel应用程序，但从它返回的除外是你应该传递回的 JSON Web Token 令牌。</p>
<p>从那里，你的 Vue 应用程序应该存储该令牌(存储在 LocalStorage 或者 Vuex)，在每一个传出请求中，都将它加入到 Authorization header 作为授权头。回到你的 Laravel 应用，你可以使用他们的令牌来引用特定用户的请求。将应该显示给他们的数据返回回去。</p>
</div>
</div>
</article>
<p>The post <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com/software-engineering/laravel/18844/topic-87086010/" data-wpel-link="internal">将数据从 Laravel 传送到 vue 的四种方式</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 Model 小知识</title>
		<link>https://hypergrowths.com/software-engineering/laravel/18332/topic-80195674/</link>
		
		<dc:creator><![CDATA[marketer]]></dc:creator>
		<pubDate>Fri, 30 Apr 2021 07:00:05 +0000</pubDate>
				<category><![CDATA[Laravel]]></category>
		<category><![CDATA[PHP / Laravel / 全栈]]></category>
		<guid isPermaLink="false">https://hypergrowths.com/software-engineering/laravel/18332/topic-80195674/</guid>

					<description><![CDATA[<p>文章转发在专业的 Laravel 开发者社区，原始链接：https://learnku.com/laravel/t/33145 当我第一次开始在 Laravel 开发时，我感觉在实现模型时有很多事情可以采用更好的方式来完成。在探索 Eloquent 模型类之后，…</p>
<p>The post <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com/software-engineering/laravel/18332/topic-80195674/" data-wpel-link="internal">七个必知必会的 Laravel Model 小知识</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 Model 小知识</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/33145" 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/3</span><span class="invisible">3145</span></a></p></blockquote>
<p>当我第一次开始在 Laravel 开发时，我感觉在实现模型时有很多事情可以采用更好的方式来完成。在探索 Eloquent 模型类之后，我发现你可以用你的模型做一些有趣的事儿，这会让你感觉更加的轻松。</p>
<p>在这篇文章中，我会向你提供7个小提示，让每一个使用 Laravel 的人都知道应该如何充分利用你的模型。</p>
<h2>#1 首先，让我们创建模型开始</h2>
<p>当我们通过命令行创建一个模型时，你可以指定在某个文件夹中创建这个模型。你所要做的就是在模型名称前输入你的文件夹的名称。当你的模型没有存储在默认的 <i>app</i> 文件夹中时，这对你很有帮助。</p>
<div class="highlight">
<pre><code class="language-text">php artisan make:model Models/Product</code></pre>
</div>
<p>此时将会在 <i>app/Models</i> 文件夹中创建一个 <i>Product</i> 模型，这样可以节省你将模型移动到符合条件的的文件夹的时间。</p>
<h2>#2 转换属性类型</h2>
<p><i>$casts</i> 属性提供了将属性强制转换为某些数据类型的方法。</p>
<div class="highlight">
<pre><code class="language-text">protected $casts = [
    'is_published' =&gt; 'boolean'
];</code></pre>
</div>
<p><i>is_publish</i> 属性现在将在你访问的时候强制转换为 <i>boolean</i> 类型，即使它在你的数据库中存储的是 <i>integer</i> 。也有很多的方式将属性转换为其他的类型，例如 <i>date</i> 和 <i>datetime</i> 。</p>
<p>我经常会看到一个错误的行为，就是在 Blade 模版文件中将 <i>date</i> 和 <i>datetime</i> 进行格式化，就像这样： </p>
<div class="highlight">
<pre><code class="language-text">{{ $blog-&gt;created_at-&gt;format('Y-m-d') }}</code></pre>
</div>
<p>在某些 Blade 模板文件中，你将会看到在同一个变量上进行多次的格式化。这个问题可以通过 <i>$casts</i> 属性来更高效的解决。</p>
<p>对于 <i>date</i> 和 <i>datetime</i> 的转换属性，你可以指定一下格式：</p>
<div class="highlight">
<pre><code class="language-text">protected $casts = [
    'published_at' =&gt; 'datetime:Y-m-d',
];</code></pre>
</div>
<p>这将始终会以 <i>Y-m-d</i> 的格式返回 <i>published_at</i> 属性，所以你不再需要在 Blade 模板文件中进行任何的格式化了。</p>
<h2>#3 是否可见</h2>
<p>某些属性并不应该被包含在模型的数组或JSON表示中，例如 <i>密码</i> 属性。此时便是 <i>$hidden</i> 属性登场的时候了。</p>
<div class="highlight">
<pre><code class="language-text">protected $hidden = [
    'password'
];</code></pre>
</div>
<p><i>$hidden</i> 属性就像是属性的黑名单。或者，你也可以使用 <i>$visible</i> 属性来设置属性的白名单。</p>
<div class="highlight">
<pre><code class="language-text">protected $visible = [
    'first_name',
    'last_name'
];</code></pre>
</div>
<p>当在模型中设置了 <i>$visible</i> 属性时，其他的属性将会自动隐藏。这个方式就像 <i>$fillable</i> 和 <i>$guarded</i> 属性一样。</p>
<h2>#4 访问器</h2>
<p>有些时候你想要将多个属性合并为一个属性，或者你仅仅想要格式化属性。此时我们可以使用 Laravel 的访问器。</p>
<p>假设你有一个 User 模型，并且它们具有 <i>first_name</i> 和 <i>last_name</i> 属性。如果你想要展示全名的话，你可以这么做：</p>
<div class="highlight">
<pre><code class="language-text">$this-&gt;first_name . ' ' . $this-&gt;last_name</code></pre>
</div>
<p>这是一个非常天真的做法。在 Laravel 中解决这个问题的方法是使用访问器。访问器会使用以下语法在模型中定义一个方法：</p>
<div class="highlight">
<pre><code class="language-text">get[NameOfAttribute]Attribute</code></pre>
</div>
<p>一个获取全名的访问会是下面这个样子：</p>
<div class="highlight">
<pre><code class="language-text">public function getFullNameAttribute() {
    return "{$this-&gt;first_name} {$this-&gt;last_name}";
}</code></pre>
</div>
<p>要获取全名的值，你只需要像这样调用访问器即可：</p>
<div class="highlight">
<pre><code class="language-text">$user-&gt;full_name</code></pre>
</div>
<h2>#5 修改器</h2>
<p>修改器 允许您对值进行操作，并在模型的 ＊$attributes＊ 属性上设置操作值。变量具有与访问器相同的语法。</p>
<div class="highlight">
<pre><code class="language-text">public function setLastNameAttribute($value) {
    $this-&gt;attributes['last_name'] = ucfirst($value);
}</code></pre>
</div>
<p>这个mutator将对姓氏应用＊ucfirst ＊函数，并将结果存储在＊$attributes＊属性中。</p>
<div class="highlight">
<pre><code class="language-text">$user-&gt;last_name = 'jones'; // 结果将会是 `Jones`</code></pre>
</div>
<h2>#6 追加值</h2>
<p>当模型具有访问器和模型关联时，默认情况下它们不会被添加到模型的数组或JSON表示中。为此，你需要将访问器或模型关联添加到模型的 <i>$appends</i> 属性中。现在让我们继续使用 <i>getFullNameAttribute</i> 访问器的这个例子：</p>
<div class="highlight">
<pre><code class="language-text">$appends = [
    'full_name'
];</code></pre>
</div>
<blockquote><p> 注意： 添加到 $appends 属性的访问器是以蛇形命名法引用，即便访问器是以驼峰命名法定义的。</p></blockquote>
<p>让我们假设 User 模型与 Blog 模型存在一对多的关系。</p>
<div class="highlight">
<pre><code class="language-text">public function blogs() {
    return $this-&gt;hasMany(AppBlog::class);
}</code></pre>
</div>
<p>要将 blogs 添加到模型中，你只需要将他们添加到 <i>$appends</i> 属性中即可：</p>
<div class="highlight">
<pre><code class="language-text">$appends = [
    'full_name',
    'blogs'
];</code></pre>
</div>
<p>当然，我们以可以指定添加的属性。例如，如果你仅仅需要 blog 中的 <i>id</i> 和 <i>title</i> 添加到模型中。</p>
<div class="highlight">
<pre><code class="language-text">$appends = [
    'full_name',
    'blogs:id,title'
];</code></pre>
</div>
<h2>#7 最后润色</h2>
<p>当一个模型与与另一个模型存在 <i>BelongsTo</i> 或 <i>BelongsToMany</i> 关联模型的关系时，比如说 Comment 属于 Blog，在某些情况下可以有助于在更新子项数据时同时更新父级的时间戳。这个问题可以通过将关系添加到 <i>$touches</i> 属性中来实现。</p>
<div class="highlight">
<pre><code class="language-text">class Comment extends Model
{
    protected $touches = ['blog'];

    public function blog()
    {
        return $this-&gt;belongsTo(AppBlog::class);
    }
}</code></pre>
</div>
<p>当 Comment 模型更新时，同时也会更新 Blog 模型的 <i>updated_at</i> 属性。</p>
</div>
</div>
</article>
<p>The post <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com/software-engineering/laravel/18332/topic-80195674/" data-wpel-link="internal">七个必知必会的 Laravel Model 小知识</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 集合（Collection）</title>
		<link>https://hypergrowths.com/software-engineering/laravel/17776/topic-63005113/</link>
		
		<dc:creator><![CDATA[marketer]]></dc:creator>
		<pubDate>Fri, 30 Apr 2021 06:39:12 +0000</pubDate>
				<category><![CDATA[Laravel]]></category>
		<category><![CDATA[PHP / Laravel / 全栈]]></category>
		<guid isPermaLink="false">https://hypergrowths.com/software-engineering/laravel/17776/topic-63005113/</guid>

					<description><![CDATA[<p>文章转自：https://learnku.com/laravel/t/27647 Laravel Eloquent 通常返回一个集合作为结果，集合包含很多有用的、功能强大的方法。你可以很方便的对集合进行过滤、修改等操作。本次教程就一起来看一看集合的常…</p>
<p>The post <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com/software-engineering/laravel/17776/topic-63005113/" data-wpel-link="internal">十五个常用的 Laravel 集合（Collection）</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 集合（Collection）</h1>
<div class="Post-Author">
<div class="AuthorInfo"></div>
</div>
</header>
<div class="Post-RichTextContainer">
<div class="RichText ztext Post-RichText">
<blockquote><p> 文章转自：<a href="https://link.zhihu.com/?target=https%3A//learnku.com/laravel/t/27647" 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/2</span><span class="invisible">7647</span></a></p>
</blockquote>
<p>Laravel Eloquent 通常返回一个集合作为结果，集合包含很多有用的、功能强大的方法。你可以很方便的对集合进行过滤、修改等操作。本次教程就一起来看一看集合的常用方法及功能。 集合并不仅限于 eloquent ，也可以单独使用。但 Eloquent 的结果就是一个集合。你可以使用助手函数 <code>collect</code> 将数组转化为集合。下面所列出的集合的方法适用于 eloquent 结果的同时也适用于集合本身。</p>
<p>比方说，你有一个帖子模型。 你找到所有 <code>php</code> 类别的帖子。</p>
<div class="highlight">
<pre><code class="language-text">$posts = AppPost::where('category', 'php')-&gt;get();</code></pre>
</div>
<p>上面的命令返回一个集合。 集合是一个laravel类，它在内部使用数组函数并为它们添加许多功能。</p>
<p>你可以简单的使用 <code>collect</code> 方法创建一个集合，如下：</p>
<div class="highlight">
<pre><code class="language-text">$collection = collect([
    [
        'user_id' =&gt; '1',
        'title' =&gt; 'Helpers in Laravel',
        'content' =&gt; 'Create custom helpers in Laravel',
        'category' =&gt; 'php'
    ],
    [
        'user_id' =&gt; '2',
        'title' =&gt; 'Testing in Laravel',
        'content' =&gt; 'Testing File Uploads in Laravel',
        'category' =&gt; 'php'
    ],
    [
        'user_id' =&gt; '3',
        'title' =&gt; 'Telegram Bot',
        'content' =&gt; 'Crypto Telegram Bot in Laravel',
        'category' =&gt; 'php'
    ],
]);</code></pre>
</div>
<p>上面的数组实际上是 Post 模型的值。 在本教程中，我们将使用此数组进行简化。 请记住，一切都将以同样的方式基于 eloquent。</p>
<p>当我们在 eloquent 集合上使用辅助方法时，不会再查询数据库。 我们首先要从数据库中获取所有结果，然后我们使用集合方法来过滤和修改它们，而无需查询数据库。</p>
<h2>filter()</h2>
<p>filter，最有用的 laravel 集合方法之一，允许您使用回调过滤集合。 它只传递那些返回true的项。 所有其他项目都被删除。 <code>filter</code> 返回一个新实例而不更改原始实例。 它接受 <code>value</code> 和 <code>key</code> 作为回调中的两个参数。</p>
<div class="highlight">
<pre><code class="language-text">$filter = $collection-&gt;filter(function($value, $key) {
    if ($value['user_id'] == 2) {
        return true;
    }
});

$filter-&gt;all();</code></pre>
</div>
<p><code>all</code> 方法返回底层数组。 上面的代码返回以下响应。</p>
<div class="highlight">
<pre><code class="language-text">[
    1 =&gt; [
        "user_id" =&gt; 2,
        "title" =&gt; "Testing in Laravel",
        "content" =&gt; "Testing File Uploads in Laravel",
        "category" =&gt; "php"
    ]
]</code></pre>
</div>
<h2>search()</h2>
<p><code>search</code> 方法可以用给定的值查找集合。如果这个值在集合中，会返回对应的键。如果没有数据项匹配对应的值，会返回 <code>false</code>。</p>
<div class="highlight">
<pre><code class="language-text">$names = collect(['Alex', 'John', 'Jason', 'Martyn', 'Hanlin']);

$names-&gt;search('Jason');

// 2</code></pre>
</div>
<p><code>search</code> 方法默认使用松散比较。你可以在它的第二个参数传 <code>true</code> 使用严格比较。</p>
<p>你也可以传你自己的回调函数到 <code>search</code> 方法中。将返回通过回调真值测试的第一个项的键。</p>
<div class="highlight">
<pre><code class="language-text">$names = collect(['Alex', 'John', 'Jason', 'Martyn', 'Hanlin']);

$names-&gt;search(function($value, $key) {
    return strlen($value) == 6;
});

// 3</code></pre>
</div>
<h2>chunk()</h2>
<p><code>chunk</code> 方法将集合分割为多个给定大小的较小集合。将集合显示到网格中非常有用。</p>
<div class="highlight">
<pre><code class="language-text">$prices = collect([18, 23, 65, 36, 97, 43, 81]);

$prices = $prices-&gt;chunk(3);

$prices-&gt;toArray();</code></pre>
</div>
<p>以上代码生成效果。</p>
<div class="highlight">
<pre><code class="language-text">[
    0 =&gt; [
        0 =&gt; 18,
        1 =&gt; 23,
        2 =&gt; 65
    ],
    1 =&gt; [
        3 =&gt; 36,
        4 =&gt; 97,
        5 =&gt; 43
    ],
    2 =&gt; [
        6 =&gt; 81
    ]
]</code></pre>
</div>
<h2>dump()</h2>
<p><code>dump</code> 打印集合的方法。 它可用于在任何位置的调试和查找集合内的内容。</p>
<div class="highlight">
<pre><code class="language-text">$collection-&gt;whereIn('user_id', [1, 2])
    -&gt;dump()
    -&gt;where('user_id', 1);</code></pre>
</div>
<p><code>dump</code> 上述代码结果。</p>
<p class="ztext-empty-paragraph"></p>
<figure data-size="normal"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-24d2dde45cff10fd3c4a5117f9790766_r.jpg" data-caption="" data-size="normal" data-rawwidth="1204" data-rawheight="768" class="origin_image zh-lightbox-thumb" width="1204" data-original="https://pic3.zhimg.com/v2-24d2dde45cff10fd3c4a5117f9790766_b.jpg" title="v2-24d2dde45cff10fd3c4a5117f9790766_r"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-24d2dde45cff10fd3c4a5117f9790766_r.jpg" data-caption="" data-size="normal" data-rawwidth="1204" data-rawheight="768" class="origin_image zh-lightbox-thumb lazy" width="1204" data-original="data:image/svg+xml;utf8,&lt;svg%20xmlns='http://www.w3.org/2000/svg'%20width='1204'%20height='768'&gt;&lt;/svg&gt;" data-actualsrc="https://pic3.zhimg.com/v2-24d2dde45cff10fd3c4a5117f9790766_b.jpg" title="v2-24d2dde45cff10fd3c4a5117f9790766_r"></figure>
<p class="ztext-empty-paragraph"></p>
<h2>map()</h2>
<p><code>map</code> 方法用于遍历整个集合。 它接受回调作为参数。 <code>value</code> 和 <code>key</code> 被传递给回调。 回调可以修改值并返回它们。 最后，返回修改项的新集合实例。</p>
<div class="highlight">
<pre><code class="language-text">$changed = $collection-&gt;map(function ($value, $key) {
    $value['user_id'] += 1;
    return $value;
});

return $changed-&gt;all();</code></pre>
</div>
<p>基本上，它将 <code>user_id</code> 增加1。</p>
<p>上面代码的响应如下所示。</p>
<div class="highlight">
<pre><code class="language-text">[
    [
        "user_id" =&gt; 2,
        "title" =&gt; "Helpers in Laravel",
        "content" =&gt; "Create custom helpers in Laravel",
        "category" =&gt; "php"
    ],
    [
        "user_id" =&gt; 3,
        "title" =&gt; "Testing in Laravel",
        "content" =&gt; "Testing File Uploads in Laravel",
        "category" =&gt; "php"
    ],
    [
        "user_id" =&gt; 4,
        "title" =&gt; "Telegram Bot",
        "content" =&gt; "Crypto Telegram Bot in Laravel",
        "category" =&gt; "php"
    ]
];</code></pre>
</div>
<h2>zip()</h2>
<p>Zip 方法会将给定数组的值与集合的值合并在一起。相同索引的值会添加在一起，这意味着，数组的第一个值会与集合的第一个值合并。在这里，我会使用我们在上面刚刚创建的集合。这对 Eloquent 集合同样有效。</p>
<div class="highlight">
<pre><code class="language-text">$zipped = $collection-&gt;zip([1, 2, 3]);

$zipped-&gt;all();</code></pre>
</div>
<p>JSON 响应会像这样。</p>
<p class="ztext-empty-paragraph"></p>
<figure data-size="normal"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-b76ade11a506132ee2ca8dd1943b7363_r.jpg" data-caption="" data-size="normal" data-rawwidth="564" data-rawheight="723" class="origin_image zh-lightbox-thumb" width="564" data-original="https://pic4.zhimg.com/v2-b76ade11a506132ee2ca8dd1943b7363_b.jpg" title="v2-b76ade11a506132ee2ca8dd1943b7363_r"><img decoding="async" src="https://hypergrowths.com/wp-content/uploads/2021/04/v2-b76ade11a506132ee2ca8dd1943b7363_r.jpg" data-caption="" data-size="normal" data-rawwidth="564" data-rawheight="723" class="origin_image zh-lightbox-thumb lazy" width="564" data-original="data:image/svg+xml;utf8,&lt;svg%20xmlns='http://www.w3.org/2000/svg'%20width='564'%20height='723'&gt;&lt;/svg&gt;" data-actualsrc="https://pic4.zhimg.com/v2-b76ade11a506132ee2ca8dd1943b7363_b.jpg" title="v2-b76ade11a506132ee2ca8dd1943b7363_r"></figure>
<p class="ztext-empty-paragraph"></p>
<p>所以，基本上就是这样。如果数组的长度小于集合的长度，Laravel 会给剩下的 <code>Collection</code> 类型的元素末尾添加 <code>null</code>。类似地，如果数组的长度比集合的长度大，Laravel 会给 <code>Collection</code> 类型的元素添加 <code>null</code>，然后再接着数组的值。</p>
<h2>whereNotIn()</h2>
<p>您可以使用 <code>whereNotIn</code> 方法简单地按照给定数组中未包含的键值过滤集合。 它基本上与 <code>whereIn</code> 相反。 此外，此方法在匹配值时使用宽松比较 <code>==</code>。</p>
<p>让我们过滤 <code>$collection</code>，其中 <code>user_id</code> 既不是 <code>1</code> 也不是 <code>2</code>的。</p>
<div class="highlight">
<pre><code class="language-text">$collection-&gt;whereNotIn('user_id', [1, 2]);</code></pre>
</div>
<p>上面的语句将只返回 <code>$collection</code> 中的最后一项。 第一个参数是键，第二个参数是值数组。 如果是 eloquent 的话，第一个参数将是列的名称，第二个参数将是一个值数组。</p>
<h2>max()</h2>
<p><code>max</code> 方法返回给定键的最大值。 你可以通过调用max来找到最大的 <code>user_id</code>。 它通常用于价格或任何其他数字之类的比较，但为了演示，我们使用 <code>user_id</code>。 它也可以用于字符串，在这种情况下，<code>Z&gt; a</code>。</p>
<div class="highlight">
<pre><code class="language-text">$collection-&gt;max('user_id');</code></pre>
</div>
<p>上面的语句将返回最大的 <code>user_id</code>，在我们的例子中是 <code>3</code>。</p>
<h2>pluck()</h2>
<p><code>pluck</code> 方法返回指定键的所有值。 它对于提取一列的值很有用。</p>
<div class="highlight">
<pre><code class="language-text">$title = $collection-&gt;pluck('title');
$title-&gt;all();</code></pre>
</div>
<p>结果看起来像这样。</p>
<div class="highlight">
<pre><code class="language-text">[
  "Helpers in Laravel",
  "Testing in Laravel",
  "Telegram Bot"
]</code></pre>
</div>
<p>When working with eloquent, you can pass a column name as an argument to extract its values. <code>pluck</code> also accepts a second argument and in the case of eloquent collections, it can be another column name. It will result in collection keyed by the values of the second argument. 使用 eloquent 时，可以将列名作为参数传递以提取值。 <code>pluck</code> 也接受第二个参数，对于 eloquent 的集合，它可以是另一个列名。 它将导致由第二个参数的值作为键的集合。</p>
<div class="highlight">
<pre><code class="language-text">$title = $collection-&gt;pluck('user_id', 'title');
$title-&gt;all();</code></pre>
</div>
<p>结果如下：</p>
<div class="highlight">
<pre><code class="language-text">[
    "Helpers in Laravel" =&gt; 1,
    "Testing in Laravel" =&gt; 2,
    "Telegram Bot" =&gt; 3
]</code></pre>
</div>
<h2>each()</h2>
<p><code>each</code> 是一种迭代整个集合的简单方法。 它接受一个带有两个参数的回调：它正在迭代的项和键。 Key 是基于 0 的索引。</p>
<div class="highlight">
<pre><code class="language-text">$collection-&gt;each(function ($item, $key) {
    info($item['user_id']);
});</code></pre>
</div>
<p>上面代码，只是记录每个项的 <code>user_id</code>。</p>
<p>在迭代 eloquent 集合时，您可以将所有列值作为项属性进行访问。 以下是我们如何迭代所有帖子。</p>
<div class="highlight">
<pre><code class="language-text">$posts = AppPost::all();

$posts-&gt;each(function ($item, $key) {
    // Do something
});</code></pre>
</div>
<p>如果回调中返回 false，它将停止迭代项目。</p>
<div class="highlight">
<pre><code class="language-text">$collection-&gt;each(function ($item, $key) {
    // Tasks
    if ($key == 1) {
        return false;
    }
});</code></pre>
</div>
<h2>tap()</h2>
<p><code>tap()</code> 方法允许你随时加入集合。 它接受回调并传递并将集合传递给它。 您可以对项目执行任何操作，而无需更改集合本身。 因此，您可以在任何时候使用tap来加入集合，而不会改变集合。</p>
<div class="highlight">
<pre><code class="language-text">$collection-&gt;whereNotIn('user_id', 3)
    -&gt;tap(function ($collection) {
        $collection = $collection-&gt;where('user_id', 1);
        info($collection-&gt;values());
    })
    -&gt;all();</code></pre>
</div>
<p>在上面使用的 tap 方法中，我们修改了集合，然后记录了值。 您可以对 tap 中的集合做任何您想做的事情。 上面命令的响应是：</p>
<div class="highlight">
<pre><code class="language-text">[
    [
        "user_id" =&gt; "1",
        "title" =&gt; "Helpers in Laravel",
        "content" =&gt; "Create custom helpers in Laravel",
        "category" =&gt; "php"
    ],
    [
        "user_id" =&gt; "2",
        "title" =&gt; "Testing in Laravel",
        "content" =&gt; "Testing File Uploads in Laravel",
        "category" =&gt; "php"
    ]
]</code></pre>
</div>
<p>你可以看到 tap 不会修改集合实例。</p>
<h2>pipe()</h2>
<p><code>pipe</code> 方法非常类似于 <code>tap</code> 方法，因为它们都在集合管道中使用。 <code>pipe</code> 方法将集合传递给回调并返回结果。</p>
<div class="highlight">
<pre><code class="language-text">$collection-&gt;pipe(function($collection) {
    return $collection-&gt;min('user_id');
});</code></pre>
</div>
<p>上述命令的响应是 <code>1</code>。 如果从 <code>pipe</code>回调中返回集合实例，也可以链接其他方法。</p>
<h2>contains()</h2>
<p><code>contains</code> 方法只检查集合是否包含给定值。 只传递一个参数时才会出现这种情况。</p>
<div class="highlight">
<pre><code class="language-text">$contains = collect(['country' =&gt; 'USA', 'state' =&gt; 'NY']);

$contains-&gt;contains('USA');
// true

$contains-&gt;contains('UK');
// false</code></pre>
</div>
<p>如果将 键 / 值 对传递给 contains 方法，它将检查给定的键值对是否存在。</p>
<div class="highlight">
<pre><code class="language-text">$collection-&gt;contains('user_id', '1');
// true

$collection-&gt;contains('title', 'Not Found Title');
// false</code></pre>
</div>
<p>您还可以将回调作为参数传递给回调方法。 将对集合中的每个项目运行回调，如果其中任何一个项目通过了真值测试，它将返回 <code>true</code> 否则返回 <code>false</code>。</p>
<div class="highlight">
<pre><code class="language-text">$collection-&gt;contains(function ($value, $key) {
    return strlen($value['title']) &lt; 13;
});
// true</code></pre>
</div>
<p>回调函数接受当前迭代项和键的两个参数值。 这里我们只是检查标题的长度是否小于13。在 <code>Telegram Bot</code> 中它是12，所以它返回 <code>true</code>。</p>
<h2>forget()</h2>
<p><code>forget</code> 只是从集合中删除该项。 您只需传递一个键，它就会从集合中删除该项目。</p>
<div class="highlight">
<pre><code class="language-text">$forget = collect(['country' =&gt; 'usa', 'state' =&gt; 'ny']);

$forget-&gt;forget('country')-&gt;all();</code></pre>
</div>
<p>上面代码响应如下：</p>
<div class="highlight">
<pre><code class="language-text">[
    "state" =&gt; "ny"
]</code></pre>
</div>
<p><code>forget</code> 不适用于多维数组。</p>
<h2>avg()</h2>
<p><code>avg</code> 方法返回平均值。 你只需传递一个键作为参数，<code>avg</code> 方法返回平均值。 你也可以使用 <code>average</code> 方法，它基本上是 <code>avg</code> 的别名。</p>
<div class="highlight">
<pre><code class="language-text">$avg = collect([
    ['shoes' =&gt; 10],
    ['shoes' =&gt; 35],
    ['shoes' =&gt; 7],
    ['shoes' =&gt; 68],
])-&gt;avg('shoes');</code></pre>
</div>
<p>上面的代码返回 <code>30</code> ，这是所有四个数字的平均值。 如果你没有将任何键传递给<code>avg</code> 方法并且所有项都是数字，它将返回所有数字的平均值。 如果键未作为参数传递且集合包含键/值对，则 <code>avg</code> 方法返回 0。</p>
<div class="highlight">
<pre><code class="language-text">$avg = collect([12, 32, 54, 92, 37]);

$avg-&gt;avg();</code></pre>
</div>
<p>上面的代码返回 <code>45.4</code>，这是所有五个数字的平均值。</p>
<p>您可以使用这些 laravel 集合方法在您自己的项目中处理集合。</p>
<blockquote><p> 文章转自：<a href="https://link.zhihu.com/?target=https%3A//learnku.com/laravel/t/27647" 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/2</span><span class="invisible">7647</span></a><br />更多文章：<a href="https://link.zhihu.com/?target=https%3A//learnku.com/laravel/c/translations" class=" external" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external"><span class="invisible">https://</span><span class="visible">learnku.com/laravel/c/t</span><span class="invisible">ranslations</span></a></p></blockquote>
</div>
</div>
</article>
<p>The post <a rel="nofollow noopener noreferrer" href="https://hypergrowths.com/software-engineering/laravel/17776/topic-63005113/" data-wpel-link="internal">十五个常用的 Laravel 集合（Collection）</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>
