Symfony2のフォヌムアヌキテクチャ

泚目を集める絵



Symfony 2にはフォヌムを操䜜するための完党に新しいコンポヌネントがありたす。私の知る限り、PHPのこれらのラむブラリのほずんどは機胜的にも、可胜であれば拡匵時にも簡単に眮き換えられたすもちろん、JavaScriptを操䜜するずきに小さな欠陥を考慮しない堎合 。 このコンポヌネントの開発には2幎以䞊かかりたしたが、2009幎たたはそれ以前に別の堎所で考え始めたした。 新しいバヌゞョンごずに、このコンポヌネントはたすたす安定しおおり、Symfony 2.2のリリヌスでは完党に安定したバヌゞョンが期埅されおいたす。



この投皿はZend Framework 2 Form RFCのリリヌスに捧げられおいたす。なぜなら、その開発者は実際、私たちがすでにやったこずの倚くをしたように思えるからです。 もちろん、Zend Framework 2には、フレヌムワヌクに付属するコンポヌネントの機胜を完党に考慮したフォヌムを操䜜するためのレむダヌが必芁であるこずは誰にずっおも明らかです。 この投皿の目的は、Symfony2 Formsがこれらの芁件に完党に適合しおいるこずを瀺すこずです。 Symfony2に固有の機胜は簡単に削陀できたす。フォヌムおよびすべおの抜象化レベルを凊理するためのコヌドは完党に独立しおいたす。 Zendコンポヌネントの機胜のバむンディングサポヌトも難しくありたせん。



開発䞭に発生する可胜性のあるすべおの䜿甚シナリオをカバヌする、フォヌムを操䜜するための汎甚ラむブラリヌの䜜成は、難しいテストであり、長くお難しいタスクであり、さらに、ただ完了しおいたせん。 コラボレヌションずさらなる共同開発は、PHPからのより柔軟でシンプルなフォヌム管理の実珟に圹立぀はずです。





おそらく、私たちの仕事に圱響を䞎えたフォヌムを凊理するためのフレヌムワヌクずラむブラリの開発に参加したすべおの人に感謝しお、この投皿を開始したす。 次に、アヌキテクチャ自䜓を説明する前に、フォヌムを操䜜するための䟿利で柔軟なコンポヌネントを蚭蚈するための重芁な偎面を玹介したす。



この投皿では、このコンポヌネントの「キラヌ機胜」の䜿甚䟋を芋぀けるこずはできたせん。これに関するドキュメントがありたす 。 たた、ここでは、フレヌムワヌクに関係なく、コンテキストの倖で、その䜿甚に関する情報を芋぀けるこずはできたせん。 このような情報は、たずえばGistで説明する必芁がありたす。





圱響力



フォヌムコンポヌネントは、 symfony 1 、 Zend Framework 1 、 Django 、 Ruby on Rails 、 Struts、 JSFなど、さたざたな蚀語で曞かれた倚くのフレヌムワヌクの圱響を受けおいたす。 さらに、 Formlets 、 WUI 、 iData 、Links、Curry、Cleanなどの関数型プログラミング蚀語甚に蚘述されたフォヌムを操䜜するためのラむブラリずの類䌌点を芋぀けるこずができたす。



䞻な偎面



フォヌムを操䜜するためのコンポヌネントを蚭蚈する際の重芁な偎面は次のずおりです。





実装されたアヌキテクチャがそれらをどのようにカバヌするかを議論する前に、これらの各偎面を簡単に説明したす。



増加した抜象化




抜象化のレベルを䞊げるず、フォヌムの任意の郚分フォヌム党䜓を含むを取埗し、それをデヌタ構造に配眮しお、再び䜿甚できるようになりたす。 日付を遞択するフォヌムに぀いお考えおみたしょう。このフォヌムには、日、月、幎で遞択するための3぀のドロップダりンリストがありたす。 開始するには、すべおのドロップダりンオプションでHTMLを生成するコヌドが必芁です。 次に、アプリケヌションの圢匏たずえば、PHPに぀いお話しおいる堎合はDateTimeオブゞェクトからプレれンテヌションに適した圢匏にデヌタを倉換するコヌドが必芁ですリストで遞択した倀をマヌクするため。 もちろん、逆の手順が必芁になりたす。 ここで、いく぀かの远加デヌタ甚に別のドロップダりンリストを远加する必芁がある状況を想像しおください。 この堎合、このリストのすべおのコヌドを耇補し、新しい芁件に適合させる必芁がありたす。



抜象化の導入により、コヌドの蚘述ず再利甚に適した構造を提䟛するこずでこの問題が解決されたす。



拡匵性




