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
730
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
330
PHPで TLSのプロトコルを実装してみる
higaki_program
0
870
PHPでResult型を なるべく使いやすい形で実装する
higaki_program
2
420
aspidaで型安全にREST APIのバックエンドを呼び出したい
higaki_program
0
810
Other Decks in Technology
See All in Technology
AI時代におけるテストの基礎の再定義 / Rethinking the Fundamentals of Testing in the AI Era
mineo_matsuya
15
5.7k
20260720_クラウド女子会×PyLadiesTokyoコラボ Amazon Bedrock ハンズオン用資料
yuuka51
2
120
データエンジニアリングとドメイン駆動設計
masuda220
PRO
15
2.7k
GoでCコンパイラを作った話
repunit
0
170
A Bag-of-Documents Model for Query Specificity
dtunkelang
0
110
AI時代におけるエンジニアの新たな役割──FDEとクオリアの探求/登壇資料(戸井田 裕貴)
hacobu
PRO
0
480
クラウドを使う側から、作る側へ / 大吉祥寺.pm 2026前夜祭
fujiwara3
7
1.5k
複数プロダクトで進めるAI機能実装 ── 実践から得たリアルな学びとロードマップ実現への挑戦 / AICon2026_yanari
rakus_dev
1
310
なぜ、あなたのAPIは使われないのか? AX時代の設計原則、ガードレール、運用体制
yokawasa
1
230
AI驚き屋発見器
yama3133
1
330
AI時代こそ、スケールしないことをしよう -「作る人」から「なぜ作るか」を考える人へ / Do Things That Don't Scale in the AI Era — From How to Why
kaminashi
1
160
AIコード生成×サプライチェーン攻撃 — PHPが直面する“二重の信頼問題
shinyasaita
0
490
Featured
See All Featured
Site-Speed That Sticks
csswizardry
13
1.4k
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.9k
We Are The Robots
honzajavorek
0
280
WCS-LA-2024
lcolladotor
0
760
The untapped power of vector embeddings
frankvandijk
2
1.8k
A Modern Web Designer's Workflow
chriscoyier
698
190k
The AI Revolution Will Not Be Monopolized: How open-source beats economies of scale, even for LLMs
inesmontani
PRO
3
3.7k
The Anti-SEO Checklist Checklist. Pubcon Cyber Week
ryanjones
0
190
How to make the Groovebox
asonas
2
2.3k
Large-scale JavaScript Application Architecture
addyosmani
515
110k
Crafting Experiences
bethany
1
230
Testing 201, or: Great Expectations
jmmastey
46
8.2k
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:筋トレ・ポーカー
旧 新