独自の PHP フレームワークを構築する - コンポーネントを作成するためのメカニズム
前のブログで、基本的な Model クラスを完成させましたが、データベースの pdo インスタンスを作成したとき、それはハードな構成であったことを覚えておく必要があります。 、Model クラスで直接強化されます。
コードは次のとおりです:
<code class="sourceCode php"> <span class="kw">public</span> <span class="kw">static</span> <span class="kw">function</span> getDb<span class="ot">()</span> { <span class="kw">if</span> <span class="ot">(</span><span class="fu">empty</span><span class="ot">(</span><span class="kw">static</span>::<span class="kw">$pdo</span><span class="ot">))</span> { <span class="kw">$host</span> = <span class="st">'localhost'</span><span class="ot">;</span> <span class="kw">$database</span> = <span class="st">'sf'</span><span class="ot">;</span> <span class="kw">$username</span> = <span class="st">'jun'</span><span class="ot">;</span> <span class="kw">$password</span> = <span class="st">'jun'</span><span class="ot">;</span> <span class="kw">$options</span> = <span class="ot">[</span> <span class="kw">PDO</span>::<span class="kw">ATTR_EMULATE_PREPARES</span> => <span class="kw">false</span><span class="ot">,</span> <span class="kw">PDO</span>::<span class="kw">ATTR_STRINGIFY_FETCHES</span> => <span class="kw">false</span> <span class="ot">];</span> <span class="kw">static</span>::<span class="kw">$pdo</span> = <span class="kw">new</span> <span class="kw">PDO</span><span class="ot">(</span><span class="st">"mysql:host=</span><span class="kw">$host</span><span class="st">;dbname=</span><span class="kw">$database</span><span class="st">"</span><span class="ot">,</span> <span class="kw">$username</span><span class="ot">,</span> <span class="kw">$password</span><span class="ot">,</span> <span class="kw">$options</span><span class="ot">);</span> <span class="kw">static</span>::<span class="kw">$pdo</span>-><span class="fu">exec</span><span class="ot">(</span><span class="st">"set names 'utf8'"</span><span class="ot">);</span> } <span class="kw">return</span> <span class="kw">static</span>::<span class="kw">$pdo</span><span class="ot">;</span> }</code>
これは明らかに不適切です。変更する場合は、フレームワークを変更するコードを取得する必要があります。では、抽出してみましょう。
まず、対応する構成ファイルに構成を取得する必要があります。simple-framework フォルダーの下に config フォルダーを作成し、db.php ファイルを追加します。関連する構成を内部に追加します。
コードは次のとおりです:
<code class="sourceCode php"><span class="kw">return</span> <span class="ot">[</span> <span class="st">'class'</span> => <span class="st">'\PDO'</span><span class="ot">,</span> <span class="st">'dsn'</span> => <span class="st">'mysql:host=localhost;dbname=sf'</span><span class="ot">,</span> <span class="st">'username'</span> => <span class="st">'jun'</span><span class="ot">,</span> <span class="st">'password'</span> => <span class="st">'jun'</span><span class="ot">,</span> <span class="st">'options'</span> => <span class="ot">[</span> \<span class="kw">PDO</span>::<span class="kw">ATTR_EMULATE_PREPARES</span> => <span class="kw">false</span><span class="ot">,</span> \<span class="kw">PDO</span>::<span class="kw">ATTR_STRINGIFY_FETCHES</span> => <span class="kw">false</span><span class="ot">,</span> <span class="ot">],</span><span class="ot">];</span></code>
実際、これは pdo インスタンスを作成するために必要なパラメーターを含む配列を返します。 pdo インスタンスを作成する前に、db.php ファイルを必要とするだけです。
コードは次のとおりです。
<code class="sourceCode php"> <span class="kw">public</span> <span class="kw">static</span> <span class="kw">function</span> getDb<span class="ot">()</span> { <span class="kw">if</span> <span class="ot">(</span><span class="fu">empty</span><span class="ot">(</span><span class="kw">static</span>::<span class="kw">$pdo</span><span class="ot">))</span> { <span class="kw">$config</span> = <span class="kw">require</span><span class="ot">(</span><span class="st">'../config/db.php'</span><span class="ot">);</span> <span class="kw">static</span>::<span class="kw">$pdo</span> = <span class="kw">new</span> <span class="kw">$config</span><span class="ot">[</span><span class="st">'class'</span><span class="ot">](</span><span class="kw">$config</span><span class="ot">[</span><span class="st">'dsn'</span><span class="ot">],</span> <span class="kw">$config</span><span class="ot">[</span><span class="st">'username'</span><span class="ot">],</span> <span class="kw">$config</span><span class="ot">[</span><span class="st">'password'</span><span class="ot">],</span> <span class="kw">$config</span><span class="ot">[</span><span class="st">'options'</span><span class="ot">]);</span> <span class="kw">static</span>::<span class="kw">$pdo</span>-><span class="fu">exec</span><span class="ot">(</span><span class="st">"set names 'utf8'"</span><span class="ot">);</span> } <span class="kw">return</span> <span class="kw">static</span>::<span class="kw">$pdo</span><span class="ot">;</span> }</code>
これでも、設定ファイルを要求するときに、レイヤーごとに相対位置を確認する必要があります。間違っている場合は見つかりません。そして、将来、構成ファイルまたはモデル ファイルの場所が変更されると、相対位置が変更されるため、このコードを変更する必要があります。絶対アドレスに変更すると、少なくとも構成ファイルの場所は変更されないため、このコードを変更する必要がなくなります。
しかし、絶対アドレスに変更するには、simple-framework フォルダーのアドレスを見つける必要があるため、public/index.php で simple-framework フォルダーのアドレスをマークする定数を定義します。
public/index.php コードは次のとおりです。
<code class="sourceCode php"><span class="kw"><?php</span><span class="fu">define</span><span class="ot">(</span><span class="st">'SF_PATH'</span><span class="ot">,</span> <span class="fu">dirname</span><span class="ot">(</span><span class="kw">__DIR__</span><span class="ot">));</span><span class="kw">require_once</span><span class="ot">(</span><span class="kw">SF_PATH</span> . <span class="st">'/vendor/autoload.php'</span><span class="ot">);</span><span class="kw">$application</span> = <span class="kw">new</span> sf\web\Application<span class="ot">();</span><span class="kw">$application</span>->run<span class="ot">();</span></code>
は定数 SF_PATH を定義しており、モデル内の require は次のコードに変更できます。 :
<code class="sourceCode php"><span class="kw">$config</span> = <span class="kw">require</span><span class="ot">(</span><span class="kw">SF_PATH</span> . <span class="st">'/config/db.php'</span><span class="ot">);</span></code>
OK、これは良さそうです。
しかし、将来キャッシュ インスタンスが必要になった場合は、もう一度 getDb メソッドを記述する必要があるのではないかと考えました。この状況を避けたい場合は、抽象化する必要がありますか?それをどう抽象化するか?
現時点では、メソッドが必要になる場合があります。作成する必要があるインスタンスを指定するだけで、対応するパラメーターを受け取り、対応するインスタンスが作成されます。これは素晴らしいことではないでしょうか?
インスタンスを作成するには、src フォルダーに Sf.php を作成し、その中に createObject メソッドを作成する必要があります。
しかし、今回は、pdo インスタンスを作成するときに、特定の数のパラメーターを特定の順序で渡す必要があるという別の問題が発生しました。ただし、他のインスタンスでは、後で作成する必要があるパラメーターの数が異なります。渡される 番号とキーが違うのですがどうすればよいでしょうか?
したがって、パラメータを保存し、インスタンスが実際に作成されるときに使用するためにそれらを取得するメカニズムが必要です。 src/db フォルダーに Connection クラスを作成できます。SF の createObject メソッドは、このクラスのインスタンスを作成し、pdo インスタンスを作成するためのメソッドを提供します。
Sf.php のコードは次のとおりです。
<code class="sourceCode php"><span class="kw"><?php</span><span class="co">/**</span><span class="co"> * Sf is a helper class serving common framework functionalities.</span><span class="co"> * </span><span class="kw">@author</span><span class="co"> Harry Sun </span><span class="kw"><sunguangjun</span><span class="ot">@126.com</span><span class="kw">></span><span class="co"> */</span><span class="kw">class</span> Sf{ <span class="co">/**</span><span class="co"> * Creates a new object using the given configuration.</span><span class="co"> * You may view this method as an enhanced version of the `new` operator.</span><span class="co"> * </span><span class="kw">@param</span><span class="co"> </span><span class="kw">string</span><span class="co"> $name the object name</span><span class="co"> */</span> <span class="kw">public</span> <span class="kw">static</span> <span class="kw">function</span> createObject<span class="ot">(</span><span class="kw">$name</span><span class="ot">)</span> { <span class="kw">$config</span> = <span class="kw">require</span><span class="ot">(</span><span class="kw">SF_PATH</span> . <span class="st">"/config/</span><span class="kw">$name</span><span class="st">.php"</span><span class="ot">);</span> <span class="co">// create instance</span> <span class="kw">$instance</span> = <span class="kw">new</span> <span class="kw">$config</span><span class="ot">[</span><span class="st">'class'</span><span class="ot">]();</span> <span class="fu">unset</span><span class="ot">(</span><span class="kw">$config</span><span class="ot">[</span><span class="st">'class'</span><span class="ot">]);</span> <span class="co">// add attributes</span> <span class="kw">foreach</span> <span class="ot">(</span><span class="kw">$config</span> <span class="kw">as</span> <span class="kw">$key</span> => <span class="kw">$value</span><span class="ot">)</span> { <span class="kw">$instance</span>-><span class="kw">$key</span> = <span class="kw">$value</span><span class="ot">;</span> } <span class="kw">return</span> <span class="kw">$instance</span><span class="ot">;</span> }}</code>
Sf クラスには名前空間がないため、psr4 の規則に準拠していません。次の文を public/index に手動で追加する必要があります:
<code class="sourceCode php"><span class="kw">require_once</span><span class="ot">(</span><span class="kw">SF_PATH</span> . <span class="st">'/src/Sf.php'</span><span class="ot">);</span></code>
Connection.php のコードは次のとおりです:
<code class="sourceCode php"><span class="kw"><?php</span><span class="kw">namespace</span> sf\db<span class="ot">;</span><span class="kw">use</span> <span class="kw">PDO</span><span class="ot">;</span><span class="co">/**</span><span class="co"> * Connection represents a connection to a database via [PDO](php.net/manual/en/book.pdo.php).</span><span class="co"> * </span><span class="kw">@author</span><span class="co"> Harry Sun </span><span class="kw"><sunguangjun</span><span class="ot">@126.com</span><span class="kw">></span><span class="co"> */</span><span class="kw">class</span> Connection{ <span class="co">/**</span><span class="co"> * </span><span class="kw">@var</span><span class="co"> </span><span class="st">string</span><span class="co"> </span><span class="st">the</span><span class="co"> </span><span class="st">Data</span><span class="co"> </span><span class="st">Source</span><span class="co"> </span><span class="st">Name,</span><span class="co"> </span><span class="st">or</span><span class="co"> </span><span class="st">DSN,</span><span class="co"> </span><span class="st">contains</span><span class="co"> </span><span class="st">the</span><span class="co"> </span><span class="st">information</span><span class="co"> </span><span class="st">required</span><span class="co"> </span><span class="st">to</span><span class="co"> </span><span class="st">connect</span><span class="co"> </span><span class="st">to</span><span class="co"> </span><span class="st">the</span><span class="co"> </span><span class="st">database.</span><span class="co"> * Please refer to the [PHP manual](http://www.php.net/manual/en/function.PDO-construct.php) on</span><span class="co"> * the format of the DSN string.</span><span class="co"> * </span><span class="kw">@see</span><span class="co"> charset</span><span class="co"> */</span> <span class="kw">public</span> <span class="kw">$dsn</span><span class="ot">;</span> <span class="co">/**</span><span class="co"> * </span><span class="kw">@var</span><span class="co"> </span><span class="st">string</span><span class="co"> </span><span class="st">the</span><span class="co"> </span><span class="st">username</span><span class="co"> </span><span class="st">for</span><span class="co"> </span><span class="st">establishing</span><span class="co"> </span><span class="st">DB</span><span class="co"> </span><span class="st">connection.</span><span class="co"> </span><span class="st">Defaults</span><span class="co"> </span><span class="st">to</span><span class="co"> </span><span class="st">`null`</span><span class="co"> </span><span class="st">meaning</span><span class="co"> </span><span class="st">no</span><span class="co"> </span><span class="st">username</span><span class="co"> </span><span class="st">to</span><span class="co"> </span><span class="st">use.</span><span class="co"> */</span> <span class="kw">public</span> <span class="kw">$username</span><span class="ot">;</span> <span class="co">/**</span><span class="co"> * </span><span class="kw">@var</span><span class="co"> </span><span class="st">string</span><span class="co"> </span><span class="st">the</span><span class="co"> </span><span class="st">password</span><span class="co"> </span><span class="st">for</span><span class="co"> </span><span class="st">establishing</span><span class="co"> </span><span class="st">DB</span><span class="co"> </span><span class="st">connection.</span><span class="co"> </span><span class="st">Defaults</span><span class="co"> </span><span class="st">to</span><span class="co"> </span><span class="st">`null`</span><span class="co"> </span><span class="st">meaning</span><span class="co"> </span><span class="st">no</span><span class="co"> </span><span class="st">password</span><span class="co"> </span><span class="st">to</span><span class="co"> </span><span class="st">use.</span><span class="co"> */</span> <span class="kw">public</span> <span class="kw">$password</span><span class="ot">;</span> <span class="co">/**</span><span class="co"> * </span><span class="kw">@var</span><span class="co"> </span><span class="st">array</span><span class="co"> </span><span class="st">PDO</span><span class="co"> </span><span class="st">attributes</span><span class="co"> </span><span class="st">(name</span><span class="co"> </span><span class="st">=></span><span class="co"> </span><span class="st">value)</span><span class="co"> * to establish a DB connection. Please refer to the</span><span class="co"> * [PHP manual](http://www.php.net/manual/en/function.PDO-setAttribute.php) for</span><span class="co"> * details about available attributes.</span><span class="co"> */</span> <span class="kw">public</span> <span class="kw">$attributes</span><span class="ot">;</span> <span class="kw">public</span> <span class="kw">function</span> getDb<span class="ot">()</span> { <span class="kw">return</span> <span class="kw">new</span> <span class="kw">PDO</span><span class="ot">(</span><span class="kw">$this</span>->dsn<span class="ot">,</span> <span class="kw">$this</span>->username<span class="ot">,</span> <span class="kw">$this</span>->password<span class="ot">,</span> <span class="kw">$this</span>->attributes<span class="ot">);</span> }}</code>
宣言dsnは表示されませんが、/username/passwordとattributes属性も実行可能ですが、誰もがこのクラスを見たときにどの属性であるかがわかるように、宣言した方が良いと思いますそこにいるよ。
Model クラスの getDb メソッドを次のコードに変更します:
<code class="sourceCode php"> <span class="kw">public</span> <span class="kw">static</span> <span class="kw">function</span> getDb<span class="ot">()</span> { <span class="kw">if</span> <span class="ot">(</span><span class="fu">empty</span><span class="ot">(</span><span class="kw">static</span>::<span class="kw">$pdo</span><span class="ot">))</span> { <span class="kw">static</span>::<span class="kw">$pdo</span> = Sf::createObject<span class="ot">(</span><span class="st">'db'</span><span class="ot">)</span>->getDb<span class="ot">();</span> <span class="kw">static</span>::<span class="kw">$pdo</span>-><span class="fu">exec</span><span class="ot">(</span><span class="st">"set names 'utf8'"</span><span class="ot">);</span> } <span class="kw">return</span> <span class="kw">static</span>::<span class="kw">$pdo</span><span class="ot">;</span> }</code>
Sf を使用することを忘れないでください。
設定内の db.php もそれに応じて変更する必要があります。コードは次のとおりです。
<code class="sourceCode php"><span class="kw"><?php</span><span class="kw">return</span> <span class="ot">[</span> <span class="st">'class'</span> => <span class="st">'\sf\db\Connection'</span><span class="ot">,</span> <span class="st">'dsn'</span> => <span class="st">'mysql:host=localhost;dbname=sf'</span><span class="ot">,</span> <span class="st">'username'</span> => <span class="st">'jun'</span><span class="ot">,</span> <span class="st">'password'</span> => <span class="st">'jun'</span><span class="ot">,</span> <span class="st">'attributes'</span> => <span class="ot">[</span> \<span class="kw">PDO</span>::<span class="kw">ATTR_EMULATE_PREPARES</span> => <span class="kw">false</span><span class="ot">,</span> \<span class="kw">PDO</span>::<span class="kw">ATTR_STRINGIFY_FETCHES</span> => <span class="kw">false</span><span class="ot">,</span> <span class="ot">],</span><span class="ot">];</span></code>
結局、オプションを属性に変更しました。 、PDOドキュメントにあります。ここで書かれているのは属性です。
さて、今日はここまでにしましょう。プロジェクトの内容やブログの内容も Github に載せる予定ですので、皆様からのご提案をお待ちしております。
コード: https://github.com/CraryPrimitiveMan/simple-framework/tree/0.8
ブログプロジェクト: https://github.com/CraryPrimitiveMan/create-your-own- php-framework