MODx用のシンプルなPHPアプリケーションのリファクタリング

2011年9月2日、James Roteringによる投稿

PHPスキルレベル:中

MODxスキルレベル:初心者


説明:このマニュアルは、MODx Revolution用にPHPとHTMLが混在したコードでファイルを変換する方法を示しています。 これはPHPでの作業に慣れている人向けですが、まだMODxの基本を学んでいます。


以下の説明のほとんどに当てはまる場合、このガイドは役立ちます。

-PHPコードとHTMLを組み合わせたスクリプトを作成しました

-PHPのループと配列を理解していますか

-データベースに接続してエントリを取得するPHPコードを記述した

-MODxスニペットやその他の要素の仕組みについての一般的な考えがあります



たとえば、最近完了した実際のプロジェクトの簡略版を検討します。

アプリケーションはPHP / HTMLで開発され、次のことを行います。

-データベーステーブルからレコードのリストを取得します

-HTMLテーブルのエントリを表示します

-特定の列値で結果をフィルタリングするための2つのドロップダウン選択フィールドを表示します。



興味のある方は、 こちらのアプリケーションをご覧ください



PHPとHTMLの混合ファイルから始めます





このアプリケーションのソースコードは次のようになりました(わかりやすくするために簡略化されています)。



ファイル:acctCodes.php(オリジナルバージョン)

<html> <head> <title>    SFS</title> </head> <body> <h1>    SFS</title> <form> <!--  SELECT box --> <div> <label for="byCategory">  :</label> <select name="byCategory" id="byCategory"> <option> </option>
      
      



  <?php //   -     $values = //   -         foreach ($values as $value) { echo '<option value="' . $value . '">' . $value . '</option>'; } ?>
      
      



  </select> </div> <!--  SELECT box --> <div> <label for="byType">  :</label> <select name="byType" id="byType"> <option> </option>
      
      



  <?php $values = //   -         foreach ($values as $value) { echo '<option value="' . $value . '">' . $value . '</option>'; } ?>
      
      



  </select> </div> </form> <!--    --> <table id="acctCodes"> <thead> <!--  ,    <th>.    --> </thead> <tbody>
      
      



  <?php $records = //   -        foreach ($records as $record) { ?>
      
      



  <tr> <td><?php echo $record['category']; ?></td> <td><?php echo $record['status']; ?></td> <td><?php echo $record['account']; ?></td> <td><?php echo $record['acctType']; ?></td> <td><?php echo $record['title']; ?></td> <td><?php echo $record['definition']; ?></td> </tr>
      
      



  <?php } ?>
      
      



  </tbody> </table> </body> </html>
      
      





ここでは、PHPは非常に単純です。 クエリが実行されるコードの3つの独立したブロックがあり、結果は適切なHTMLタグで囲まれ、ページに表示されます。 3番目のブロックはやや奇妙です-かさばる厄介な「エコー」演算子ではなく、ループ内で通常のHTMLコードを使用するためにPHPコードが中断されます。

しかし、ここではそれほど複雑なことは起こりません。



ただし、MODxへの移行に備えて、いくつかのクリーニングを行う必要があります。



パート1:クリーニング(最初に値を取得し、次に出力を取得します)





MODxの(そして実際に)このPHPコードをクリーニングする最初のステップは、アプリケーションロジックとページレイアウトの混在を避けることです。 各リクエストを使用する前に実行する代わりに、すべてのリクエストを開始し、必要に応じてエコーを使用して結果を表示します。



結果は次のようになります(ここでも、わかりやすくするために非常に簡略化されています)。