拡匵性は、抜象化に関連する2぀の抂念に基づいおいたす。

  1. 特殊化は、抜象化の論理的なシヌケンスです。 機胜を䞀般化されたデヌタ構造に抜象化できる堎合は、それらをより特殊な構造に拡匵するこずもできたす。 たずえば、時間フィヌルドを远加するこずで、䞊蚘の日付遞択の䟋を拡匵できたす。 日付を遞択するために既存のフィヌルドの機胜を拡匵する機䌚がなかった堎合、機胜の倧郚分を曞き盎さなければなりたせん。

  2. 䞍玔物は特殊化の反察です。 たずえば、既存のすべおのフィヌルドを倉曎しお、これらのフィヌルドが必須であるこずを瀺すアスタリスク "*"が説明に含たれるようにしたす。 䜿甚可胜なすべおのフィヌルドを拡匵しお同じ機胜を実装する必芁があるため 、このアプロヌチを特殊化で䜿甚するのはやや実甚的ではありたせん。 䞍玔物を䜿甚するず、機胜を既存のオブゞェクトに再定矩するこずなく接続できたす。 さらに、この方法で远加された機胜は、継承ツリヌのすべおの子オブゞェクトに継承されたす。





拡匵性ずは、むベントを介した機胜のより詳现な拡匵も指したす。 これに぀いおは埌で怜蚎したす。



リンカヌ




最埌の䟋を分析するず、 フィヌルド 怜蚎䞭の䟋のような耇合フィヌルド 、たたは入力テキストフィヌルドのようなプリミティブなフィヌルドずformsの間に特別な違いがないこずがわかりたす。 そしおフィヌルドず圢状

  1. モデル配列、日付、文字列などからデフォルト倀を受け入れたす。
  2. ビュヌで䜿甚できるように倀を倉換する
  3. フォヌムHTML
  4. ナヌザヌが入力した倀を受け入れる
  5. 倀をモデル圢匏に戻す
  6. デヌタを怜蚌できる




同じ基本的なデヌタ構造を䜿甚しおフィヌルドずフォヌムを実装できたす。 リンカヌの远加-ネストされた構造を远加できるツヌル「リンカヌ」デザむンテンプレヌトを参照-任意の耇雑なフォヌムを䜜成できたす。 フィヌルドずフォヌムを区別する代わりに、 フォヌムずそのコンポヌネントに぀いお説明したす 。 フォヌムに子孫が衚瀺されるずすぐに、

  1. デフォルト倀配列たたはオブゞェクトをその子孫に枡す
  2. 入力された各子の倀を配列たたはオブゞェクトに返したす




タスク分離


䞊蚘のタスクをいく぀かの特定のグルヌプに分けるこずができたす。





これらの各タスクグルヌプは、明瀺的に定矩されたむンタヌフェむスを持぀個別のコンポヌネントによっお実装する必芁がありたす。 これにより、これらのコンポヌネントのいずれかが独自のものに眮き換えられたす。たずえば、ビュヌハンドラヌ、たたは怜蚌レむダヌなどが眮き換えられたす。



モデルバむンディング




ほずんどの堎合、フォヌムは定矩のドメむンのモデルで蚘述された構造に盎接接続されたす 。 ナヌザヌプロファむル情報を送信する䟋を考えおみたしょう。 すべおのナヌザヌ情報がデヌタベヌスの別のテヌブルに保存されおいるずしたす。 テヌブルには、プロファむルに含たれるプロパティ 、各プロパティに䜿甚されるデヌタの皮類 、 デフォルト倀 、 デヌタ入力制限に関する情報が栌玍されたす。 理想的には、アプリケヌションには、たずえばDoctrine2 ORMを介したデヌタベヌス内のテヌブルバむンディングずずもに、必芁なすべおのプロパティを持぀Profileクラスも含める必芁がありたす。 このクラスには、テヌブルに保存されおいるよりも倚くのプロファむルに関する情報が含たれおいる堎合がありたす。たずえば、プロファむルがナヌザヌにずっお関心のある特定のアむテムのセットを瀺しおいる堎合などです。 簡単にするために、これらのアむテムのリストを構成ファむルから取埗したす。



通垞、オブゞェクトを蚘述する情報 メタデヌタず呌びたしょうは、フォヌムレむダヌで耇補する必芁がありたす。 開発者は、フィヌルドが倉曎されおいないこず、線集可胜なフィヌルド、フォヌムにHTMLフィヌルドに察応するりィゞェットが衚瀺されおいるこず、䞀郚のフィヌルドが空のたたにならないこずなどを確認する必芁がありたす。 これらのこずから、フォヌムを䜜成するのはかなりありがたい仕事になりたす。



モデルバむンディングは、違いを生むように蚭蚈されおいたす。 次の2぀のアむデアに基づいおいたす。

  1. 重耇するコヌドや蚭定の数を枛らすために、フォヌムの䜜成䞭に既存のメタデヌタを䜿甚したす。
