検索
ホームページバックエンド開発PHPチュートリアルPHP 依存関係インジェクションを理解する Laravel IoC コンテナー

PHP 依存関係注入について | Laravel IoC コンテナ

Laravel フレームワークの依存関係注入は確かに非常に強力で、コンテナを通じて実装された依存関係注入により、必要なサービスを選択的にロードし、フレームワークの初期化のオーバーヘッドを削減できます。以下は私がオンラインで学んだことです。非常によく書かれた投稿を見たので、それを共有したいと思います。この記事は、従来のクラスに従ってデータベース接続を設計することから始まり、コンテナを介してサービスをロードするという高度に分離された設計で終わります。これは依存関係の挿入の力を示しており、学ぶ価値があります。

------------------------------------------ ------ ---------------分割線の下はダニエルの原文です--------------------- ------ ----------------------------------

元リンク(http ://www.yuansir-web.com/2014/03/20)

まず、SomeComponent という名前のコンポーネントを開発するとします。データベース接続がこのコンポーネントに挿入されます。この例では、データベース接続はコンポーネント内で作成されますが、これを行うと、データベース接続パラメータやデータベース タイプなどの一部のパラメータを変更できなくなります。

<span style="color: #008080;"> 1</span> <span style="color: #000000;">php</span><span style="color: #008080;"> 2</span> <span style="color: #008080;"> 3</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> SomeComponent</span><span style="color: #008080;"> 4</span> <span style="color: #000000;">{</span><span style="color: #008080;"> 5</span> <span style="color: #008080;"> 6</span>     <span style="color: #008000;">/*</span><span style="color: #008000;">*</span><span style="color: #008080;"> 7</span> <span style="color: #008000;">     * The instantiation of the connection is hardcoded inside</span><span style="color: #008080;"> 8</span> <span style="color: #008000;">     * the component so is difficult to replace it externally</span><span style="color: #008080;"> 9</span> <span style="color: #008000;">     * or change its behavior</span><span style="color: #008080;">10</span>      <span style="color: #008000;">*/</span><span style="color: #008080;">11</span>     <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> someDbTask()</span><span style="color: #008080;">12</span> <span style="color: #000000;">    {</span><span style="color: #008080;">13</span>         <span style="color: #800080;">$connection</span> = <span style="color: #0000ff;">new</span> Connection(<span style="color: #0000ff;">array</span><span style="color: #000000;">(</span><span style="color: #008080;">14</span>             "host" => "localhost",<span style="color: #008080;">15</span>             "username" => "root",<span style="color: #008080;">16</span>             "password" => "secret",<span style="color: #008080;">17</span>             "dbname" => "invo"<span style="color: #008080;">18</span> <span style="color: #000000;">        ));</span><span style="color: #008080;">19</span> <span style="color: #008080;">20</span>         <span style="color: #008000;">//</span><span style="color: #008000;"> ...</span><span style="color: #008080;">21</span> <span style="color: #000000;">    }</span><span style="color: #008080;">22</span> <span style="color: #008080;">23</span> <span style="color: #000000;">}</span><span style="color: #008080;">24</span> <span style="color: #008080;">25</span> <span style="color: #800080;">$some</span> = <span style="color: #0000ff;">new</span><span style="color: #000000;"> SomeComponent();</span><span style="color: #008080;">26</span> <span style="color: #800080;">$some</span>->someDbTask();

上記の問題を解決するには、使用前に外部接続を作成し、それをコンテナーに注入する必要があります。今のところ、これは良い解決策のように見えます:

<span style="color: #008080;"> 1</span> <span style="color: #000000;">php</span><span style="color: #008080;"> 2</span> <span style="color: #008080;"> 3</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> SomeComponent</span><span style="color: #008080;"> 4</span> <span style="color: #000000;">{</span><span style="color: #008080;"> 5</span> <span style="color: #008080;"> 6</span>     <span style="color: #0000ff;">protected</span> <span style="color: #800080;">$_connection</span><span style="color: #000000;">;</span><span style="color: #008080;"> 7</span> <span style="color: #008080;"> 8</span>     <span style="color: #008000;">/*</span><span style="color: #008000;">*</span><span style="color: #008080;"> 9</span> <span style="color: #008000;">     * Sets the connection externally</span><span style="color: #008080;">10</span>      <span style="color: #008000;">*/</span><span style="color: #008080;">11</span>     <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> setConnection(<span style="color: #800080;">$connection</span><span style="color: #000000;">)</span><span style="color: #008080;">12</span> <span style="color: #000000;">    {</span><span style="color: #008080;">13</span>         <span style="color: #800080;">$this</span>->_connection = <span style="color: #800080;">$connection</span><span style="color: #000000;">;</span><span style="color: #008080;">14</span> <span style="color: #000000;">    }</span><span style="color: #008080;">15</span> <span style="color: #008080;">16</span>     <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> someDbTask()</span><span style="color: #008080;">17</span> <span style="color: #000000;">    {</span><span style="color: #008080;">18</span>         <span style="color: #800080;">$connection</span> = <span style="color: #800080;">$this</span>-><span style="color: #000000;">_connection;</span><span style="color: #008080;">19</span> <span style="color: #008080;">20</span>         <span style="color: #008000;">//</span><span style="color: #008000;"> ...</span><span style="color: #008080;">21</span> <span style="color: #000000;">    }</span><span style="color: #008080;">22</span> <span style="color: #008080;">23</span> <span style="color: #000000;">}</span><span style="color: #008080;">24</span> <span style="color: #008080;">25</span> <span style="color: #800080;">$some</span> = <span style="color: #0000ff;">new</span><span style="color: #000000;"> SomeComponent();</span><span style="color: #008080;">26</span> <span style="color: #008080;">27</span> <span style="color: #008000;">//</span><span style="color: #008000;">Create the connection</span><span style="color: #008080;">28</span> <span style="color: #800080;">$connection</span> = <span style="color: #0000ff;">new</span> Connection(<span style="color: #0000ff;">array</span><span style="color: #000000;">(</span><span style="color: #008080;">29</span>     "host" => "localhost",<span style="color: #008080;">30</span>     "username" => "root",<span style="color: #008080;">31</span>     "password" => "secret",<span style="color: #008080;">32</span>     "dbname" => "invo"<span style="color: #008080;">33</span> <span style="color: #000000;">));</span><span style="color: #008080;">34</span> <span style="color: #008080;">35</span> <span style="color: #008000;">//</span><span style="color: #008000;">Inject the connection in the component</span><span style="color: #008080;">36</span> <span style="color: #800080;">$some</span>->setConnection(<span style="color: #800080;">$connection</span><span style="color: #000000;">);</span><span style="color: #008080;">37</span> <span style="color: #008080;">38</span> <span style="color: #800080;">$some</span>->someDbTask();

次に、このコンポーネントをアプリケーション内のさまざまな場所で使用する問題を考えてみましょう。データベース接続が複数回作成されます。 。データベース接続インスタンスを使用後に作成するのではなく、グローバル レジストリと同様の方法を使用して、ここからデータベース接続インスタンスを取得します。

<span style="color: #008080;"> 1</span> <span style="color: #000000;">php</span><span style="color: #008080;"> 2</span> <span style="color: #008080;"> 3</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> Registry</span><span style="color: #008080;"> 4</span> <span style="color: #000000;">{</span><span style="color: #008080;"> 5</span> <span style="color: #008080;"> 6</span>     <span style="color: #008000;">/*</span><span style="color: #008000;">*</span><span style="color: #008080;"> 7</span> <span style="color: #008000;">     * Returns the connection</span><span style="color: #008080;"> 8</span>      <span style="color: #008000;">*/</span><span style="color: #008080;"> 9</span>     <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> getConnection()</span><span style="color: #008080;">10</span> <span style="color: #000000;">    {</span><span style="color: #008080;">11</span>        <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">new</span> Connection(<span style="color: #0000ff;">array</span><span style="color: #000000;">(</span><span style="color: #008080;">12</span>             "host" => "localhost",<span style="color: #008080;">13</span>             "username" => "root",<span style="color: #008080;">14</span>             "password" => "secret",<span style="color: #008080;">15</span>             "dbname" => "invo"<span style="color: #008080;">16</span> <span style="color: #000000;">        ));</span><span style="color: #008080;">17</span> <span style="color: #000000;">    }</span><span style="color: #008080;">18</span> <span style="color: #008080;">19</span> <span style="color: #000000;">}</span><span style="color: #008080;">20</span> <span style="color: #008080;">21</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> SomeComponent</span><span style="color: #008080;">22</span> <span style="color: #000000;">{</span><span style="color: #008080;">23</span> <span style="color: #008080;">24</span>     <span style="color: #0000ff;">protected</span> <span style="color: #800080;">$_connection</span><span style="color: #000000;">;</span><span style="color: #008080;">25</span> <span style="color: #008080;">26</span>     <span style="color: #008000;">/*</span><span style="color: #008000;">*</span><span style="color: #008080;">27</span> <span style="color: #008000;">     * Sets the connection externally</span><span style="color: #008080;">28</span>      <span style="color: #008000;">*/</span><span style="color: #008080;">29</span>     <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> setConnection(<span style="color: #800080;">$connection</span><span style="color: #000000;">){</span><span style="color: #008080;">30</span>         <span style="color: #800080;">$this</span>->_connection = <span style="color: #800080;">$connection</span><span style="color: #000000;">;</span><span style="color: #008080;">31</span> <span style="color: #000000;">    }</span><span style="color: #008080;">32</span> <span style="color: #008080;">33</span>     <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> someDbTask()</span><span style="color: #008080;">34</span> <span style="color: #000000;">    {</span><span style="color: #008080;">35</span>         <span style="color: #800080;">$connection</span> = <span style="color: #800080;">$this</span>-><span style="color: #000000;">_connection;</span><span style="color: #008080;">36</span> <span style="color: #008080;">37</span>         <span style="color: #008000;">//</span><span style="color: #008000;"> ...</span><span style="color: #008080;">38</span> <span style="color: #000000;">    }</span><span style="color: #008080;">39</span> <span style="color: #008080;">40</span> <span style="color: #000000;">}</span><span style="color: #008080;">41</span> <span style="color: #008080;">42</span> <span style="color: #800080;">$some</span> = <span style="color: #0000ff;">new</span><span style="color: #000000;"> SomeComponent();</span><span style="color: #008080;">43</span> <span style="color: #008080;">44</span> <span style="color: #008000;">//</span><span style="color: #008000;">Pass the connection defined in the registry</span><span style="color: #008080;">45</span> <span style="color: #800080;">$some</span>->setConnection(Registry::<span style="color: #000000;">getConnection());</span><span style="color: #008080;">46</span> <span style="color: #008080;">47</span> <span style="color: #800080;">$some</span>->someDbTask();

さて、コンポーネントに 2 つのメソッドを実装する必要があると想像してみましょう。最初に新しいデータベース接続を作成する必要があり、2 番目のメソッドは常に共有接続を取得します。

<span style="color: #008080;"> 1</span> <span style="color: #000000;">php</span><span style="color: #008080;"> 2</span> <span style="color: #008080;"> 3</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> Registry</span><span style="color: #008080;"> 4</span> <span style="color: #000000;">{</span><span style="color: #008080;"> 5</span> <span style="color: #008080;"> 6</span>     <span style="color: #0000ff;">protected</span> <span style="color: #0000ff;">static</span> <span style="color: #800080;">$_connection</span><span style="color: #000000;">;</span><span style="color: #008080;"> 7</span> <span style="color: #008080;"> 8</span>     <span style="color: #008000;">/*</span><span style="color: #008000;">*</span><span style="color: #008080;"> 9</span> <span style="color: #008000;">     * Creates a connection</span><span style="color: #008080;">10</span>      <span style="color: #008000;">*/</span><span style="color: #008080;">11</span>     <span style="color: #0000ff;">protected</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> _createConnection()</span><span style="color: #008080;">12</span> <span style="color: #000000;">    {</span><span style="color: #008080;">13</span>         <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">new</span> Connection(<span style="color: #0000ff;">array</span><span style="color: #000000;">(</span><span style="color: #008080;">14</span>             "host" => "localhost",<span style="color: #008080;">15</span>             "username" => "root",<span style="color: #008080;">16</span>             "password" => "secret",<span style="color: #008080;">17</span>             "dbname" => "invo"<span style="color: #008080;">18</span> <span style="color: #000000;">        ));</span><span style="color: #008080;">19</span> <span style="color: #000000;">    }</span><span style="color: #008080;">20</span> <span style="color: #008080;">21</span>     <span style="color: #008000;">/*</span><span style="color: #008000;">*</span><span style="color: #008080;">22</span> <span style="color: #008000;">     * Creates a connection only once and returns it</span><span style="color: #008080;">23</span>      <span style="color: #008000;">*/</span><span style="color: #008080;">24</span>     <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> getSharedConnection()</span><span style="color: #008080;">25</span> <span style="color: #000000;">    {</span><span style="color: #008080;">26</span>         <span style="color: #0000ff;">if</span> (self::<span style="color: #800080;">$_connection</span>===<span style="color: #0000ff;">null</span><span style="color: #000000;">){</span><span style="color: #008080;">27</span>             <span style="color: #800080;">$connection</span> = self::<span style="color: #000000;">_createConnection();</span><span style="color: #008080;">28</span>             self::<span style="color: #800080;">$_connection</span> = <span style="color: #800080;">$connection</span><span style="color: #000000;">;</span><span style="color: #008080;">29</span> <span style="color: #000000;">        }</span><span style="color: #008080;">30</span>         <span style="color: #0000ff;">return</span> self::<span style="color: #800080;">$_connection</span><span style="color: #000000;">;</span><span style="color: #008080;">31</span> <span style="color: #000000;">    }</span><span style="color: #008080;">32</span> <span style="color: #008080;">33</span>     <span style="color: #008000;">/*</span><span style="color: #008000;">*</span><span style="color: #008080;">34</span> <span style="color: #008000;">     * Always returns a new connection</span><span style="color: #008080;">35</span>      <span style="color: #008000;">*/</span><span style="color: #008080;">36</span>     <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> getNewConnection()</span><span style="color: #008080;">37</span> <span style="color: #000000;">    {</span><span style="color: #008080;">38</span>         <span style="color: #0000ff;">return</span> self::<span style="color: #000000;">_createConnection();</span><span style="color: #008080;">39</span> <span style="color: #000000;">    }</span><span style="color: #008080;">40</span> <span style="color: #008080;">41</span> <span style="color: #000000;">}</span><span style="color: #008080;">42</span> <span style="color: #008080;">43</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> SomeComponent</span><span style="color: #008080;">44</span> <span style="color: #000000;">{</span><span style="color: #008080;">45</span> <span style="color: #008080;">46</span>     <span style="color: #0000ff;">protected</span> <span style="color: #800080;">$_connection</span><span style="color: #000000;">;</span><span style="color: #008080;">47</span> <span style="color: #008080;">48</span>     <span style="color: #008000;">/*</span><span style="color: #008000;">*</span><span style="color: #008080;">49</span> <span style="color: #008000;">     * Sets the connection externally</span><span style="color: #008080;">50</span>      <span style="color: #008000;">*/</span><span style="color: #008080;">51</span>     <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> setConnection(<span style="color: #800080;">$connection</span><span style="color: #000000;">){</span><span style="color: #008080;">52</span>         <span style="color: #800080;">$this</span>->_connection = <span style="color: #800080;">$connection</span><span style="color: #000000;">;</span><span style="color: #008080;">53</span> <span style="color: #000000;">    }</span><span style="color: #008080;">54</span> <span style="color: #008080;">55</span>     <span style="color: #008000;">/*</span><span style="color: #008000;">*</span><span style="color: #008080;">56</span> <span style="color: #008000;">     * This method always needs the shared connection</span><span style="color: #008080;">57</span>      <span style="color: #008000;">*/</span><span style="color: #008080;">58</span>     <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> someDbTask()</span><span style="color: #008080;">59</span> <span style="color: #000000;">    {</span><span style="color: #008080;">60</span>         <span style="color: #800080;">$connection</span> = <span style="color: #800080;">$this</span>-><span style="color: #000000;">_connection;</span><span style="color: #008080;">61</span> <span style="color: #008080;">62</span>         <span style="color: #008000;">//</span><span style="color: #008000;"> ...</span><span style="color: #008080;">63</span> <span style="color: #000000;">    }</span><span style="color: #008080;">64</span> <span style="color: #008080;">65</span>     <span style="color: #008000;">/*</span><span style="color: #008000;">*</span><span style="color: #008080;">66</span> <span style="color: #008000;">     * This method always needs a new connection</span><span style="color: #008080;">67</span>      <span style="color: #008000;">*/</span><span style="color: #008080;">68</span>     <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> someOtherDbTask(<span style="color: #800080;">$connection</span><span style="color: #000000;">)</span><span style="color: #008080;">69</span> <span style="color: #000000;">    {</span><span style="color: #008080;">70</span> <span style="color: #008080;">71</span> <span style="color: #000000;">    }</span><span style="color: #008080;">72</span> <span style="color: #008080;">73</span> <span style="color: #000000;">}</span><span style="color: #008080;">74</span> <span style="color: #008080;">75</span> <span style="color: #800080;">$some</span> = <span style="color: #0000ff;">new</span><span style="color: #000000;"> SomeComponent();</span><span style="color: #008080;">76</span> <span style="color: #008080;">77</span> <span style="color: #008000;">//</span><span style="color: #008000;">This injects the shared connection</span><span style="color: #008080;">78</span> <span style="color: #800080;">$some</span>->setConnection(Registry::<span style="color: #000000;">getSharedConnection());</span><span style="color: #008080;">79</span> <span style="color: #008080;">80</span> <span style="color: #800080;">$some</span>-><span style="color: #000000;">someDbTask();</span><span style="color: #008080;">81</span> <span style="color: #008080;">82</span> <span style="color: #008000;">//</span><span style="color: #008000;">Here, we always pass a new connection as parameter</span><span style="color: #008080;">83</span> <span style="color: #800080;">$some</span>->someOtherDbTask(Registry::getConnection());

これまで、依存関係注入を使用して問題を解決する方法を見てきました。コード内に依存関係を作成する代わりに、依存関係をパラメーターとして渡します。これにより、プログラムの保守が容易になり、プログラム コードの結合が減少し、一種の疎結合が実現します。しかし、長期的には、この形式の依存性注入にはいくつかの欠点もあります。

たとえば、コンポーネントに多くの依存関係がある場合、渡すセッター メソッドを複数作成するか、渡すコンストラクターを作成する必要があります。さらに、コンポーネントを使用するたびに依存コンポーネントを作成する必要があるため、コードのメンテナンスは次のようになります。

<span style="color: #008080;"> 1</span> <span style="color: #000000;">php</span><span style="color: #008080;"> 2</span> <span style="color: #008080;"> 3</span> <span style="color: #008000;">//</span><span style="color: #008000;">Create the dependencies or retrieve them from the registry</span><span style="color: #008080;"> 4</span> <span style="color: #800080;">$connection</span> = <span style="color: #0000ff;">new</span><span style="color: #000000;"> Connection();</span><span style="color: #008080;"> 5</span> <span style="color: #800080;">$session</span> = <span style="color: #0000ff;">new</span><span style="color: #000000;"> Session();</span><span style="color: #008080;"> 6</span> <span style="color: #800080;">$fileSystem</span> = <span style="color: #0000ff;">new</span><span style="color: #000000;"> FileSystem();</span><span style="color: #008080;"> 7</span> <span style="color: #800080;">$filter</span> = <span style="color: #0000ff;">new</span><span style="color: #000000;"> Filter();</span><span style="color: #008080;"> 8</span> <span style="color: #800080;">$selector</span> = <span style="color: #0000ff;">new</span><span style="color: #000000;"> Selector();</span><span style="color: #008080;"> 9</span> <span style="color: #008080;">10</span> <span style="color: #008000;">//</span><span style="color: #008000;">Pass them as constructor parameters</span><span style="color: #008080;">11</span> <span style="color: #800080;">$some</span> = <span style="color: #0000ff;">new</span> SomeComponent(<span style="color: #800080;">$connection</span>, <span style="color: #800080;">$session</span>, <span style="color: #800080;">$fileSystem</span>, <span style="color: #800080;">$filter</span>, <span style="color: #800080;">$selector</span><span style="color: #000000;">);</span><span style="color: #008080;">12</span> <span style="color: #008080;">13</span> <span style="color: #008000;">//</span><span style="color: #008000;"> ... or using setters</span><span style="color: #008080;">14</span> <span style="color: #008080;">15</span> <span style="color: #800080;">$some</span>->setConnection(<span style="color: #800080;">$connection</span><span style="color: #000000;">);</span><span style="color: #008080;">16</span> <span style="color: #800080;">$some</span>->setSession(<span style="color: #800080;">$session</span><span style="color: #000000;">);</span><span style="color: #008080;">17</span> <span style="color: #800080;">$some</span>->setFileSystem(<span style="color: #800080;">$fileSystem</span><span style="color: #000000;">);</span><span style="color: #008080;">18</span> <span style="color: #800080;">$some</span>->setFilter(<span style="color: #800080;">$filter</span><span style="color: #000000;">);</span><span style="color: #008080;">19</span> <span style="color: #800080;">$some</span>->setSelector(<span style="color: #800080;">$selector</span>);

Iこのオブジェクトはアプリケーション内のさまざまな場所で作成されます。依存コンポーネントが必要ない場合は、コード挿入部分に移動して、コンストラクターまたはセッター メソッドのパラメーターを削除する必要があります。この問題を解決するには、もう一度グローバル レジストリを使用してコンポーネントを作成します。ただし、オブジェクトを作成する前に、新しい抽象化レイヤーが追加されます:

<span style="color: #008080;"> 1</span> <span style="color: #000000;">php</span><span style="color: #008080;"> 2</span> <span style="color: #008080;"> 3</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> SomeComponent</span><span style="color: #008080;"> 4</span> <span style="color: #000000;">{</span><span style="color: #008080;"> 5</span> <span style="color: #008080;"> 6</span>     <span style="color: #008000;">//</span><span style="color: #008000;"> ...</span><span style="color: #008080;"> 7</span> <span style="color: #008080;"> 8</span>     <span style="color: #008000;">/*</span><span style="color: #008000;">*</span><span style="color: #008080;"> 9</span> <span style="color: #008000;">     * Define a factory method to create SomeComponent instances injecting its dependencies</span><span style="color: #008080;">10</span>      <span style="color: #008000;">*/</span><span style="color: #008080;">11</span>     <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> factory()</span><span style="color: #008080;">12</span> <span style="color: #000000;">    {</span><span style="color: #008080;">13</span> <span style="color: #008080;">14</span>         <span style="color: #800080;">$connection</span> = <span style="color: #0000ff;">new</span><span style="color: #000000;"> Connection();</span><span style="color: #008080;">15</span>         <span style="color: #800080;">$session</span> = <span style="color: #0000ff;">new</span><span style="color: #000000;"> Session();</span><span style="color: #008080;">16</span>         <span style="color: #800080;">$fileSystem</span> = <span style="color: #0000ff;">new</span><span style="color: #000000;"> FileSystem();</span><span style="color: #008080;">17</span>         <span style="color: #800080;">$filter</span> = <span style="color: #0000ff;">new</span><span style="color: #000000;"> Filter();</span><span style="color: #008080;">18</span>         <span style="color: #800080;">$selector</span> = <span style="color: #0000ff;">new</span><span style="color: #000000;"> Selector();</span><span style="color: #008080;">19</span> <span style="color: #008080;">20</span>         <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">new</span> self(<span style="color: #800080;">$connection</span>, <span style="color: #800080;">$session</span>, <span style="color: #800080;">$fileSystem</span>, <span style="color: #800080;">$filter</span>, <span style="color: #800080;">$selector</span><span style="color: #000000;">);</span><span style="color: #008080;">21</span> <span style="color: #000000;">    }</span><span style="color: #008080;">22</span> <span style="color: #008080;">23</span> }

現時点では、問題の始まりに戻ったようで、依存関係を作成しています。コンポーネント内では、毎回修正を加えて問題を解決する方法を探していますが、これは良いアプローチではありません。

これらの問題を解決するための実用的かつ洗練された方法は、コンテナの依存関係の注入を使用することです。前に説明したように、コンテナはグローバル レジストリとして機能し、コンテナの依存関係の注入をブリッジとして使用して依存関係を解決します。私たちのコードは結合度が低くなり、コンポーネントの複雑さが大幅に軽減されます。

<span style="color: #008080;"> 1</span> <span style="color: #000000;">php</span><span style="color: #008080;"> 2</span> <span style="color: #008080;"> 3</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> SomeComponent</span><span style="color: #008080;"> 4</span> <span style="color: #000000;">{</span><span style="color: #008080;"> 5</span> <span style="color: #008080;"> 6</span>     <span style="color: #0000ff;">protected</span> <span style="color: #800080;">$_di</span><span style="color: #000000;">;</span><span style="color: #008080;"> 7</span> <span style="color: #008080;"> 8</span>     <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> __construct(<span style="color: #800080;">$di</span><span style="color: #000000;">)</span><span style="color: #008080;"> 9</span> <span style="color: #000000;">    {</span><span style="color: #008080;">10</span>         <span style="color: #800080;">$this</span>->_di = <span style="color: #800080;">$di</span><span style="color: #000000;">;</span><span style="color: #008080;">11</span> <span style="color: #000000;">    }</span><span style="color: #008080;">12</span> <span style="color: #008080;">13</span>     <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> someDbTask()</span><span style="color: #008080;">14</span> <span style="color: #000000;">    {</span><span style="color: #008080;">15</span> <span style="color: #008080;">16</span>         <span style="color: #008000;">//</span><span style="color: #008000;"> Get the connection service</span><span style="color: #008080;">17</span> <span style="color: #008000;">        // Always returns a new connection</span><span style="color: #008080;">18</span>         <span style="color: #800080;">$connection</span> = <span style="color: #800080;">$this</span>->_di->get('db'<span style="color: #000000;">);</span><span style="color: #008080;">19</span> <span style="color: #008080;">20</span> <span style="color: #000000;">    }</span><span style="color: #008080;">21</span> <span style="color: #008080;">22</span>     <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> someOtherDbTask()</span><span style="color: #008080;">23</span> <span style="color: #000000;">    {</span><span style="color: #008080;">24</span> <span style="color: #008080;">25</span>         <span style="color: #008000;">//</span><span style="color: #008000;"> Get a shared connection service,</span><span style="color: #008080;">26</span> <span style="color: #008000;">        // this will return the same connection everytime</span><span style="color: #008080;">27</span>         <span style="color: #800080;">$connection</span> = <span style="color: #800080;">$this</span>->_di->getShared('db'<span style="color: #000000;">);</span><span style="color: #008080;">28</span> <span style="color: #008080;">29</span>         <span style="color: #008000;">//</span><span style="color: #008000;">This method also requires a input filtering service</span><span style="color: #008080;">30</span>         <span style="color: #800080;">$filter</span> = <span style="color: #800080;">$this</span>->_db->get('filter'<span style="color: #000000;">);</span><span style="color: #008080;">31</span> <span style="color: #008080;">32</span> <span style="color: #000000;">    }</span><span style="color: #008080;">33</span> <span style="color: #008080;">34</span> <span style="color: #000000;">}</span><span style="color: #008080;">35</span> <span style="color: #008080;">36</span> <span style="color: #800080;">$di</span> = <span style="color: #0000ff;">new</span><span style="color: #000000;"> Phalcon\DI();</span><span style="color: #008080;">37</span> <span style="color: #008080;">38</span> <span style="color: #008000;">//</span><span style="color: #008000;">Register a "db" service in the container</span><span style="color: #008080;">39</span> <span style="color: #800080;">$di</span>->set('db', <span style="color: #0000ff;">function</span><span style="color: #000000;">(){</span><span style="color: #008080;">40</span>     <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">new</span> Connection(<span style="color: #0000ff;">array</span><span style="color: #000000;">(</span><span style="color: #008080;">41</span>         "host" => "localhost",<span style="color: #008080;">42</span>         "username" => "root",<span style="color: #008080;">43</span>         "password" => "secret",<span style="color: #008080;">44</span>         "dbname" => "invo"<span style="color: #008080;">45</span> <span style="color: #000000;">    ));</span><span style="color: #008080;">46</span> <span style="color: #000000;">});</span><span style="color: #008080;">47</span> <span style="color: #008080;">48</span> <span style="color: #008000;">//</span><span style="color: #008000;">Register a "filter" service in the container</span><span style="color: #008080;">49</span> <span style="color: #800080;">$di</span>->set('filter', <span style="color: #0000ff;">function</span><span style="color: #000000;">(){</span><span style="color: #008080;">50</span>     <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">new</span><span style="color: #000000;"> Filter();</span><span style="color: #008080;">51</span> <span style="color: #000000;">});</span><span style="color: #008080;">52</span> <span style="color: #008080;">53</span> <span style="color: #008000;">//</span><span style="color: #008000;">Register a "session" service in the container</span><span style="color: #008080;">54</span> <span style="color: #800080;">$di</span>->set('session', <span style="color: #0000ff;">function</span><span style="color: #000000;">(){</span><span style="color: #008080;">55</span>     <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">new</span><span style="color: #000000;"> Session();</span><span style="color: #008080;">56</span> <span style="color: #000000;">});</span><span style="color: #008080;">57</span> <span style="color: #008080;">58</span> <span style="color: #008000;">//</span><span style="color: #008000;">Pass the service container as unique parameter</span><span style="color: #008080;">59</span> <span style="color: #800080;">$some</span> = <span style="color: #0000ff;">new</span> SomeComponent(<span style="color: #800080;">$di</span><span style="color: #000000;">);</span><span style="color: #008080;">60</span> <span style="color: #008080;">61</span> <span style="color: #800080;">$some</span>->someTask();

これで、コンポーネントは特定のサービスにアクセスするときにのみ必要となり、必要ない場合は必要になります。リソースを節約するための初期化も行われていません。コンポーネントは高度に分離されています。コンポーネントの動作やその他の側面は、コンポーネント自体には影響しません。
今回の実装方法¶

PhalconDIはサービスの依存性注入機能を実装するコンポーネントであり、それ自体がコンテナでもあります。

Phalcon は高度に分離されているため、PhalconDI は他のコンポーネントを統合するために使用されるフレームワークの重要な部分であり、開発者はこのコンポーネントを使用して、アプリケーション内のさまざまなクラス ファイルのインスタンスを依存関係に挿入したり管理したりすることもできます。

基本的に、このコンポーネントは制御の反転パターンを実装します。これに基づいて、オブジェクトはコンストラクターでパラメーターを受け取ったり、セッターを使用してインジェクションを実装するのではなく、サービスの依存関係インジェクションを直接要求します。コンポーネントの必要な依存関係を取得する方法が 1 つしかないため、これによりプログラム全体の複雑さが大幅に軽減されます。

さらに、このパターンによりコードのテスト容易性が向上し、エラーが発生しにくくなります。
コンテナへのサービスの登録¶

サービスは、フレームワーク自体または開発者によって登録できます。コンポーネント A がコンポーネント B (またはそのクラスのインスタンス) への呼び出しをリクエストする場合、コンポーネント B のインスタンスを作成する代わりに、コンテナからコンポーネント B への呼び出しをリクエストできます。

この働き方には多くの利点があります:

我们可以更换一个组件,从他们本身或者第三方轻松创建。
在组件发布之前,我们可以充分的控制对象的初始化,并对对象进行各种设置。
我们可以使用统一的方式从组件得到一个结构化的全局实例

服务可以通过以下几种方式注入到容器:

<span style="color: #008080;"> 1</span> <span style="color: #000000;">php</span><span style="color: #008080;"> 2</span> <span style="color: #008080;"> 3</span> <span style="color: #008000;">//</span><span style="color: #008000;">Create the Dependency Injector Container</span><span style="color: #008080;"> 4</span> <span style="color: #800080;">$di</span> = <span style="color: #0000ff;">new</span><span style="color: #000000;"> Phalcon\DI();</span><span style="color: #008080;"> 5</span> <span style="color: #008080;"> 6</span> <span style="color: #008000;">//</span><span style="color: #008000;">By its class name</span><span style="color: #008080;"> 7</span> <span style="color: #800080;">$di</span>->set("request", 'Phalcon\Http\Request'<span style="color: #000000;">);</span><span style="color: #008080;"> 8</span> <span style="color: #008080;"> 9</span> <span style="color: #008000;">//</span><span style="color: #008000;">Using an anonymous function, the instance will lazy loaded</span><span style="color: #008080;">10</span> <span style="color: #800080;">$di</span>->set("request", <span style="color: #0000ff;">function</span><span style="color: #000000;">(){</span><span style="color: #008080;">11</span>     <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">new</span><span style="color: #000000;"> Phalcon\Http\Request();</span><span style="color: #008080;">12</span> <span style="color: #000000;">});</span><span style="color: #008080;">13</span> <span style="color: #008080;">14</span> <span style="color: #008000;">//</span><span style="color: #008000;">Registering directly an instance</span><span style="color: #008080;">15</span> <span style="color: #800080;">$di</span>->set("request", <span style="color: #0000ff;">new</span><span style="color: #000000;"> Phalcon\Http\Request());</span><span style="color: #008080;">16</span> <span style="color: #008080;">17</span> <span style="color: #008000;">//</span><span style="color: #008000;">Using an array definition</span><span style="color: #008080;">18</span> <span style="color: #800080;">$di</span>->set("request", <span style="color: #0000ff;">array</span><span style="color: #000000;">(</span><span style="color: #008080;">19</span>     "className" => 'Phalcon\Http\Request'<span style="color: #008080;">20</span> ));

在上面的例子中,当向框架请求访问一个请求数据时,它将首先确定容器中是否存在这个”reqeust”名称的服务。

容器会反回一个请求数据的实例,开发人员最终得到他们想要的组件。

在上面示例中的每一种方法都有优缺点,具体使用哪一种,由开发过程中的特定场景来决定的。

用一个字符串来设定一个服务非常简单,但缺少灵活性。设置服务时,使用数组则提供了更多的灵活性,而且可以使用较复杂的代码。lambda函数是两者之间一个很好的平衡,但也可能导致更多的维护管理成本。

Phalcon\DI 提供服务的延迟加载。除非开发人员在注入服务的时候直接实例化一个对象,然后存存储到容器中。在容器中,通过数组,字符串等方式存储的服务都将被延迟加载,即只有在请求对象的时候才被初始化。

<span style="color: #008080;"> 1</span> <span style="color: #000000;">php</span><span style="color: #008080;"> 2</span> <span style="color: #008080;"> 3</span> <span style="color: #008000;">//</span><span style="color: #008000;">Register a service "db" with a class name and its parameters</span><span style="color: #008080;"> 4</span> <span style="color: #800080;">$di</span>->set("db", <span style="color: #0000ff;">array</span><span style="color: #000000;">(</span><span style="color: #008080;"> 5</span>     "className" => "Phalcon\Db\Adapter\Pdo\Mysql",<span style="color: #008080;"> 6</span>     "parameters" => <span style="color: #0000ff;">array</span><span style="color: #000000;">(</span><span style="color: #008080;"> 7</span>           "parameter" => <span style="color: #0000ff;">array</span><span style="color: #000000;">(</span><span style="color: #008080;"> 8</span>                "host" => "localhost",<span style="color: #008080;"> 9</span>                "username" => "root",<span style="color: #008080;">10</span>                "password" => "secret",<span style="color: #008080;">11</span>                "dbname" => "blog"<span style="color: #008080;">12</span> <span style="color: #000000;">          )</span><span style="color: #008080;">13</span> <span style="color: #000000;">    )</span><span style="color: #008080;">14</span> <span style="color: #000000;">));</span><span style="color: #008080;">15</span> <span style="color: #008080;">16</span> <span style="color: #008000;">//</span><span style="color: #008000;">Using an anonymous function</span><span style="color: #008080;">17</span> <span style="color: #800080;">$di</span>->set("db", <span style="color: #0000ff;">function</span><span style="color: #000000;">(){</span><span style="color: #008080;">18</span>     <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">new</span> Phalcon\Db\Adapter\Pdo\<span style="color: #008080;">Mysql</span>(<span style="color: #0000ff;">array</span><span style="color: #000000;">(</span><span style="color: #008080;">19</span>          "host" => "localhost",<span style="color: #008080;">20</span>          "username" => "root",<span style="color: #008080;">21</span>          "password" => "secret",<span style="color: #008080;">22</span>          "dbname" => "blog"<span style="color: #008080;">23</span> <span style="color: #000000;">    ));</span><span style="color: #008080;">24</span> });

以上这两种服务的注册方式产生相同的结果。然后,通过数组定义的,在后面需要的时候,你可以修改服务参数:

<span style="color: #008080;">1</span> <span style="color: #000000;">php</span><span style="color: #008080;">2</span> <span style="color: #008080;">3</span> <span style="color: #800080;">$di</span>->setParameter("db", 0, <span style="color: #0000ff;">array</span><span style="color: #000000;">(</span><span style="color: #008080;">4</span>     "host" => "localhost",<span style="color: #008080;">5</span>     "username" => "root",<span style="color: #008080;">6</span>     "password" => "secret"<span style="color: #008080;">7</span> ));

从容器中获得服务的最简单方式就是使用”get”方法,它将从容器中返回一个新的实例:

<span style="color: #008080;">1</span> <span style="color: #000000;">php</span><span style="color: #008080;">2</span>      <span style="color: #800080;">$request</span> = <span style="color: #800080;">$di</span>->get("request");

或者通过下面这种魔术方法的形式调用:

<span style="color: #008080;">1</span> <span style="color: #000000;">php</span><span style="color: #008080;">2</span> <span style="color: #008080;">3</span> <span style="color: #800080;">$request</span> = <span style="color: #800080;">$di</span>-><span style="color: #000000;">getRequest();</span><span style="color: #008080;">4</span> <span style="color: #008080;">5</span> Phalcon\DI 同时允许服务重用,为了得到一个已经实例化过的服务,可以使用 getShared() 方法的形式来获得服务。

具体的 Phalcon\Http\Request 请求示例:

<span style="color: #008080;">1</span> <span style="color: #000000;">php</span><span style="color: #008080;">2</span> <span style="color: #008080;">3</span> <span style="color: #800080;">$request</span> = <span style="color: #800080;">$di</span>->getShared("request");

参数还可以在请求的时候通过将一个数组参数传递给构造函数的方式:

<span style="color: #008080;">1</span> <span style="color: #000000;">php</span><span style="color: #008080;">2</span> <span style="color: #008080;">3</span> <span style="color: #800080;">$component</span> = <span style="color: #800080;">$di</span>->get("MyComponent", <span style="color: #0000ff;">array</span>("some-parameter", "other"))
声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
华为GT3 Pro和GT4的差异是什么?华为GT3 Pro和GT4的差异是什么?Dec 29, 2023 pm 02:27 PM

许多用户在选择智能手表的时候都会选择的华为的品牌,其中华为GT3pro和GT4都是非常热门的选择,不少用户都很好奇华为GT3pro和GT4有什么区别,下面就就给大家介绍一下二者。华为GT3pro和GT4有什么区别一、外观GT4:46mm和41mm,材质是玻璃表镜+不锈钢机身+高分纤维后壳。GT3pro:46.6mm和42.9mm,材质是蓝宝石玻璃表镜+钛金属机身/陶瓷机身+陶瓷后壳二、健康GT4:采用最新的华为Truseen5.5+算法,结果会更加的精准。GT3pro:多了ECG心电图和血管及安

function是什么意思function是什么意思Aug 04, 2023 am 10:33 AM

function是函数的意思,是一段具有特定功能的可重复使用的代码块,是程序的基本组成单元之一,可以接受输入参数,执行特定的操作,并返回结果,其目的是封装一段可重复使用的代码,提高代码的可重用性和可维护性。

CONNECTION_REFUSED什么意思CONNECTION_REFUSED什么意思Jul 31, 2023 pm 02:48 PM

CONNECTION_REFUSED是一种网络连接错误,通常会在试图连接到远程服务器时出现。当客户端设备试图建立一个与服务器的网络连接时,如果服务器拒绝该连接请求,就会返回一个CONNECTION_REFUSED错误。常见的原因包括:服务器未启动、服务器无法接受更多的连接请求、服务器防火墙阻止了该连接等。

修复:截图工具在 Windows 11 中不起作用修复:截图工具在 Windows 11 中不起作用Aug 24, 2023 am 09:48 AM

为什么截图工具在Windows11上不起作用了解问题的根本原因有助于找到正确的解决方案。以下是截图工具可能无法正常工作的主要原因:对焦助手已打开:这可以防止截图工具打开。应用程序损坏:如果截图工具在启动时崩溃,则可能已损坏。过时的图形驱动程序:不兼容的驱动程序可能会干扰截图工具。来自其他应用程序的干扰:其他正在运行的应用程序可能与截图工具冲突。证书已过期:升级过程中的错误可能会导致此issu简单的解决方案这些适合大多数用户,不需要任何特殊的技术知识。1.更新窗口和Microsoft应用商店应用程

connection error怎么解决connection error怎么解决Nov 07, 2023 am 10:44 AM

解决方法:1、检查网络连接;2、检查服务器状态;3、清除缓存和Cookie;4、检查防火墙和安全软件设置;5、尝试使用其他网络等等。

PHP Warning: mysqli_connect(): (HY000/2002): Connection refused的解决方法PHP Warning: mysqli_connect(): (HY000/2002): Connection refused的解决方法Jun 23, 2023 am 08:54 AM

如果你使用PHP连接MySQL数据库时遇到了以下错误提示:PHPWarning:mysqli_connect():(HY000/2002):Connectionrefused那么你可以尝试按照下面的步骤来解决这个问题。确认MySQL服务是否正常运行首先应该检查MySQL服务是否正常运行,如果服务未运行或者启动失败,就可能会导致连接被拒绝的错误。你可

如何修复无法连接到iPhone上的App Store错误如何修复无法连接到iPhone上的App Store错误Jul 29, 2023 am 08:22 AM

第1部分:初始故障排除步骤检查苹果的系统状态:在深入研究复杂的解决方案之前,让我们从基础知识开始。问题可能不在于您的设备;苹果的服务器可能会关闭。访问Apple的系统状态页面,查看AppStore是否正常工作。如果有问题,您所能做的就是等待Apple修复它。检查您的互联网连接:确保您拥有稳定的互联网连接,因为“无法连接到AppStore”问题有时可归因于连接不良。尝试在Wi-Fi和移动数据之间切换或重置网络设置(“常规”>“重置”>“重置网络设置”>设置)。更新您的iOS版本:

"enumerate()"函数在Python中的用途是什么?"enumerate()"函数在Python中的用途是什么?Sep 01, 2023 am 11:29 AM

在本文中,我们将了解enumerate()函数以及Python中“enumerate()”函数的用途。什么是enumerate()函数?Python的enumerate()函数接受数据集合作为参数并返回一个枚举对象。枚举对象以键值对的形式返回。key是每个item对应的索引,value是items。语法enumerate(iterable,start)参数iterable-传入的数据集合可以作为枚举对象返回,称为iterablestart-顾名思义,枚举对象的起始索引由start定义。如果我们忽

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

mPDF

mPDF

mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。

SecLists

SecLists

SecLists は、セキュリティ テスターの究極の相棒です。これは、セキュリティ評価中に頻繁に使用されるさまざまな種類のリストを 1 か所にまとめたものです。 SecLists は、セキュリティ テスターが必要とする可能性のあるすべてのリストを便利に提供することで、セキュリティ テストをより効率的かつ生産的にするのに役立ちます。リストの種類には、ユーザー名、パスワード、URL、ファジング ペイロード、機密データ パターン、Web シェルなどが含まれます。テスターはこのリポジトリを新しいテスト マシンにプルするだけで、必要なあらゆる種類のリストにアクセスできるようになります。

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser は、オンライン試験を安全に受験するための安全なブラウザ環境です。このソフトウェアは、あらゆるコンピュータを安全なワークステーションに変えます。あらゆるユーティリティへのアクセスを制御し、学生が無許可のリソースを使用するのを防ぎます。

PhpStorm Mac バージョン

PhpStorm Mac バージョン

最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール