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
S3操作の落とし穴から学ぶ Laravel File Storageと例外処理
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
maimyyym
July 02, 2024
Technology
2.1k
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
S3操作の落とし穴から学ぶ Laravel File Storageと例外処理
2024/07/02
Fusic Tech Live Vol.20 〜PHPer CONNECT〜
https://fusic.connpass.com/event/317123/
maimyyym
July 02, 2024
More Decks by maimyyym
See All by maimyyym
組織内の開発ポリシーを 整えるはじめの一歩
maimyyym
1
76
未来の自分と明日の誰かへ繋ぐ、非連続的なキャリアと再現性の分析
maimyyym
0
170
AWSを使う上で最低限知っておきたいセキュリティ研修を社内で実施した話 ~みんなでやるセキュリティ~
maimyyym
3
2.4k
大規模サーバーレスAPIの堅牢性・信頼性設計 〜AWSのベストプラクティスから始まる現実的制約との向き合い方〜
maimyyym
11
6.4k
Amazon Inspector コードセキュリティで手軽に実現するシフトレフト
maimyyym
1
860
組織とセキュリティ文化と、自分の一歩
maimyyym
3
1.7k
大規模サーバーレスプロジェクトのリアルな零れ話
maimyyym
3
460
ABWG2024採択者が語るエンジニアとしての自分自身の見つけ方〜発信して、つながって、世界を広げていく〜
maimyyym
1
610
re:Invent2024で広がった AWS Verified Accessの可能性を探る
maimyyym
1
380
Other Decks in Technology
See All in Technology
データサイエンスを価値につなげるプロジェクト設計 〜 DS一年目が現場で得た気づき 〜
ysd113
1
280
Oracle AI Database@Google Cloud:サービス概要のご紹介
oracle4engineer
PRO
6
1.5k
SONiC Scale-Up Working Group から探る Scale-UpやUltraEthernet機能の実装方法
ebiken
PRO
2
400
Kiro Ambassador を目指す話
k_adachi_01
0
110
20260619 私の日常業務での生成 AI 活用
masaruogura
1
230
2026TECHFRESH畢業分享會 - Lightning Talk - 資料也要 CI/CD? 用 Airbyte 自動化資料同步
line_developers_tw
PRO
0
1.2k
GitHub Copilot app最速の発信の裏側
tomokusaba
1
110
いまさら聞けない「仕様駆動開発入門」 〜AI活用時代の開発プロセスを考える〜
findy_eventslides
2
160
自分が詳しくない領域でAIを使う #プロヒス2026
konifar
7
2k
現地で盛り上がった WWDC26 Keynote
zozotech
PRO
1
260
OTel × Datadog で 「AI活用」を計測し、改善に繋げる
shihochan
1
310
【2026年版】 ベクトル検索とEmbedding最前線
mocobeta
14
3.8k
Featured
See All Featured
Building Experiences: Design Systems, User Experience, and Full Site Editing
marktimemedia
0
530
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
430
Automating Front-end Workflow
addyosmani
1370
210k
Writing Fast Ruby
sferik
630
63k
How to train your dragon (web standard)
notwaldorf
97
6.7k
Organizational Design Perspectives: An Ontology of Organizational Design Elements
kimpetersen
PRO
1
750
Leo the Paperboy
mayatellez
7
1.8k
Code Review Best Practice
trishagee
74
20k
The Pragmatic Product Professional
lauravandoore
37
7.3k
brightonSEO & MeasureFest 2025 - Christian Goodrich - Winning strategies for Black Friday CRO & PPC
cargoodrich
3
730
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
270
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
2k
Transcript
©Fusic Co., Ltd. 0 S3操作の落とし⽳から学ぶ Laravel File Storageと例外処理 2024.07.02 Mai
Miyazaki @maimyyym Fusic Tech Live Vol.20 〜PHPer CONNECT〜
©Fusic Co., Ltd. 1 はじめに ⾃⼰紹介 / 今⽇話すこと 0
©Fusic Co., Ltd. 2 宮崎 真⾐ Miyazaki Mai HN: mai
(@maimyyym ) ◉ I am - 管理栄養⼠(養成校卒業・資格保持のみ) - 元百貨店スタッフ(Beauty Counselor) - 2023年10⽉ Fusic⼊社 ◉ Skill - PHP / AWS / TypeScript / Python ◉ Comment - Tech Live初登壇です!うれしい! ⾃⼰紹介 はじめに 事業本部 技術創造部⾨ / エンジニア 株式会社Fusic
©Fusic Co., Ltd. 3 今⽇話すこと はじめに Laravel on FargateでのS3操作 Laravel
Filesystemにおける例外処理 について経験して、学んで、考えてみた話
©Fusic Co., Ltd. 4 CONTENTS ⽬次 1. こんな構成・処理 2. Laravelのファイルシステム
3. 困ったこと・その答え 4. 例外処理の話 / どうしたらよかったのか 5. まとめ
©Fusic Co., Ltd. 5 こんな構成・こんな処理 環境 / Laravel on FargateでS3操作したい
/ 実装 1
©Fusic Co., Ltd. 6 環境 こんな構成・こんな処理 PHP8.3 Laravel10
©Fusic Co., Ltd. 7 Laravel on FargateでS3操作したい こんな構成・こんな処理
©Fusic Co., Ltd. 8 LaravelのStorageファサードで実装する こんな構成・こんな処理 try { Storage::disk("s3")->copy( $sourcePath,
$distinationPath ); } catch (\Exception $e) { Log::error(''. $e->getMessage()); return redirect()->route(‘user.top’)->with(‘error’, ‘copy失敗'); } return redirect()->route('user.top')->with('success', 'copy成功'); Storageファサードは抽象化された Filesystemによって、ストレージの 種類によらずコピー等の操作を 簡単に実装できる。 Storage::disk(ʻs3ʼ)->copy($from, $to);
©Fusic Co., Ltd. 9 Laravelのファイルシステム Flysystem / 使い⽅ / 動かしてみる
2
©Fusic Co., Ltd. 10 Flysystem Laravelのファイルシステム Laravelのファイルシステムは、Flysystemというライブラリを使⽤して 実装されている。 【 Flysystem
とは?】 PHPのためのファイルストレージライブラリ。 異なるストレージドライバ(ローカル、S3、FTPなど)に対する ⼀貫したインターフェースを提供する。 ストレージシステムの種類を問わず、 コードを変更することなく簡単に切り替えることができる。
©Fusic Co., Ltd. 11 使い⽅ Laravelのファイルシステム 1. アダプタをインストールする 2. ファイルシステム設定(config/filesystems.php)
3. 使う: composer require league/flysystem-aws-s3-v3 "^3.0" --with-all-dependencies 's3' => [ 'driver' => 's3’, 'key' => env('AWS_ACCESS_KEY_ID’), 'secret' => env('AWS_SECRET_ACCESS_KEY’), 'region' => env('AWS_DEFAULT_REGION’), 'bucket' => env('AWS_BUCKET’), 'throw’ => false, ] Storage::disk("s3")->xxx();
©Fusic Co., Ltd. 12 動かしてみる Laravelのファイルシステム Storage::disk("s3")->copy( $source/hoge.png, $copy/hoge.png );
"POST /xxx.php" 200 logs コピーできてない!
©Fusic Co., Ltd. 13 困ったこと・その答え コピー処理ができていない / 考えたこと / 答えは・・・
3
©Fusic Co., Ltd. 14 コピー処理ができていなかった 困ったこと・その答え 【やろうとしたこと】 S3に保存された画像ファイルのコピー操作や その他DB操作等を含む⼀連の処理 《⼊⼒》
↓ 処理A ↓ 処理B ↓ S3コピー処理 ↓ 《出⼒》
©Fusic Co., Ltd. 15 コピー処理ができていなかった 困ったこと・その答え 【やろうとしたこと】 S3に保存された画像ファイルのコピー操作や その他DB操作等を含む⼀連の処理 【結果】
レスポンス:200OK しかし、S3のコピー処理だけができていない ※その他DB操作等の処理は全てできていた 《⼊⼒》 ↓ 処理A ↓ 処理B ↓ S3コピー処理 ↓ 《出⼒》 OK! OK! Failed…😰 200OK $request
©Fusic Co., Ltd. 16 コピー処理ができていなかった 困ったこと・その答え 【やろうとしたこと】 S3に保存された画像ファイルのコピー操作や その他DB操作等を含む⼀連の処理 【結果】
レスポンス:200OK しかし、S3のコピー処理だけができていない ※その他DB操作等の処理は全てできていた 《⼊⼒》 ↓ 処理A ↓ 処理B ↓ S3コピー処理 ↓ 《出⼒》 OK! OK! Failed…😰 200OK $request コピーしたオブジェクトの 取得処理ができず、気づいた
©Fusic Co., Ltd. 17 考えたこと 困ったこと・その答え CPU使⽤率が⾼くなる… move() もできない! get()
→ put() だと うまくいく Filesystemの裏側の 処理に違いが? ロジックに問題が?
©Fusic Co., Ltd. 18 考えたこと 困ったこと・その答え CPU使⽤率が⾼くなる… move() もできない! get()
→ put() だと うまくいく Filesystemの裏側の 処理に違いが? ロジックに問題が? でも・・・ 裏側が複雑な実装だとは思えない! 【 copy() 】と【 get() → put() 】で ⼤きな差が出るとは思えない…
©Fusic Co., Ltd. 19 考えたこと 困ったこと・その答え CPU使⽤率が⾼くなる… move() もできない! get()
→ put() だと うまくいく Filesystemの裏側の 処理に違いが? ロジックに問題が? では、原因は何…?
©Fusic Co., Ltd. 20 答えは・・・ 困ったこと・その答え ポリシー不⾜でした。
©Fusic Co., Ltd. 21 { "Version": "2012-10-17", "Statement": [ {
"Action": [ "s3:ListBucket", "s3:PutObject", "s3:GetObject", "s3:PutObjectAcl", "s3:GetObjectAcl", ], "Effect": "Allow", "Resource": "*" }, ] } 【正しくは…】 答えは・・・ 困ったこと・その答え ポリシー不⾜でした。 タスクロール { "Version": "2012-10-17", "Statement": [ { "Action": [ "s3:ListBucket", "s3:PutObject", "s3:GetObject", ], "Effect": "Allow", "Resource": "*" }, ] } 【現在】
©Fusic Co., Ltd. 22 答えは・・・ 困ったこと・その答え ドキュメントがあった。 またコンソール内のオブジェクトのコピー、カット、貼り付けを⾏う ためには、s3:PutObjectAcl および
s3:GetObjectAcl アクションが必要 となります。 https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/example-policies-s3.html#iam-policy-ex3
©Fusic Co., Ltd. 23 S3のアクセスコントロールリスト(ACL) 困ったこと・その答え PutObjectAcl, GetObjectAclとは? 【Amazon S3のアクセスコントロールリスト(ACL)とは】
バケットとオブジェクトへのアクセスを管理するもの。 各バケットとオブジェクトにはサブリソースとしてACLがアタッチされる。
©Fusic Co., Ltd. 24 S3のアクセスコントロールリスト(ACL) 困ったこと・その答え PutObjectAcl, GetObjectAclとは? 【Amazon S3のアクセスコントロールリスト(ACL)とは】
バケットとオブジェクトへのアクセスを管理するもの。 各バケットとオブジェクトにはサブリソースとしてACLがアタッチされる。
©Fusic Co., Ltd. 25 ACL ACL S3のアクセスコントロールリスト(ACL) 困ったこと・その答え PutObjectAcl, GetObjectAclとは?
ACL ACL 同じ状態を複製する=コピーという操作には オブジェクトとACLの両⽅を取得・保存する権限が必要 GetObject GetObjectAcl
©Fusic Co., Ltd. 26 答え 困ったこと・その答え ポリシー不⾜は分かった。copy()は使えるようになった。 でも・・・ この問題が発⽣した根本的な原因は? なぜ成功を⽰すレスポンスが?
失敗をキャッチできなかったのは何故?
©Fusic Co., Ltd. 27 例外処理の話 / どうしたらよかったのか copyメソッドの中⾝を⾒てみる / Flysystem3.xの仕様
/例外 vs false 仕様と向き合い、仕様を定める 4
©Fusic Co., Ltd. 28 copyメソッドの中⾝を⾒てみる 例外処理の話 / どうしたらよかったのか FilesystemAdapter.phpのcopyメソッドを⾒てみる public
function copy($from, $to) { try { $this->driver->copy($from, $to); } catch (UnableToCopyFile $e) { throw_if($this->throwsExceptions(), $e); return false; } return true; } 私たちがコードとして書くストレージ操作と Flysystemを橋渡しするクラス
©Fusic Co., Ltd. 29 copyメソッドの中⾝を⾒てみる 例外処理の話 / どうしたらよかったのか FilesystemAdapter.phpのcopyメソッドを⾒てみる public
function copy($from, $to) { try { $this->driver->copy($from, $to); } catch (UnableToCopyFile $e) { throw_if($this->throwsExceptions(), $e); return false; } return true; } 私たちがコードとして書くストレージ操作と Flysystemを橋渡しするクラス 返り値は true / false
©Fusic Co., Ltd. 30 copyメソッドの中⾝を⾒てみる 例外処理の話 / どうしたらよかったのか FilesystemAdapter.phpのcopyメソッドを⾒てみる public
function copy($from, $to) { try { $this->driver->copy($from, $to); } catch (UnableToCopyFile $e) { throw_if($this->throwsExceptions(), $e); return false; } return true; } 私たちがコードとして書くストレージ操作と Flysystemを橋渡しするクラス 返り値は true / false $this->throwsExceptions() がtrueの時に例外を投げる
©Fusic Co., Ltd. 31 copyメソッドの中⾝を⾒てみる 例外処理の話 / どうしたらよかったのか throwsExceptions()を⾒てみる public
function copy($from, $to) { try { $this->driver->copy($from, $to); } catch (UnableToCopyFile $e) { throw_if($this->throwsExceptions(), $e); return false; } return true; } protected function throwsExceptions(): bool { return (bool) ($this->config['throw'] ?? false); } config🤔
©Fusic Co., Ltd. 32 copyメソッドの中⾝を⾒てみる 例外処理の話 / どうしたらよかったのか つまり、copyメソッドはどのように例外を投げるのか public
function copy($from, $to) { try { $this->driver->copy($from, $to); } catch (UnableToCopyFile $e) { throw_if($this->throwsExceptions(), $e); return false; } return true; } protected function throwsExceptions(): bool { return (bool) ($this->config['throw'] ?? false); } config[ʻthrowʼ] = 例外を投げる設定 がtrueであれば例外を投げ、 そうでなければfalseを返す
©Fusic Co., Ltd. 33 copyメソッドの中⾝を⾒てみる 例外処理の話 / どうしたらよかったのか 設定ファイルを⾒てみる 's3'
=> [ 'driver' => 's3’, 'key' => env('AWS_ACCESS_KEY_ID’), 'secret' => env('AWS_SECRET_ACCESS_KEY’), 'region' => env('AWS_DEFAULT_REGION’), 'bucket' => env('AWS_BUCKET’), 'throw’ => false, ] 【config/filesystems.php】 デフォルト設定 =falseのまま
©Fusic Co., Ltd. 34 copyメソッドの中⾝を⾒てみる 例外処理の話 / どうしたらよかったのか 呼び出し元を⾒てみる try
{ Storage::disk("s3")->copy( $sourcePath, $distinationPath ); } catch (\Exception $e) { Log::error(''. $e->getMessage()); return redirect()->route(‘user.top’)->with('error', 'copy失敗'); } return redirect()->route('user.top')->with('success', 'copy成功'); この処理結果を出⼒すると ”false ”だった。 例外をキャッチしていない
©Fusic Co., Ltd. 35 copyメソッドの中⾝を⾒てみる 例外処理の話 / どうしたらよかったのか 例外を投げる設定にする 's3'
=> [ 'driver' => 's3’, 'key' => env('AWS_ACCESS_KEY_ID’), 'secret' => env('AWS_SECRET_ACCESS_KEY’), 'region' => env('AWS_DEFAULT_REGION’), 'bucket' => env('AWS_BUCKET’), 'throw’ => true, ] 【config/filesystems.php】
©Fusic Co., Ltd. 36 copyメソッドの中⾝を⾒てみる 例外処理の話 / どうしたらよかったのか 再度、呼び出してみる try
{ Storage::disk("s3")->copy( $sourcePath, $distinationPath ); } catch (\Exception $e) { Log::error(''. $e->getMessage()); return redirect()->route(‘user.top’)->with('error', 'copy失敗'); } return redirect()->route('user.top')->with('success', 'copy成功'); 処理に失敗すると、 例外をキャッチするように!
©Fusic Co., Ltd. 37 Flysystem3.xの仕様 例外処理の話 / どうしたらよかったのか Laravel8までは例外を投げていた。 Laravel9で、Flysystemのバージョンが1.xから3.xに。
伴って、ファイル操作の仕様が⼀部変更。 その⼀つが書き込み失敗時に例外を投げなくなったこと。 (代わりに、falseを返すように) https://laravel.com/docs/9.x/upgrade#flysystem-3
©Fusic Co., Ltd. 38 例外 vs false 例外処理の話 / どうしたらよかったのか
仕組みは分かった。 例外を投げる設定をしていれば、確かに気づけた。 しかし、デフォルトはtrue / falseを返すだけ。 その思想は「アプリケーションを⽌めないこと」などが考えられる。 そもそもポリシーを知っていればよかった問題! テストフェーズで気づいたから成果物の挙動としては問題ない。 本当にそれでいいの?
©Fusic Co., Ltd. 39 例外 vs false 例外処理の話 / どうしたらよかったのか
betterはどっち? 例外を投げる その場で失敗が分かるべき 詳細なエラーログを保存・通知したい falseを返す アプリケーションは⽌めない falseの場合の挙動ロジックを⽤意する
©Fusic Co., Ltd. 40 仕様と向き合い、仕様を定める 例外処理の話 / どうしたらよかったのか betterはどっち? 例外を投げる
その場で失敗が分かるべき 詳細なエラーログを保存・通知したい falseを返す アプリケーションは⽌めない falseの場合の挙動ロジックを⽤意する ⼀つの正解はない
©Fusic Co., Ltd. 41 仕様と向き合い、仕様を定める 例外処理の話 / どうしたらよかったのか betterはどっち? 例外を投げる
その場で失敗が分かるべき 詳細なエラーログを保存・通知したい falseを返す アプリケーションは⽌めない falseの場合の挙動ロジックを⽤意する ⾔語・フレームワークの 仕組みや仕様を知ること どうあるべきかを考える 前提
©Fusic Co., Ltd. 42 仕様と向き合い、仕様を定める 例外処理の話 / どうしたらよかったのか フレームワークの仕様と向き合い、 アプリケーションの仕様を定める
©Fusic Co., Ltd. 43 まとめ S3操作の落とし⽳から学ぶLaravel File Storageと例外処理 Laravelのストレージ操作はPHPのファイルストレージライブラリ”Flysystem”で抽象化されている Point
01 S3のコピー処理においては、オブジェクトだけではなくACLを取得・保存する権限を付与する必要がある Point 02 Laravelのストレージ操作において、書き込み失敗時のデフォルトは「例外を投げず、falseを返す」 Point 03 フレームワークの仕様と向き合い、アプリケーションの仕様を定めることが⼤切 Point 04
©Fusic Co., Ltd. 44 Thank You We are Hiring! https://recruit.fusic.co.jp/
ご清聴いただきありがとうございました