Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Symfonyの特性(設計思想)を手軽に活かす特性(trait)

Avatar for ICKX ICKX
March 21, 2026

 Symfonyの特性(設計思想)を手軽に活かす特性(trait)

Avatar for ICKX

ICKX

March 21, 2026
Tweet

More Decks by ICKX

Other Decks in Programming

Transcript

  1. 自己紹介 • 若葉 章(わかば あきら) • 2010年~ 同人ソフトサークル Project ICKX

    • プロデューサー / 営業 / インフラ / サーバサイド... / ゲームの実開発以外全部 • 本職はスタッフエンジニアっぽいこともするphpエンジニア • PHP続けて26年 PHP3の頃からお世話になっています • 最近の趣味は自転車とコーヒーとアマチュア無線 • Tyrell iveで京阪や徳島から高松まで走ったり、icom ic-705やID-52で移動運用試したり • ボトルゲージ用のアルミステーやドリッパーホルダの自作を始めましたもうだめだ • Nintendo Switch で『VERTICAL STRIKE ENDLESS CHALLENGE』販売中 • Qiitaで『phpで高速に・省メモリ・確実に日本語csvを扱う方法』公開中 https://qiita.com/wakabadou/items/84b48ca12f25fb2fb69c 「composer require fw3/streams」をよろしくね。 「composer require tacddd/tacddd」もよろしくね。 「composer require bypassflow/crypt」もよろしくね。
  2. • 2012年リリースのPHP5.4から導入された機能 • 単一継承言語でコードを再利用する仕組みの一つ • 単にいくつかの機能をまとめるためだけのもの • プロパティやメソッド、定数(8.2以降)を定義できる • インスタンスは作れない

    • 縦軸の再利用が継承、横軸の再利用が特性として整理できる • 適用できる先はクラス、特性、列挙型(Enum) • 疑似的に多重継承っぽいことができる • 継承が許されないEnumに対して共通処理を持ち込める
  3. class A extends AC use TraitA use TraitB class C

    extends B use TraitB class D extends B trait TraitB abstract class AC class B extends AC use TraitA trait TraitA 継承と特性で実現する再利用
  4. abstract class AC class A extends AC use TraitA use

    TraitB class B extends AC use TraitA class C extends B use TraitB class D extends B 旧来の継承で実現する再利用範囲
  5. abstract class AC class A extends AC use TraitA use

    TraitB class B extends AC use TraitA class C extends B use TraitB class D extends B trait TraitA 特性Aで実現する再利用範囲
  6. abstract class AC class A extends AC use TraitA use

    TraitB class B extends AC use TraitA class C extends B use TraitB class D extends B trait TraitB 特性Bで実現する再利用範囲
  7. traitからの静的プロパティ 直呼び出し 21 Deprecated: Accessing static trait property SampleTrait::$fuga is

    deprecated, it should only be accessed on a class using the trait Fatal error: Cannot redeclare trait SampleTrait
  8. traitで定義した定数を クラスで上書き 24 Fatal error: SampleClass and SampleTrait define the

    same constant (HOGE) in the composition of SampleClass. However, the definition differs and is considered incompatible. Class was composed
  9. 抽象プロパティ 28 Fatal error: SampleClass and SampleTrait define the same

    hooked property ($public) in the composition of SampleClass. Conflict resolution between hooked properties is currently not supported. Class was composed
  10. 抽象プロパティフック 29 Fatal error: SampleClass and SampleTrait define the same

    hooked property ($public) in the composition of SampleClass. Conflict resolution between hooked properties is currently not supported. Class was composed
  11. プロパティフック 30 Fatal error: SampleClass and SampleTrait define the same

    hooked property ($public) in the composition of SampleClass. Conflict resolution between hooked properties is currently not supported. Class was composed
  12. 複数のtraitで定義した(略 53 object(class@anonymous)#3 (2) { ["instance"]=> object(SampleClass)#8 (1) { ["id"]=>

    int(1) } ["attributes"]=> array(2) { [0]=> object(Id)#5 (0) { } [1]=> object(Validate)#6 (1) { ["rule"]=> enum(ValidateRuleEnum::PositiveIntA) } } }
  13. 58 カードマ~ン 決済代行会社 • 対応決済方法 • クレジットカード • IC払い •

    QR払い • 銀行払い • 後払い ビューン 決済代行会社 • 対応決済方法 • クレジットカード • IC払い • QR払い
  14. • DIコンテナを中心にHTTP処理をイベントで組み立てる フレームワーク • Laravelのようなフルスタック一体ではなく HTTP / CLI / DI

    / Event / Config を束ねる 実行環境がコアとしてふるまう • フレームワークを使うではなく、 DIコンテナ上にアプリを構築するイメージ • パフォーマンスの担保をruntimeではなく buildタイミングで最適化
  15. 73 オプションも合成できる • [ ‘title_root’ => ‘サンプル’, ‘title_section’ => ‘売り上げ’,

    ‘title_page’ => ‘一覧’, ] • title:サンプル – 売り上げ – 一覧
  16. Symfony¥Bundle¥FrameworkBundle¥Controller¥ AbstractController ※必須:これを継承しないと何もできない class SalesLogController extends AbstractController ※ここで余計なものを挟み込めない Symfony Controllerの継承制約

    abstract class AbstractAppController extends AbstractController ※一見共通化できたように見える abstract class SalesLogControllerr extends AbstractAppController ※特化共通基盤が必要になったら 特化ごとにAbstractが必要になる 特化が入れ子になったら…?
  17. • {{ config.current_path }}で現在のページのパスを得られます • つまり{{ path(config.current_path) }}で終わる もうこれでいちいちページごとにnameを書き換えることはない… •

    同様に{{ path(config.getTemplatePathByAction(‘index’) }} • 更には{{ path( config.getPathByAction(‘update‘), param.from(entity).criteria ) }}などもできます Configの恩恵
  18. • config.current_path => sample_sales_log • config.getTemplatePathByAction(‘read’) => sample_sales_log_read • config.getTemplatePath(‘payment_log’)

    => sample_payment_log_read • path( config.getPathByAction(‘update‘), param.from(entity).criteria ) => /sample/sales-log/1 /sample/sales-log(sample_sales_log) の場合