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
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
higaki
July 19, 2025
Technology
700
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
310
PHPで TLSのプロトコルを実装してみる
higaki_program
0
850
PHPでResult型を なるべく使いやすい形で実装する
higaki_program
2
410
aspidaで型安全にREST APIのバックエンドを呼び出したい
higaki_program
0
810
Other Decks in Technology
See All in Technology
Agile and AI Redmine Japan 2026
hiranabe
4
480
Flow 不死:AI 時代 DevOps 的不變本質
cheng_wei_chen
2
510
GitHub Copilot app最速の発信の裏側
tomokusaba
1
260
AIに障害切り分けを全部やってもらった。 。 。 。
estie
0
150
時期が悪い!それでもRaspberry Piを買って遊んで活用するには / 20260627-osc26do-rpi-jikigawarui
akkiesoft
0
820
気軽に使える"情報のハブ"としてのNotion活用 〜フロー情報の集積点 と、 Claude Code × Notion AI〜
syucream
1
200
Microsoft のサポートとフィードバック総まとめ
murachiakira
PRO
0
110
Kiro Ambassador を目指す話
k_adachi_01
0
130
フィジカル版Github Onshapeの紹介
shiba_8ro
0
320
AIのReact習熟度を測る
uhyo
2
680
AI時代のコスト管理を考えよう〜明日から使える実践AWSノウハウ~
yoshimi0227
0
870
Multi-Agent並列開発を 安全に回すための技術 / Technology for Safely Multi-Agent Parallel Development
tooppoo
0
180
Featured
See All Featured
Reflections from 52 weeks, 52 projects
jeffersonlam
356
21k
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
860
Money Talks: Using Revenue to Get Sh*t Done
nikkihalliwell
0
260
Effective software design: The role of men in debugging patriarchy in IT @ Voxxed Days AMS
baasie
0
430
Game over? The fight for quality and originality in the time of robots
wayneb77
1
200
Building the Perfect Custom Keyboard
takai
2
800
HTML-Aware ERB: The Path to Reactive Rendering @ RubyCon 2026, Rimini, Italy
marcoroth
1
230
How to Align SEO within the Product Triangle To Get Buy-In & Support - #RIMC
aleyda
2
1.6k
SEO for Brand Visibility & Recognition
aleyda
0
4.6k
ラッコキーワード サービス紹介資料
rakko
1
3.7M
Digital Ethics as a Driver of Design Innovation
axbom
PRO
1
330
Hiding What from Whom? A Critical Review of the History of Programming languages for Music
tomoyanonymous
2
870
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:筋トレ・ポーカー
旧 新