ファイル:acctCodes.php(クリーンバージョン)

 <?php //   -     $values = //   -         $options1 = ''; foreach ($values as $value) { $options1 .= '<option value="' . $value . '">' . $value . '</option>'; } $values = //   -         $options2 = ''; foreach ($values as $value) { $options2 .= '<option value="' . $value . '">' . $value . '</option>'; } $records = //   -        $trrows = ''; foreach ($records as $record) { $trrows .= '<tr><td>' . $record['category'] . '</td><td>' . $record['status'] . '</td><td>' . $record['account'] . '</td><td>' . $record['acctType'] . '</td><td>' . $record['title'] . '</td><td>' . $record['definition'] . '</td></tr>'; } ?>
      
      



 <html> <head> <title>    SFS</title> </head> <body> <h1>    SFS</h1> <form> <!--  SELECT box --> <div> <label for="byCategory">  :</label> <select name="byCategory" id="byCategory"> <option> </option> <?php echo $options1; ?> </select> </div> <!--  SELECT box --> <div> <label for="byType">  :</label> <<font color="#006699">select name="byType" id="byType"> <option> </option> <?php echo $options2; ?> </select> </div> </form> <!--    --> <table id="acctCodes"> <thead> <!--  ,    <th>.    --> </thead> <tbody> <?php echo $trrows; ?> </tbody> </table> </body> </html>
      
      







これにより、マークアップの表示と編集がはるかに簡単になります。 すべてのPHPコードは4つのブロックに含まれています。最初のリクエストで値を設定し、次の3つの簡単なエコーコマンドでこれらの値を表示します。

この小さなWebアプリケーションをMODxに移植することはすでに受け入れられています。



パート2:スニペットとプレースホルダー





クリアしたコードをMODxに転送するには、追加の変更を加える必要があります。

HTMLコードは、MODxリソースに直接コピーできます。 (リソースは変更されなくなります!-約。)

ただし、PHPコードをスニペットといくつかのプレースホルダーに置き換える必要があります。



MODxリソースのコンテンツは次のようになります。

リソースMODx: 'acctCodes'

 [[accountCodes]] <html> <head> <title>    SFS</title> </head> <body> <h1>    SFS</h1> <form> <!--  SELECT box --> <div> <label for="byCategory">  :</label> <select name="byCategory" id="byCategory"> <option> </option> [[+options1]] </select> </div> <!--  SELECT box --> <div> <label for="byType">  :</label> <select name="byType" id="byType"> <option> </option> [[+options2]] </select> </div> </form> <!--    --> <table id="acctCodes"> <thead> <!--  ,    <th>.    --> </thead> <tbody> [[+trrows]] </tbody> </table> </body> </html>
      
      





リソースでは、PHPコードの4つのブロックがMODxタグに置き換えられました。 最初の[[accountCodes]]は、 accountCodesスニペットを呼び出します(まだ記述していません)。 次の3つのタグはプレースホルダーで、スニペットで設定された値に置き換えられます。

次に、このスニペットを記述する必要があります



パート3:スニペット





「accountCodes」スニペットには、このPHPの最初のブロック(すべてのリクエストとループ)からのコードが含まれます。 追加するのは、プレースホルダーを作成するためのMODx APIコードの数行だけです。



スニペット:「accountCodes」

 <?php //   -     $values = //   -         $options1 = ''; foreach ($values as $value) { $options1 .='<option value="' . $value . '">' . $value . '</option>'; } $values = //   -         $options2 = ''; foreach ($values as $value) { $options2 .= '<option value="' . $value . '">' . $value . '</option>'; } $records = //   -        $trrows = ''; foreach ($records as $record) { $trrows .= '<tr><td>' . $record['category'] . &nbsp; '</td><td>' . $record['status'] . '</td><td>' . $record['account'] . '</td><td>' . $record['acctType'] . '</td><td>' . $record['title'] . '</td><td>' . $record['definition'] . '</td></tr>'; } $modx->setPlaceholder('options1', $options1); $modx->setPlaceholder('options2', $options2); $modx->setPlaceholder('trrows', $trrows);
      
      







