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
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
不要なレビューをAIにまかせて AIコーディングの環境改善を加速した
shoota
1
270
ぼっちではじめた登壇が「51名」「241件」の発信に化けた
subroh0508
1
310
IaC コードを資産へ:AWS CDK 社内ライブラリと横断展開 / aws-summit-japan-2026
gotok365
10
1.6k
起点・思考・出力で分解する 〜PM業務の自動化設計〜
kazu_kichi_67
1
1.1k
フィジカル版Github Onshapeの紹介
shiba_8ro
0
320
徹底討論!ECS vs EKS!
daitak
3
1.7k
AI Agentをシステムに組み込む前にゆるく向き合ってみる
hayama17
0
140
「軸足」は 固定しなくていい - 熱量と強みで描く、しなやかなキャリアの形
kakehashi
PRO
1
270
AIが自律的に回る開発ループを設計してチーム開発に組み込む
nekorush14
0
130
AIはどのように 組織のアジリティを変えるのか?
junki
4
1.4k
2026-06-24_人とAIの責務分離に基づく開発プロセスの提案.pdf
takahiromatsui
0
120
GitHub Copilot app最速の発信の裏側
tomokusaba
1
260
Featured
See All Featured
Being A Developer After 40
akosma
91
590k
HDC tutorial
michielstock
2
720
What the history of the web can teach us about the future of AI
inesmontani
PRO
1
620
A brief & incomplete history of UX Design for the World Wide Web: 1989–2019
jct
2
400
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
8.2k
Reflections from 52 weeks, 52 projects
jeffersonlam
356
21k
What’s in a name? Adding method to the madness
productmarketing
PRO
24
4.1k
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
560
Navigating the moral maze — ethical principles for Al-driven product design
skipperchong
2
400
Agile Actions for Facilitating Distributed Teams - ADO2019
mkilby
0
210
Ten Tips & Tricks for a 🌱 transition
stuffmc
0
140
Data-driven link building: lessons from a $708K investment (BrightonSEO talk)
szymonslowik
1
1.1k
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:筋トレ・ポーカー
旧 新