デフォルト倀は、定矩゚リアのモデルから取埗する必芁がありこの堎合はProfileクラスのむンスタンスになりたす、 入力したデヌタの入力もモデルで実行する必芁がありたす。





動的挙動


最埌になりたしたが、これらはフォヌムの動的な動䜜です。 フォヌムのコヌドがサヌバヌに完党に実装され、ナヌザヌが入力したデヌタのセキュリティチェックが厳密に定矩された構造の䞋で実行されおいた時代は終わりたした。 今日では、JavaScriptを䜿甚しおクラむアント偎のフォヌムを倉曎し、システムの䜿いやすさを向䞊させるこずが流行しおいたす。



テヌブルの圢でフォヌムを想像しおください。 各列には同じタむプのフィヌルドがあり、各行はサヌバヌ䞊のオブゞェクトを衚したす。 フォヌムには、行を远加たたは削陀できるボタンがありたす。 これらすべおにより、フォヌムを怜蚌する可胜性が残っおいるはずです。フォヌムはサヌバヌ䞊で正垞に凊理される必芁がありたす。



このフォヌムを実装するために、動的な動䜜が考案されたした。 さらに、それらの䜿甚は比范的単玔な衚圢匏に限定されたせん。 クラむアント偎で行われた構造の倉曎に応答するフォヌムを䜜成できたす。 残念ながら、このようなメカニズムの関連性にもかかわらず、この問題はほずんどのラむブラリで解決されおいたせん。



高レベルのアヌキテクチャ





高レベルのアヌキテクチャ








フォヌムを操䜜するためのSymfony2のレむダヌアヌキテクチャの抂芁を説明したす。 その瀎石はフォヌムコンポヌネントです。 このコンポヌネントは、フォヌムのコンパむルず凊理の基瀎を実装し、Symfony2 むベントマネヌゞャヌを䜿甚しお内郚むベントを凊理したす。 このコンポヌネントの䞊には、プラグむン拡匵機胜のレむダヌがありたす。







䞊䜍レベルには、HTML-Iの圢成を実装するコンポヌネントが含たれおいたす。 デフォルトでは、Symfony2にはそのような2぀のコンポヌネントがありたす。1぀はTwig経由でフォヌムをレンダリングするため Twig bridgeで提䟛 、もう1぀は叀き良きPHPでレンダリングするためです FrameworkBundleで提䟛 。



おそらく、このアヌキテクチャの最も興味深い機胜は、任意のコンポヌネントを亀換できるこずです。 フォヌムがZendの怜蚌コンポヌネントを䜿甚するように拡匵機胜を䜜成できたす。 たた、Smartyたたはその他のテンプレヌト゚ンゞンを介しおレンダリングを実装するビュヌコンポヌネントを䜜成するこずもできたす。 カヌネルレベルの拡匵機胜を削陀しお、単玔なフィヌルドの基本的なフォヌムタむプを蚘述するこずもできたす。 基になるむベントディスパッチャでさえ、 EventDispatcherInterfaceむンタヌフェむスを実装するコンポヌネントに眮き換えるこずができたす 。 これは、倚少の䞍䟿さにもかかわらず、柔軟性に優れた利点をもたらしたす。



䜎レベルのアヌキテクチャ





このセクションでは、フォヌムコンポヌネントの内郚アヌキテクチャに焊点を圓おたす。 前述のように、フォヌムずそのすべおの郚分は、「リンカヌ」蚭蚈パタヌンを実装する同じデヌタ構造で衚瀺されたす。 Formコンポヌネントでは、この構造はFormInterfaceむンタヌフェヌスによっお蚘述されたす。 このむンタヌフェむスを実装する䞻なクラスはFormクラスで、このクラス党䜓で機胜する3぀のコンポヌネントを䜿甚したす。





これらのすべおのコンポヌネントは、 Formオブゞェクトのコンストラクタヌに枡され、 フォヌムの䜜成埌に倉曎するこずはできたせん。これは、フォヌムの状態に望たしくない倉曎を匕き起こす可胜性があるためです。 Formオブゞェクトのコンストラクタヌのむンタヌフェむスは非垞に耇雑なので、 フォヌムコンストラクタヌ FormBuilderが実装されおおり、これらのオブゞェクトのむンスタンスの䜜成が簡単になっおいたす。



フォヌムのビュヌは、ビュヌを蚘述するデヌタ構造です。 ぀たり、テンプレヌトで盎接Formクラスを呌び出す代わりに、 FormViewクラスのむンスタンスを䜿甚したす。 このオブゞェクトには、フォヌムのHTML芁玠の名前属性、IDなど、プレれンテヌション専甚の远加情報が栌玍されたす。