これがスニペットです。 元のPHPコードと比較すると、下部に3行の「setPlaceholder」が追加されています。 彼らは、MODxに、ページ上で下のプレースホルダー[[+ options1]]に出会った場合、それを$ options1の値に置き換える必要があることを伝えるだけです。 プレースホルダーは、スニペットからの出力値を処理するシンプルでエレガントな方法です。



これで、WebアプリケーションがMODx内で機能するために必要なすべての処理が完了しました。 ただし、MODxでより多くのAPI関数を使用して、アプリケーションをよりセクシーにするいくつかの追加手順を実行できます。 現在の実装を「満足」と評価します(元の「C」では作業を続けましょう。



パート4:チャンクを出力テンプレートとして使用する





現在のPHPコードに対する批判の1つは、マークアップとロジックが混在していることです。 「foreach」ループにはまだHTMLマークアップのチャンクが含まれています。

 foreach ($values as $value) { $options1 .= '<option value="' . $value . '">' . $value . '/option>'; }
      
      





この戦略は理想とはほど遠いです。上司がSkippyのHTMLエンコーダー(元の「Skippy the HTML code monkey」-約Per。)に尋ねるとします。各<option>タグにいくつかの追加属性を追加して、このアプリケーションのHTMLコード変更します。 しかし、HTMLコードモンキーであるSkippyを PHPスクリプトの近くに配置たくありません。



PHPでこの状況を修正するには、いくつかの方法があります。外部ファイルからHTMLコードを取得し、文字列を置き換えることが考えられます。 ただし、心配する必要はなく、適切なソリューションを見つける必要もありません。 このタスクのために、MODxは別のシンプルでエレガントなソリューションを提供します: プレースホルダー付きチャンク



上記のスニペットの「オプション」コードは、「オプション」と呼ばれるチャンクとして書き換えることができます。



チャンク:「オプション」

 <option value="[[+value]]">[[+value]]</option>
      
      





このチャンクには特別なものはありません-いくつかのプレースホルダーを備えたHTMLです。 「オプション」は、さまざまなリソースの複数のスニペットで、どこでも使用できるシンプルで便利なチャンクです。



ループでこのチャンクの値を使用するMODx APIコードをもう少し追加して、スニペットを変更できます。

 <?php //   -     $values = //   -         $options1 = ''; foreach ($values as $value) { $modx->setPlaceholder('value', $value); $options1 .= $modx->getChunk('option'); }
      
      





ここで、ループは$値のプレースホルダーを作成し、「オプション」チャンクの値を出力行に追加します。

これにより、すべてのHTMLコードをPHPから完全に分離できます。 Skippy (「HTMLコードモンキーをスキップ」)が属性を<option>要素に追加する必要がある場合、「option」チャンクを編集してこれを行うことができます。 (これらのプレースホルダーに触れないように言ってください!)



テーブルの行は同じ方法で実行できます。

チャンク:「trrows」

 <tr> <td>[[+category]]</td> <td>[[+status]]</td> <td>[[+account]]</td> <td>[[+acctType]]</td> <td>[[+title]]</td> <td>[[+definition]]</td> </tr>
      
      





そしてそれを呼び出すPHPコード

 each ($records as $record) { $trrows .= $modx->getChunk('trrows', $record); }
      
      





この例では、プレースホルダーをインストールする必要もありません。

$レコード連想配列を引数としてGetChunk()に渡すことができ、プレースホルダーは配列内のキー/値のペアごとに自動的に設定されます!

(** MODX Awesomeness!あなたはそれに浸っています!**) (いくつかの粉末洗剤のスローガンとの類似?-約Per。)



これで、すべてのHTMLチャンクをチャンクに保存し、スニペットを次のように書き換えることができます。

 <?php //   -     $values = //   -         $options1 = ''; foreach ($values as $value) { $modx->setPlaceholder('value', $value); $options1 .= $modx->getChunk('option'); } $values = //   -         $options2 = ''; foreach ($values as $value) { $modx->setPlaceholder('value', $value); $options2 .= $modx->getChunk('option'); } $records = //   -        $trrows = ''; foreach ($records as $record) { $trrows .= $modx->getChunk('trrows', $record); } $modx->setPlaceholder('options1', $options1); $modx->setPlaceholder('options2', $options2); $modx->setPlaceholder('trrows', $trrows);
      
      





すでに非常に良く見え始めています。 出力テンプレートにMODx APIを使用しましたが、スニペットは非常にきれいに見えます。 それにもかかわらず、私を悩ませ、潜在的に問題がある可能性があることが1つあります-現在、アプリケーションのロジックに添付されたMODx APIコールがあります。 このWebページにこの形式で印刷されたデータのみが必要になることを100%確信している場合、これは実際には問題ではありません。 ただし、このデータをMODxの外部の別の場所で使用する必要がある可能性がある場合は、メインアプリケーションロジックをMODxエンティティから分離しておくことをお勧めします。



現時点では、アプリケーションの評価は「良好」です(オリジナルでは「B」) 。 最後の一歩を踏み出し、評価を「優れた」 (元の-「A」)に上げましょう。



パート5:アプリケーションロジックの分離





最後のステップで必要なことは、スニペットを2つの部分に分割することだけです。 最初の部分にはアプリケーションロジックが含まれ、すべての配列を1つの大きな配列のメンバーとして返します。

これは純粋なPHPで行われ、サーバーにファイルとして保存するのが理想的です。



2番目の部分はスニペットそのものです。 最初にロジックファイルから返された配列を受け取り、チャンクを使用して結果行を標準化し、最後にプレースホルダーをインストールして結果をリソースに表示します。



これがすべての終了方法です。



ファイル:acctCodes.php

 <?php //   -     $values = //   -         $values2 = //   -         $records = //   -        return array('values'=>$values, 'values2'=>$values2, 'records'=>$records); ?>
      
      







スニペット: 'acctCodes'

 <?php $data = include_once(MY_INCLUDE_PATH . 'acctCodes.php'); $options1 = ''; foreach ($data['values'] as $value) { $modx->setPlaceholder('value', $value); $options1 .= $modx->getChunk('option'); } $options2 = ''; foreach ($data['values2'] as $value) { $modx->setPlaceholder('value', $value); $options2 .= $modx->getChunk('option'); } $trrows = ''; foreach ($data['records'] as $record) { $trrows .= $modx->getChunk('trrows', $record); } $modx->setPlaceholder('options1', $options1); $modx->setPlaceholder('options2', $options2); $modx->setPlaceholder('trrows', $trrows);
      
      





アヒルが並んでいます。 私たちがやったことを見てみましょう:

-サーバー上のファイルにアプリケーションロジックがあります(MODxの完全に外部)。

-データを(HTMLマークアップなしで)MODxスニペットに直接転送します。

「MODxに出力レコードのテンプレートを制御させました。」

-リソースの上部にある1つのスニペットにすべてのプレースホルダー値を設定します。

-必要に応じて、プレースホルダーを使用してページにデータを表示します。



元のPHPとHTMLの混合ファイルから長い道のりを歩んできましたよね? この最終的な実装を「優れた」 (元の「A」)と評価します。 ただし、さまざまな問題領域を分離する方法について、おそらく誰かがより良いアイデアを持っています。 しかし、私のようなPHPの愛好家にとっては、ここから始めるのが良いでしょう。



MODxで使用するシンプルなPHPアプリケーションを作成する際の重要な問題のいくつかを学んだことを願っています。 このガイドに関するご意見、ご質問、ご提案は、 ここのコメントに自由にお寄せください



ご注意 あたり -結果として作成された:

-リソースacctCodes (パート2)

-accountCodesスニペット(パート5)

-ファイルacctCodes.php (パート5)

- オプションチャンク(パート4)

-チャンクを捨てる (パート4)



All Articles