💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
<article><h1>服务提供者</h1><ul><li><a href="#introduction">简介</a></li><li><a href="#writing-service-providers">编写服务提供者</a><ul><li><a href="#the-register-method">注册方法</a></li><li><a href="#the-boot-method">引导方法</a></li></ul></li><li><a href="#registering-providers">注册提供者</a></li><li><a href="#deferred-providers">延迟的提供者</a></li></ul><p><a name="introduction"></a></p><h2><a href="#introduction">简介</a></h2><p>服务提供者是所有 Laravel 应用程序引导启动的中心所在。包括您自己的应用程序,以及所有的 Laravel 核心服务,都是通过服务提供者引导启动的。</p><p>但我们所谓的「引导启动」指的是什么?一般而言,我们指的是<strong>注册</strong>事务,包括注册服务容器绑定,事件监听器,中间件,甚至路由。服务提供者是配置应用程序的中心所在。</p><p>如果您打开 Laravel 的 <code class=" language-php">config<span class="token operator">/</span>app<span class="token punctuation">.</span>php</code> 文件,您会看到一个 <code class=" language-php">providers</code> 数组。这些是将被应用程序加载的服务提供者类。当然,它们其中有许多是「延迟」提供者,意味着它们不会每次请求都加载,只会按需加载。</p><p>在本概述中,您将学习如何编写自己的服务提供商,并在您的 Laravel 应用程序中注册它们。</p><p><a name="writing-service-providers"></a></p><h2><a href="#writing-service-providers">编写服务提供者</a></h2><p>所有服务提供者都需要继承 <code class=" language-php">Illuminate\<span class="token package">Support<span class="token punctuation">\</span>ServiceProvider</span></code> 类。大多数服务提供者都包含 <code class=" language-php">register</code> 和 <code class=" language-php">boot</code> 方法。在 <code class=" language-php">register</code> 方法中,您应该<strong>只能将事务绑定到 <a href="/docs/5.4/container">服务容器</a></strong>。不应该在 <code class=" language-php">register</code> 方法中尝试注册任何事件监听器,路由或者任何其他功能。</p><p>Artisan 命令行可以生成一个新的提供者通过 <code class=" language-php">make<span class="token punctuation">:</span>provider</code> 命令:</p><pre class=" language-php"><code class=" language-php">php artisan make<span class="token punctuation">:</span>provider RiakServiceProvider</code></pre><p><a name="the-register-method"></a></p><h3>注册方法</h3><p>如前所述,在 <code class=" language-php">register</code> 方法中,您只能将事务绑定到 <a href="/docs/5.4/container">服务容器</a> 。不应该在 <code class=" language-php">register</code> 方法中尝试注册任何事件监听器,路由或者任何其他功能。否则,您可能会意外的使用到尚未加载的服务提供者提供的服务。</p><p>让我们来看看一个基本的服务提供者。在服务提供者的方法中,都会提供一个有服务容器访问权限的 <code class=" language-php"><span class="token variable">$app</span></code> 属性:</p><p>现在,让我们来看看基本的服务提供者。在你的任意一个服务提供者方法中,你总是可以通过访问 <code class=" language-php"><span class="token variable">$app</span></code> 属性使用服务容器:</p><pre class=" language-php"><code class=" language-php"><span class="token delimiter">&lt;?php</span> <span class="token keyword">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Providers</span><span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package">Riak<span class="token punctuation">\</span>Connection</span><span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>ServiceProvider</span><span class="token punctuation">;</span> <span class="token keyword">class</span> <span class="token class-name">RiakServiceProvider</span> <span class="token keyword">extends</span> <span class="token class-name">ServiceProvider</span> <span class="token punctuation">{</span> <span class="token comment" spellcheck="true">/** * 在容器中注册绑定 * * @return void */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">register<span class="token punctuation">(</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token this">$this</span><span class="token operator">-</span><span class="token operator">&gt;</span><span class="token property">app</span><span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">singleton<span class="token punctuation">(</span></span><span class="token scope">Connection<span class="token punctuation">::</span></span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$app</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Connection</span><span class="token punctuation">(</span><span class="token function">config<span class="token punctuation">(</span></span><span class="token string">'riak'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre><p>服务提供者只定义了一个 <code class=" language-php">register</code> 方法,并且使用该方法在服务容器中定义了一个 <code class=" language-php">Riak\<span class="token package">Connection</span></code> 类的实现。如果您不明白服务容器的工作原理,请查看 <a href="/docs/5.4/container">服务容器</a>。</p><p><a name="the-boot-method"></a></p><h3>引导方法</h3><p>那么,如果我们需要在我们的服务提供商中注册一个视图合成器呢?这应该在 <code class=" language-php">boot</code> 方法中完成。<strong>此方法在所有其他服务提供者均已注册之后调用</strong>,这意味着您可以访问已由框架注册的所有服务:</p><pre class=" language-php"><code class=" language-php"><span class="token delimiter">&lt;?php</span> <span class="token keyword">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Providers</span><span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>ServiceProvider</span><span class="token punctuation">;</span> <span class="token keyword">class</span> <span class="token class-name">ComposerServiceProvider</span> <span class="token keyword">extends</span> <span class="token class-name">ServiceProvider</span> <span class="token punctuation">{</span> <span class="token comment" spellcheck="true">/** * 引导启动任何应用程序服务 * * @return void */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">boot<span class="token punctuation">(</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">view<span class="token punctuation">(</span></span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">composer<span class="token punctuation">(</span></span><span class="token string">'view'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment" spellcheck="true"> // </span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre><h4>引导方法依赖注入</h4><p>您可以为服务提供者的 <code class=" language-php">boot</code> 方法设置类型提示。<a href="/docs/5.4/container">服务容器</a> 会自动注入您需要的任何依赖:</p><pre class=" language-php"><code class=" language-php"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Contracts<span class="token punctuation">\</span>Routing<span class="token punctuation">\</span>ResponseFactory</span><span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">boot<span class="token punctuation">(</span></span>ResponseFactory <span class="token variable">$response</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$response</span><span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">macro<span class="token punctuation">(</span></span><span class="token string">'caps'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$value</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment" spellcheck="true"> // </span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre><p><a name="registering-providers"></a></p><h2><a href="#registering-providers">注册提供者</a></h2><p>所有服务提供者都在 <code class=" language-php">config<span class="token operator">/</span>app<span class="token punctuation">.</span>php</code> 配置文件中注册。此文件包含一个服务提供者类数组 <code class=" language-php">providers</code> 。默认情况下,它只会列出 Laravel 核心服务提供者类。这些服务提供者引导启动 Laravel 核心组件,例如邮件程序,队列,缓存和其他。</p><p>要注册您的提供程序,只需将其添加到数组:</p><pre class=" language-php"><code class=" language-php"><span class="token string">'providers'</span> <span class="token operator">=</span><span class="token operator">&gt;</span> <span class="token punctuation">[</span> <span class="token comment" spellcheck="true"> // Other Service Providers </span> <span class="token scope">App<span class="token punctuation">\</span>Providers<span class="token punctuation">\</span>ComposerServiceProvider<span class="token punctuation">::</span></span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">,</span></code></pre><p><a name="deferred-providers"></a></p><h2><a href="#deferred-providers">延迟的提供者</a></h2><p>如果您的提供程序 <strong>仅</strong> 在 <a href="/docs/5.4/container">服务容器</a> 中注册绑定,您可以选择推迟其注册,直到真正需要注册绑定时。延迟加载服务提供者将提高应用程序的性能,因为它不会每次都从文件系统中加载。</p><p>Laravel 编译并保存了一份清单,包括由延缓服务提供者所提供的所有服务,以及其服务提供者类的类名。因此,只有在当您在试图解析其中的服务时,Laravel 才会加载该服务提供者。</p><p>若要推迟提供者的加载,请将 <code class=" language-php">defer</code> 属性设置为 <code class=" language-php"><span class="token boolean">true</span></code> ,并定义 <code class=" language-php">provides</code> 方法。<code class=" language-php">provides</code> 应该返回由提供者注册的服务容器绑定:</p><pre class=" language-php"><code class=" language-php"><span class="token delimiter">&lt;?php</span> <span class="token keyword">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Providers</span><span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package">Riak<span class="token punctuation">\</span>Connection</span><span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>ServiceProvider</span><span class="token punctuation">;</span> <span class="token keyword">class</span> <span class="token class-name">RiakServiceProvider</span> <span class="token keyword">extends</span> <span class="token class-name">ServiceProvider</span> <span class="token punctuation">{</span> <span class="token comment" spellcheck="true">/** * 显示是否延迟提供程序的加载 * * @var bool */</span> <span class="token keyword">protected</span> <span class="token variable">$defer</span> <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token comment" spellcheck="true">/** * 注册一个服务提供者 * * @return void */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">register<span class="token punctuation">(</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token this">$this</span><span class="token operator">-</span><span class="token operator">&gt;</span><span class="token property">app</span><span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">singleton<span class="token punctuation">(</span></span><span class="token scope">Connection<span class="token punctuation">::</span></span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$app</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Connection</span><span class="token punctuation">(</span><span class="token variable">$app</span><span class="token punctuation">[</span><span class="token string">'config'</span><span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token string">'riak'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment" spellcheck="true">/** * 获取提供者提供的服务 * * @return array */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">provides<span class="token punctuation">(</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">[</span><span class="token scope">Connection<span class="token punctuation">::</span></span><span class="token keyword">class</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre><h2>译者署名</h2><table><thead><tr><th>用户名</th><th>头像</th><th>职能</th><th>签名</th></tr></thead><tbody><tr><td><a href="https://github.com/e421083458">@e421083458</a></td><td><img class="avatar-66 rm-style" src="https://dn-phphub.qbox.me/uploads/avatars/10802_1486368142.jpeg?imageView2/1/w/100/h/100"></td><td>翻译</td><td>Github求star,<a href="https://github.com/e421083458/">@e421083458</a> at Github</td></tr></tbody></table></article>