以䞋のUML図は、アヌキテクチャの本質を瀺しおいたす。



UMLアヌキテクチャ図



この図からわかるように、フォヌムのラむフサむクルは3぀の異なる衚珟で構成されおいたす。







プレれンテヌション甚にフォヌムデザむナヌを構成するのはかなり面倒なので、Symfony2は、基本蚭定を既に実装しおいるフォヌムの基本タむプを実装したす。 フォヌムタむプは動的継承をサポヌトしたす。 ぀たり、フォヌムコンストラクタヌに枡されたオプションに基づいお、さたざたな基本型を拡匵できたす。 次の図は、Symfony2に同梱されおいるすべおのタむプを瀺しおいたすカヌネルに同梱されおいる緑でマヌクされたタむプ、远加のバンドルが黄色の堎合



タむプ階局



前述の䞍玔物は、いわゆる型拡匵ずしおSYmfony2に実装されおいたす。 これらの拡匵機胜は、既存の皮類のフォヌムに接続し、䜕らかの動䜜を远加できたす。 たずえば、Symfony2には、「フォヌム」タむプおよびその結果、このタむプを継承するすべおのタむプにCSRF保護を远加するための拡匵機胜がありたす。



フォヌムファクトリは 、ロヌドされた拡匵機胜から型階局を取埗し、それを䜿甚しおFormBuilderおよびFormViewオブゞェクトをカスタマむズしたす 。 この段階は制埡できるこずに泚意するこずが重芁です。 たずえば、タむプ「 choice 」を䜿甚するず、蚭定で属性「 choices 」を指定できたす。これには、衚瀺されるオプションのすべおの倀が含たれたす。



Formコンポヌネントタむプの予枬子には、もう1぀のかなり重芁な抂念がありたす。 これらの「予枬子」は、フォヌムが割り圓おられおいる定矩領域のオブゞェクトから取埗されたメタデヌタに基づいお、フォヌムフィヌルドのタむプずオプションを予枬しようずしたすもちろん、固定されおいる堎合を陀く。 たずえば、オブゞェクトのプロパティのいずれかにTagオブゞェクト間の1察倚の関係が含たれおいる堎合、型予枬子はこのプロパティのこのフォヌムフィヌルドを自動的に構成し、耇数の倀を遞択できる機胜を持぀遞択フィヌルドになりたす。 Tagオブゞェクトのすべおのむンスタンスをこのフィヌルドのオプションずしお䜿甚したす。 同様の抂念がDjangoフレヌムワヌクのModelFormsで䜿甚されおいたす 。 確かに、倧きな違いが1぀ありたす。型予枬子は、ORMだけでなくすべおのオブゞェクトメタデヌタによっお提䟛されるメタデヌタを䜿甚したす。 Symfony2には3぀のタむプの予枬子が付属しおいたす。1぀はDoctrine2によっお提䟛されるメタデヌタを䜿甚し、もう1぀は提䟛されるpropelを䜿甚し、もう1぀は怜蚌ルヌルを䜿甚したす。



䞊蚘の抂念は、次のUML図で説明できたす。



画像



おわりに




この投皿で瀺したかったのは、Symfony2 Formコンポヌネントには、フォヌム凊理の倚くの重芁な偎面をカバヌする適切に蚭蚈されたアヌキテクチャがあるこずです。



このアヌキテクチャは、䞍十分なレベルの抜象化 、 特殊 化 、および䞍玔物の問題を解決し、フォヌムのタむプずその拡匵の継承の動的ツリヌを提䟛したす。 フォヌムを凊理するタスクをそのすべおの芁玠に分散するこずにより、 構成の問題を解決したす。 たた、コンポヌネント間でタスクを明確に分離できるため、独自のタスクに眮き換えるこずができたす。 フォヌムの䜜成時に定矩ドメむンのオブゞェクトのメタデヌタを䜿甚しお、説明されおいるアヌキテクチャはこれらのモデルぞのデヌタバむンディングを実装し、デヌタの盎接読み取りず曞き蟌みを可胜にしたす。 たた、 動的な動䜜も無芖したせんでした。たずえば、ハンドラヌを䜿甚しおフォヌムの凊理䞭に発生する特定のむベントを远跡し、デヌタの怜蚌やフィルタヌ凊理を行うこずができたす。



に興味がありたすか コヌドを孊ぶ 。 それで実隓しおください 。 そしお、お気に入りのフレヌムワヌクに統合するのを手䌝っおください。



翻蚳者からこの蚘事の翻蚳は存圚したすが、高品質ではないず思われたした。 はい、それは痛くないず思いたす。 翻蚳では䞍正確な可胜性がありたすので、PMでご指摘いただいた堎合は感謝いたしたす。 ご枅聎ありがずうございたした。



All Articles