Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
PHPでResult型やってみよう
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
higaki
July 19, 2025
Technology
750
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
PHPでResult型やってみよう
PHPConference関西2025の登壇資料です。
補足資料
https://zenn.dev/higaki/articles/my-php-result-type
higaki
July 19, 2025
More Decks by higaki
See All by higaki
PHPで TLSのプロトコルを実装してみるをもう一度しゃべりたい
higaki_program
0
340
PHPで TLSのプロトコルを実装してみる
higaki_program
0
880
PHPでResult型を なるべく使いやすい形で実装する
higaki_program
2
420
aspidaで型安全にREST APIのバックエンドを呼び出したい
higaki_program
0
810
Other Decks in Technology
See All in Technology
ハーレムエンジニアリング
kazuma777777
0
170
MulticaとPi Coding Agentで、小規模OSSを30本同時運用した流れ
eiei114
0
130
LLM・AIエージェントシステムベストプラクティス
shibuiwilliam
6
1.4k
ラジオの科学
frievea
0
330
20分でわかるセキュアAPI
nwiizo
2
300
PLATEAU で バーチャル花火大会
tatsuya1970
0
160
【CEDEC2026】次世代デジタルカードゲームのサーバー設計と運用 〜『Shadowverse: Worlds Beyond』の舞台裏~
cygames
PRO
1
1.4k
Goでデータパイプラインを作ろう
sansantech
PRO
1
480
認知負荷をGemini で溶かす — GKE 基盤「Orbit」における AI エージェントの実践
sansantech
PRO
1
320
ボトムアップ文化が強い組織で セキュリティをどう根付かせていくかの現在進行形の話 / Making Security Stick in a Bottom-Up Organization
yamaguchitk333
0
240
Contract One Engineering Unit 紹介資料
sansan33
PRO
0
19k
AIコーディングの次。コードレビューと理解負荷を解消して組織の開発生産性を高める
moongift
PRO
2
2.6k
Featured
See All Featured
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
49
10k
How to build a perfect <img>
jonoalderson
1
5.9k
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
390
SEO for Brand Visibility & Recognition
aleyda
0
4.7k
Claude Code のすすめ
schroneko
67
230k
Discover your Explorer Soul
emna__ayadi
2
1.3k
Into the Great Unknown - MozCon
thekraken
41
2.7k
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
770
Rails Girls Zürich Keynote
gr2m
96
14k
KATA
mclloyd
PRO
35
15k
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
470
Bioeconomy Workshop: Dr. Julius Ecuru, Opportunities for a Bioeconomy in West Africa
akademiya2063
PRO
1
230
Transcript
PHPでResult型やってみよう @PHPカンファレンス関西2025 ひがき
話すこと • Result型とは • 各種エラーハンドリングの例 • PHPでどう実装する?(今日は省略) • 使いどころ
Result型とは??
Result型 とある処理が「成功」したこと、あるいは「失敗」したことを表現する 関数結果にアクセスする前に、関数が成功したか失敗したかのチェックが必要 try-catchの例外処理に頼らないエラーハンドリング PHPではデフォルトで実装されていない
fn divide(a: f64, b: f64) -> Result<f64, String> { if
b == 0.0 { Err("ゼロで割ることはできません ".to_string()) } else { Ok(a / b) } } // 呼び出し側 let result = divide(10.0, 0.0); if result.is_ok() { println!("結果: {:?}", result.unwrap()); } else { println!("エラー: {:?}", result.unwrap_err()); } /** * @return Result<float, string> */ function divide(float $a, float $b): Result { if ($b == 0.0) { return new Err("ゼロで割ることはできません "); } return new Ok($a / $b); } // 呼び出し側 $result = divide(10.0, 0.0); if ($result->isOk()) { echo "結果: " . $result->unwrap() . "\n"; } else { echo "エラー: " . $result->unwrapErr() . "\n"; } Rust PHP(僕の実装)
fn divide(a: f64, b: f64) -> Result<f64, String> { if
b == 0.0 { Err("ゼロで割ることはできません ".to_string()) } else { Ok(a / b) } } // 呼び出し側 let result = divide(10.0, 0.0); if result.is_ok() { println!("結果: {:?}", result.unwrap()); } else { println!("エラー: {:?}", result.unwrap_err()); } /** * @return Result<float, string> */ function divide(float $a, float $b): Result { if ($b == 0.0) { return new Err("ゼロで割ることはできません "); } return new Ok($a / $b); } // 呼び出し側 $result = divide(10.0, 0.0); if ($result->isOk()) { echo "結果: " . $result->unwrap() . "\n"; } else { echo "エラー: " . $result->unwrapErr() . "\n"; } Rust PHP(僕の実装)
fn divide(a: f64, b: f64) -> Result<f64, String> { if
b == 0.0 { Err("ゼロで割ることはできません ".to_string()) } else { Ok(a / b) } } // 呼び出し側 let result = divide(10.0, 0.0); if result.is_ok() { println!("結果: {:?}", result.unwrap()); } else { println!("エラー: {:?}", result.unwrap_err()); } /** * @return Result<float, string> */ function divide(float $a, float $b): Result { if ($b == 0.0) { return new Err("ゼロで割ることはできません "); } return new Ok($a / $b); } // 呼び出し側 $result = divide(10.0, 0.0); if ($result->isOk()) { echo "結果: " . $result->unwrap() . "\n"; } else { echo "エラー: " . $result->unwrapErr() . "\n"; } Rust PHP(僕の実装)
各種エラーハンドリングの例 ※説明のために愉快なコードも出てきますが🙏
1. try-catch 2. nullable 3. union型 4. Result 4つの例
1. try-catch 2. nullable 3. union型 4. Result 4つの例
function completePayment(ProcessingPayment $payment): CompletedPayment { if ($payment->amount <= 0) {
throw new PaymentAmountRuleError("Payment amount must be positive"); } return new CompletedPayment($payment->amount); } // 呼び出し側 try { $result = completePayment($payment); // ... 支払い完了時の処理 } catch (PaymentAmountRuleError $e) { // ... 支払金エラー時の処理 }
function completePayment(ProcessingPayment $payment): CompletedPayment { if ($payment->amount <= 0) {
throw new PaymentAmountRuleError("Payment amount must be positive"); } return new CompletedPayment($payment->amount); } // 呼び出し側 try { $result = completePayment($payment); // ... 支払い完了時の処理 } catch (PaymentAmountRuleError $e) { // ... 支払金エラー時の処理 }
よくあるPHPの例外処理 • 複数のエラーパターンを例外で表現可能 • フローが複雑になりがち(GOTOみたい) try-catch
1. try-catch 2. nullable 3. union型 4. Result 4つの例
function completePayment(ProcessingPayment $payment): ?CompletedPayment { if ($payment->amount <= 0) {
return null; } return new CompletedPayment($payment->amount); } // 呼び出し側 $result = completePayment($payment); if ($result === null) { // ... 支払金エラー時の処理 } // ... 支払い完了時の処理
function completePayment(ProcessingPayment $payment): ?CompletedPayment { if ($payment->amount <= 0) {
return null; } return new CompletedPayment($payment->amount); } // 呼び出し側 $result = completePayment($payment); if ($result === null) { // ... 支払金エラー時の処理 } // ... 支払い完了時の処理
稀によく見る • シンプルで軽量 • PHP 7.1〜 • エラーの詳細情報が得られない • 複数のエラーパターンを区別できない
nullable
1. try-catch 2. nullable 3. union型 4. Result 4つの例
function completePayment(ProcessingPayment $payment): CompletedPayment|PaymentAmountRuleError { if ($payment->amount <= 0) {
return new PaymentAmountRuleError("Payment amount must be positive"); } return new CompletedPayment($payment->amount); } // 呼び出し側 $result = completePayment($payment); if ($result instanceof PaymentAmountRuleError) { // ... 支払金エラー時の処理 } // ... 支払い完了時の処理
function completePayment(ProcessingPayment $payment): CompletedPayment|PaymentAmountRuleError { if ($payment->amount <= 0) {
return new PaymentAmountRuleError("Payment amount must be positive"); } return new CompletedPayment($payment->amount); } // 呼び出し側 $result = completePayment($payment); if ($result instanceof PaymentAmountRuleError) { // ... 支払金エラー時の処理 } // ... 支払い完了時の処理
成功も失敗も同列で扱う • 複数のエラーパターンを型で表現可能 • PHP 8.0 〜 • どの型が成功か失敗の判断が必要 union型
1. try-catch 2. nullable 3. union型 4. Result 4つの例
/** * @return Result<CompletedPayment, PaymentAmountRuleError> */ function completePayment(ProcessingPayment $payment): Result
{ if ($payment->amount <= 0) { return new Err(new PaymentAmountRuleError("Payment amount must be positive")); } return new Ok(new CompletedPayment($payment->amount)); } // 呼び出し側 $result = completePayment($payment); if ($result->isErr()) { return match (true) { $result->unwrapErr() instanceof PaymentAmountRuleError::class => // ... 支払金エラー時の処理 } } // ... 支払い完了時の処理
/** * @return Result<CompletedPayment, PaymentAmountRuleError> */ function completePayment(ProcessingPayment $payment): Result
{ if ($payment->amount <= 0) { return new Err(new PaymentAmountRuleError("Payment amount must be positive")); } return new Ok(new CompletedPayment($payment->amount)); } // 呼び出し側 $result = completePayment($payment); if ($result->isErr()) { return match (true) { $result->unwrapErr() instanceof PaymentAmountRuleError::class => // ... 支払金エラー時の処理 } } // ... 支払い完了時の処理
関数結果にアクセスする前に、関数が成功したか失敗したかのチェックが必要 • 複数のエラーパターンを型で表現可能 • 成功と失敗が明示的 • PHPStanなどの静的解析がないと辛い Result
PHPでどう実装する? (本日は省略)
zennの記事を見てください🙏 時間の関係で本日は省略します >< https://zenn.dev/higaki/articles/my-php-result-type
使いどころ
使いどころ 🤔 そもそも我々が対処すべきエラーハンドリング • ⭕ビジネス例外 • ❌技術的例外 技術的例外に関しては、アプリケーションのフレームワークに対応を任せることができ、ビジネス例 外に関しては、クライアントにあらかじめ対処するコードを組み込んでおくことができます。 「PHPの例外処理の参考になる資料」
asumikam: プロダクトコードと OSSに学ぶ例外処理の選択肢 — キャッチするのか、投げっぱなしにするのか プログラマが知るべき 97のこと: 21 - 技術的例外とビジネス例外を明確に区別する
使いどころ 😆 ビジネスロジックに取り入れていく • ビジネス例外の対応にResult型を取り入れる ◦ 技術的例外は例外を投げっぱなす • 予期されるエラーに対して効果的な場合は Result型でエラーハンドリングする
• 他の手法の方が適切なシステム・処理は多々ある 「Result型を取り入れない場所の参考になるブログ」 Kentaro Inomata: 鉄道指向プログラミング(の安易な利用)に反対する
• Takuma Kajikawa ◦ try-catchを使わないエラーハンドリング!? PHPでResult型の考え方を取り 入れてみよう • asumikam ◦
プロダクトコードとOSSに学ぶ例外処理の選択肢 — キャッチするのか、投 げっぱなしにするのか • Kentaro Inomata ◦ 鉄道指向プログラミング(の安易な利用)に反対する • プログラマが知るべき97のこと ◦ 21 - 技術的例外とビジネス例外を明確に区別する 参考
自己紹介 ひがき 🍊PHPConference愛媛2026 実行委員長🐘 2026年9月 or 10月 愛媛県松山市 ペチコン愛媛開催予定!! LIKE:筋トレ・ポーカー
旧 新