弊社では物流Techとして物流業界の様々な課題を解決しようと奮闘しています。
今回はその中でも注文情報周りを扱う処理が肥大化してしまい、変更がどんどんと困難になってしまった話をします。
注文情報というのは各ECプラットフォームから取得される情報で、どこに配送するかや、なにを配送するかなど多くの情報を持っています。
また、配送済みかどうかや、そもそも弊社倉庫から出荷するのかなど、更に内部の状態を複数持つことになります。
DDDライクな設計で実装を進めていましたが、最初は保存処理などシンプルなもののみをOrderRepositoryとして実装していたので、特に問題はありませんでした。
しかし、どんどんと機能仕様が膨れ上がり、注文が持っているべき状態というのもそれに伴って増えていきました。
注文の状態を更新するために他のテーブルの状態を見ないといけなくなり、そのロジックをトランザクションの中に入れようとした結果記述量が増えたり、
注文の状態が変わったことをeventで通知するのをすべてRepository層でやったことで抜けが発生したりと、だんだんとOrderRepositoryが太っていきました。
また複雑になっていくことで、機能追加するたびに他の機能の変更を気にしなければいけない状態になっており、同時に機能開発をしているとコンフリクトと戦う時間が増えてしまうという問題もありました。
そんなOrderRepositoryとどうやって向き合って、どうやって綺麗にしていったかの話をしていきます。
P山 サービスに途中から参加すると、最初の頃はコードとドメインがどのように積み上がってきたのかを追いかけるところから始まります。私が担当しているユーザー領域も、サービスの成長に合わせて機能が増え、その結果としてバリデーションや判定処理がいくつかの層に分散していました。本セッションでは、これらを読み解きながら整理していったプロセスを紹介します。
まず、散在していたユーザーまわりのバリデーションをドメインサービスに集約し、どのような処理をドメイン側で扱うべきかをチームで合意できるよう、簡単なマニフェストを用意しました。また、利用者ごとのケーパビリティを導入し、エンドポイント単位でアクセス制御を行うことで、コントローラへの細かな分岐を避けられるようにしました。
さらに、DB のインデックス追加を安全に進めるために、GitHub Actions から実行できる “alterguard” を開発し、作業手順を極力シンプルにしながら pt-osc を併用できる環境を整えました。これにより、ユーザー領域以外の改善も継続的に進められるようになりました。
成長中のプロダクトに後から加わった立場として、どのようにドメインを理解し、どこから整えていったのか。その具体的な進め方をお話しします。
プログラミングをするパンダ 本セッションでは、「大量のショップが同時刻にセール予約をすると開始遅延や未開始が発生する」という課題に対して、「計測→可視化→ボトルネック特定→個別改善→再計測」というループを元にパフォーマンスの改善をした実践を共有します。
まず New Relic のダッシュボードでCPU・レイテンシ・処理件数を可視化し、遅延要因を特定しました。打ち手は、SNS Publish のバルク化、Active Record での N+1 の一部処理の切り出し、重いセールグループを処理するプロセスごとの負荷の平準化などです。
この改善を実施したことにより、開発環境でおおむね 40% の速度改善に成功。2025年のブラックフライデーでも 10 万商品のセールをインシデントなく完了しました。
ユーザーが直面しているペインを解消するために、技術でプロダクトを泥臭く改善する大切さと華々しい成果だけではなく、根本解決のためにはまだやれることがあるという現場のリアルもお伝えします。
きんじょうひでき いつでも気軽に、本格的なスパゲッティを手に入れたいと考えていませんか?
次のようなコードを、得る方法を構築しましょう。
あなたがいつものようにPHPで書いたコードを材料として、
まるで「レンジでチン!で食品を温める」ように、スパゲッティコードを手に入れる。
そんな「夢の無限スパゲッティ製造機」があったら、どうでしょうか?
構造も制御も低レベルな表現力しか持たない世界に転生させ、その後に再びPHPの世界に蘇らせることができれば、
PHPで作られたスパゲッティの製造が可能です!
本トークでは、ネイティブなスパゲッティを作成してみなさんにお届けします
「PHPで書かれたコード → opcodeに変換 → 再度PHPに変換」を行い、「通常のコード」 と見比べていきます。
例外処理の実現など、一部のPHPの機能については割愛します
(つまり、どんなコードにも利用できるものではなく、対応する内容には制限があります)
ma@me Laravel Octaneは、Laravelアプリケーションを更に高速化させるためのパッケージです。
SwooleやRoadRunnerに加え、Caddy WebサーバーやFrankenPHPもサポートされ、モダンな構成が容易に導入できるようになりました。
しかし、単に「導入すれば速くなる」という理解だけでは、メモリリークやステート汚染といった、便利さの裏に隠されている落とし穴にハマってしまうかもしれません。
本セッションでは、特にLaravel OctaneのFrankenPHPドライバにフォーカスし、
octane:frankenphp コマンドが実行されたその裏側で何が起きているのか、ソースコードレベルで内部実装を紐解いていきます。
梶川 琢馬 アプリケーションを運用していると、外部サービスの遅延や内部の重い処理が原因で応答速度が不安定になることがあります。
私自身、サービス間の連携やドメインイベントの実装に取り組む中で、メインフローが時間のかかる処理と密結合していることが、遅延や障害につながるケースを経験しました。
こうした状況では、時間のかかる処理をメインフローから切り離し、QueueやPubSubなどメッセージングを使って非同期で実行するアプローチが有効な場合があります。
これにより応答速度が安定し、メイン処理と周辺処理を分離することで、変更に強い構造を作りやすくなります。
一方で、非同期化には同期処理では現れにくい落とし穴があります。
整合性のズレ、処理順序の乱れ、重複実行など...
適切な対処をせずに導入すると、期待した改善よりも複雑さが増すケースもありました。
本セッションでは、メッセージングによる非同期化を進める際に押さえておきたいポイントを、次の観点から整理して解説します。
イベント駆動アーキテクチャなどメッセージング導入について議論のきっかけになると嬉しいです!
郡山 昭仁 ソフトウェア工学70年の歴史で、我々は三つの主要パラダイムを経験しました。命令型(How)は手順を、オブジェクト指向(Who)は主体を、関数型(What)は計算内容を問いました。本講演では第四のパラダイム「存在論的プログラミング(Whether)」を提唱します。
従来のプログラミングはDOING(何をするか)に着目します:
$user->validate();
$user->save();
$user->notify();
対して本手法はBEING(何であるか)に着目します:
$rawData = new UserInput($_POST);
$validatedUser = new ValidatedUser($rawData);
$savedUser = new SavedUser($validatedUser);
動作を指示するのではなく、オブジェクトが「どう変容するか」を表現するのです。
『時間と存在は分割できない』——アインシュタインが時空の不可分性を説いたように、我々は「時間とドメインの不可分性」を基礎とします。メソッドを持たず、コンストラクタのみを持つそのオブジェクトは、内在(イマナンス)と超越(トランセンデンス)の出会いにより、時間の中で変態(メタモルフォーシス)し、時間的存在として自立します。
「さっぱり、何のことか分からない」と感じましたか? しかし、その違和感はかつて60年代のアセンブラ利用者が初めてOOPに触れた時の衝撃と同じで、これが単なる方法論ではなくパラダイムシフトである証拠かもしれません。
70年間、我々は「より良い命令」を追求してきました。しかしAIが「命令(How)」を無限生成する今、人間が書くべきものは手順書ではなく「存在(BEING)の定義」です。
うさみけんた 世の中にはさまざまなプログラミング言語があり、それぞれさまざまな分類方法があります。
オブジェクト指向プログラミング、関数型プログラミングのようなプログラミングのスタイルは「パラダイム」と呼ばれ、言語ごとのプログラムの世界観となるものです。これらの言語やパラダイムは独自に発展するだけではなく、互いに影響を与え合いながら発展を続けてきました。PHPも例外ではなく、30年前の誕生時から同じ「PHP」と呼ばれていても、そのソースコードは似ても似つかないものに変化しています。
特に2000年代以降は「関数型」と呼ばれる概念がPHPをはじめ、さまざまな言語に浸透してきましたが、その概念を育んできた関数プログラミング言語と、PHPで実現できる関数型プログラミングは同等のものなのでしょうか。
本トークではプログラミング言語にまつわるさまざまなトピックを紹介し、PHPの作者はそこまで考えていなかったであろうPHPの正体を丸裸にしていきます。
めもり〜☆ PHP を Web アプリケーションを作るための言語の一つだと思っていませんか。
実はそれ Web アプリケーション以外の用途にも PHP を用いることができるのはご存知でしょうか。
実例として PHP で Java VM (JVM) を実装したり、RubyVM を実装したり,OS などが実装されています。
もちろん,PHP を使って "OS を動かす" エミュレータを実装することもできます。
エミュレータという言葉にピンとこない人もいるかもしれません。皆さんも一度は使ったことあるであろう QEMU や、 VirtualBox のような仕組みを PHP で実装する、というイメージを持ってもらうとわかりやすいのではないかと思います。
本セッションでは,OS の代表格の一つである Ubuntu の起動までをマイルストーンとし, PHP を用いたエミュレータの実装方法から OS を動かすのに必要な知識を解説します。
荒巻拓哉 DIコンテナは、Dependency Injection(依存の注入)を利用してクラス間の依存関係の解決を行ってくれます。
具体的には、オブジェクト生成時やメソッド呼び出し時に渡す引数を自動的に生成してくれるなどの機能を有します。
LaravelやSymfonyなど、最近のWebアプリケーションフレームワークの多くにもこの機能が組み込まれているので、普段使っているという人も多いのではないでしょうか。
Autowire機能を持つDIコンテナの場合、コンストラクタやメソッドに型宣言を書いてさえおけば、引数を増やしたり入れ替えたりしても柔軟に動作してくれます。
『これはまるで「魔法」だ』とDIコンテナを知った当時に感じたのを覚えています。
とはいえ、DIコンテナもただのプログラムです。実際には魔法などではなく、PHPのコードとして実装されているのです。
このセッションでは、Autowire機能がどのように実装されているのかを紐解きます。その上で、Autowireによるコンストラクタインジェクション機能を持つDIコンテナを実装してみます。
DIコンテナの裏側を理解し、普段ブラックボックスになっているフレームワークの動作の一端を覗いてみましょう。
藤掛治 ウェブアプリケーションの品質担保は重要課題です。しかし、2001年にローンチされた弊社のメール共有サービス「メールディーラー」のようなレガシープロダクトはより深刻です。
フレームワークを持たず、DBアクセスとHTML生成が単一プログラム内で混在する「スパゲッティコード」が構造を陳腐化させました。
このためコード全体の把握が困難になり、修正前の十分な影響調査ができない状態を生み出しました 。
実際、新機能リリース直後に改修していないはずの機能で「画面が表示できなくなる」という致命的な障害が発生。
この「意図せぬ機能破壊」に対し、理想は大規模リファクタリングでしたが、現実的なコストと期間ではありませんでした。
そこで私たちは、リスクを抑えつつ最低限の品質を担保する戦略的な選択として、E2Eテストの導入を決断しました。
本トークでは、私がテクニカルリーダーとして主導した、限られたリソース(3ヶ月)でのE2Eテスト導入戦略を公開します。
・複雑な内部構造を持つレガシーシステムに対し、テスト対象のスコープを切り出し、導入の投資対効果を最大化した手法。
・テストコード実装とテストケース作成において、スパゲッティコード特有の難しさをどのように克服し、273画面のカバー率を達成したか。
・導入後に「致命的な不具合の発生ゼロ」という具体的な成果をどのように勝ち取ったか。
本セッションは、レガシーシステムの品質改善に取り組むエンジニアに向けた、実践的な E2E テスト導入事例の共有です。
困難な環境下でのテスト戦略策定方法と、既存プロダクトへの段階的な導入テクニックと、
開発チーム全体に客観的な安心感をもたらすための確かな知見を持ち帰ってください。
PHPはZend VMの上で動いており、すべてのPHPプログラムはそのopcodeに変換され実行されます。
本発表では、そのopcodeを眺めてみて、他の言語処理系との違いについてご紹介します。
発表者はいくつか仮想マシンを作ったことがあり、とくにRubyの仮想マシンについてちょっと詳しいので、そういった観点でご紹介できればと思います。
参加者の皆様には、他の言語処理系との比較を通じて、Zend VMの独自性や利点を理解していただければと思います。
2015年、PHPコミュニティは内戦状態でした。Scalar Type Declarations RFCは、賛成108票、反対48票という異常な投票数を記録し、厳密派と寛容派が激しく対立しました。なぜ最終的にstrict_typesは「ファイル単位のオプトイン」になったのでしょうか。
背景には、PHP 5.4で削除されたmagic_quotesの苦い教訓がありました。php.iniの設定次第で同じコードが環境によって異なる動作をし、SQLインジェクション脆弱性を生む原因となった経験から、PHPは環境依存の設定を避ける方向に舵を切りました。さらに、Composerエコシステムとの共存も不可欠でした。もしグローバル設定が可能だったら、vendorディレクトリ以下の数百のパッケージが想定外の動作モードを強制され、エコシステム全体が壊れる可能性がありました。
この設計は「漸進的型付け」という学術的アプローチに基づき、後方互換性、エコシステムの安定性、開発者の選択の自由を守りました。「全部ONにすべきか」という問いへの答えは、あなたのプロジェクトが決めることです。Whyを知るとHowの判断が変わります。
髙橋直規 アーキテクチャの刷新は、しばしば「決める人」が限定され、トップダウンでの進行になりがちです。
しかし、その方法では納得感が生まれず、チーム全体が新しいアーキテクチャに適応しきれないのではと私は感じていました。
そこで実施したのが、「俺の/私の最強アーキテクチャ決定戦」というイベントです。
全員が発言できるように場を用意し、メンバーがそれぞれ考える理想のアーキテクチャを持ち寄る形式を取りました。
この取り組みには二つの意図がありました。
実際に開催してみると、若手メンバーからも積極的な発信があり、各自抱えていた困りごと・改善の種を吸い取ることができました。
最終的に決まったアーキテクチャはひとつですが、その結論には全員の声が反映された状態をつくれました。
これによりトップダウンでは得られない、「自分たちで決めた」という納得感とオーナーシップが生まれました。
本LTでは、
・なぜトップダウンではなくイベント開催を選んだのか
・どのように発言機会を設計したのか
・若手の声を拾うことで何が変わったのか
チーム全員が新しいアーキテクチャに適合するための工夫を実体験に沿って紹介します。
アーキテクチャ刷新は設計だけでは進みません。
“決め方”を設計することでチームは刷新に適応できるようになる。
そんな学びをお伝えします。
■想定する参加者層
・トップダウンの設計決定に違和感を覚えたことがある人
・若手の意見を引き出したいリーダー
・設計刷新や合意形成に悩むチームメンバー
■Learning Outcome
・チーム内での考える人作る人の分断を防止できる
・チームが主体的に開発を進めていける
・チームがオーナーシップを持ってプロダクトを育てていける
pika ProgateでPHPを学び、2ヶ月でCRUD処理ができる掲示板を作れるようになりました。しかし機能を追加するたびにコードは複雑化し、どこに何を書けばいいか分からなくなり、収集がつかなくなっては最初からやり直す日々。
この地獄を抜け出すために「フレームワーク」を調べ始めましたが、LaravelやSymfonyの説明を読んでもありがたみが分からないし、漠然と機能を覚えていく学習に面白さを感じませんでした。ならば自分で作ってみよう。
MVC、ルーティングのディスパッチャー、コンストラクタインジェクション、バリデーター、CSRF対策、自動XSSエスケープ、Laravel風のヘルパー関数—これらをゼロから実装する中で、特に「依存性注入のメリット」と「設定より規約」の考え方が腹落ちしました。
本トークでは、フレームワーク自作を通じてこれらを理解していった過程を共有します。
トークの内容:
__get() 経由で読み取り可能な protected プロパティに対し、外部から empty() を使用した際、値が存在するにも関わらず true (空) が返ってくる現象に遭遇しました。
「直接アクセスでは値が取れるのに、なぜ empty() は空と判定するのか?」
調査の結果、原因は empty() 関数の内部仕様にありました。
empty() はアクセス不能プロパティに対し、いきなり get() で値を取りに行くのではなく、まず isset() で存在確認を行います。
ここで __isset() が未定義だと、問答無用で「存在しない=空」と判断されていたのです。
本LTでは、この意外なハマりポイントの解説と、get() を使うなら必ず isset() も実装すべきという「お作法」について、実例を交えて共有します。
※PHP7.4のお話です。
8.1以降なら public readonly でプロパティを定義すれば __get() とか使わなくて良いはずですが、実際には8.1まで上げられていないプロジェクトもあると思うので…。
まきまき フレームワーク同士の噛み合わせによって、カスタムしたい箇所がうまくカスタムできずモヤモヤしたことはありますでしょうか?
私は「例外時のAPI Platformからのレスポンスをカスタムしたいのに、Laravelの標準エラーハンドラに書いても効かない〜〜〜!」とAPI Platform for Laravelの例外処理に悩まされました。
これは、API Platformが内部で利用するSymfonyのコンポーネントが、Laravelの例外処理よりも手前でレスポンスを生成し、意図的に上書きしているためです。
そこでフレームワークのソースコードを確認して勝ち取った解決策を共有します。それは、複雑な設定変更ではなく、たった一つのサービスプロバイダへの追記によるものです。
ポイントはフレームワークのErrorHandlerクラスをカスタムクラスで上書きすることでした。
このLTでは、フレームワークの制御の意図的な優先問題を解決する実例とDI(依存性注入)がいかにフレームワークを裏側から制御する武器になるかをお話しします!
さくらい 「ハイコンテキスト」「ローコンテキスト」「言語間距離」。
これらは、日本語や英語といった自然言語を語る際によく用いられる言葉です。
言語が持つ"性格"を表す概念でもあります。
では、私たちのPHPはどうでしょうか。
文法があり、慣習があり、文脈によって意味が補われる。
PHPもまた言語である以上、「言語としての性格」を持っています。
近年、生成AIの普及によって、エンジニアの言語環境はより複雑になりました。
日本語で考え、英語を交えてPHPを書き、複数のAIと同時対話する。
このように異なる性格を持つ言語の行き来が、いまや日常となっています。
しかし、この切り替えは人間の脳にとって、時に無視できない認知負荷となります。
大AI時代となった今「以前より集中できない」「脳が疲れる」と感じる人が増えているのも、
この言語の切り替えによる負荷が、気付かないうちに積み重なっていることが原因かもしれません。
本セッションでは、技術選定や言語選定の是非は扱いません。
PHPを言語学の視点から捉え直し、AI時代の「脳疲れ」はどこから来るのか、
そして日々の思考を少し楽にする対策についてお話しします。
本セッションの対象者
02 PHP 8.5にて、配列の先頭・末尾の値を取得する array_first / array_last が導入されました。内部ポインタを操作せず、直感的に値をシュッと取得できる便利関数です。
実はPHP7.3にも、似た機能を持つ array_value_first / array_value_last というRFCが存在し、否決されていた事実をご存知でしょうか。
当時は配列の先頭・末尾のキーを取得する array_key_first / array_key_last のみが採用され、 array_value_first / array_value_last は見送られました。
PHP7.3だった時代に比べ、現代は readonly プロパティの普及により内部ポインタ操作の副作用ができなくなったことや、冗長な記述の蔓延など、array_first / array_last を必要とする理由があります。
本LTでは、array_first / array_lastの紹介に留まらず、array_value_first / array_value_lastのRFCが否決された背景や理由と、今回array_first / array_lastのRFCが可決された背景や理由を比較・解説します。
新機能だけでなく、歴史的経緯についても学べる5分間をお届けします。
masnmt オンプレミスの本番環境の構築を行う際にも、やはり開発/テスト環境が欲しくなります。
Dockerを日常的に使用するエンジニアが多いですが、Hyper-Vを利用すると実機の環境をより正確に再現できます。
特にHyper-VはWindows Pro / Enterpriseの環境であれば、機能を有効化することで簡単に導入できるのでとても便利です。
Hyper-Vの機能を有効化すると「Hyper-Vマネージャー」というGUIツールで管理できるようになりますが、設定項目が多いのでチームで共有するためにPowerShellスクリプト(ps1ファイル)で記述してコードで管理できるのが望ましいです。
本LTでは、Hyper-Vの各コマンドを詳しく説明するのではなく、実際にps1ファイルで環境構築を自動化しようとしたときにハマったポイントと回避策を紹介します。
今回はこの2点に絞って話します。
・ps1ファイルをそのまま実行できない環境で、WSL2からPowerShellを呼び出してHyper-Vを操作した方法
・仮想スイッチ作成やVM作成など、管理者権限が必要な作業をPowerShellで記述するための工夫
これからHyper-V環境をコードで管理したい方が、同じ落とし穴にはまらないための知見を共有できればと思います。