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におけるアトリビュートの活用方法
Search
will1992114
November 30, 2022
Programming
0
430
PHPにおけるアトリビュートの活用方法
PHPerのための「PHPフレームワーク」を語り合うPHP TechCafe
で発表
https://rakus.connpass.com/event/264108/
will1992114
November 30, 2022
Tweet
Share
Other Decks in Programming
See All in Programming
Mastering Developer Experience: A Roadmap for Success 【開発生産性Conference 2024】
findyinc
1
380
リハビリmruby
kishima
1
160
AWS初心者ってどうやってAWSを学ぶ?〜アプリエンジニアがやってよかったアーキテクチャ学習方法〜
yamanashi_ren01
0
190
実用的かつリーズナブルな 「Azure × Gemini × LINE」~キャラクターBot 実装ライブデモ~
tomodo_ysys
1
170
Rubyのパフォーマンスプロファイリングの改善 / Enhancing performance profiling for Ruby
osyoyu
1
410
Trial
cairolibrary720
1
130
初心者がおさえておきたいAWS CDKのベストプラクティス 2024
konokenj
15
7.3k
Rust.Nagoya #1
codemountains
0
170
How to use Macrobenchmark
veronikapj
0
160
Exploring the Gradually Lost Technical Skills in the Cloud Native Era
hwchiu
2
3.9k
最古の関数型言語「Lisp」ことはじめ / lisp_in_kamiyama
uhooi
1
190
GraphQL はいいぞ! ~Laravel で学ぶ GraphQL 入門~
azuki
1
160
Featured
See All Featured
Bash Introduction
62gerente
607
210k
YesSQL, Process and Tooling at Scale
rocio
166
14k
The Art of Programming - Codeland 2020
erikaheidi
48
13k
Documentation Writing (for coders)
carmenintech
63
4.2k
Infographics Made Easy
chrislema
238
18k
The Illustrated Children's Guide to Kubernetes
chrisshort
39
47k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
224
21k
Navigating Team Friction
lara
181
13k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
189
16k
Designing for humans not robots
tammielis
247
25k
Typedesign – Prime Four
hannesfritz
37
2.2k
Debugging Ruby Performance
tmm1
71
11k
Transcript
PHPにおけるアトリ ビュートの活⽤⽅法 株式会社ケアリッツ・テクノロジーズ 栗原 駿 2022/11/29
⾃⼰紹介 • 名前:栗原 駿 • 所属:株式会社ケアリッツ・テクノロジーズ • 主な経験⾔語:C# • PHPは業務で使い始めて半年ほどです。
• 趣味:マラソン(最近全然⾛ってない…) • 最近はサウナにはまってます!
話すこと • PHPにおけるアトリビュートとは • 活⽤例①:バリデーションの共通化 • 活⽤例②:ロギング処理の共通化
PHPにおけるアトリビュートとは #[Description("アトリビュートの説明⽤のクラス")] class Example { #[Description("プロパティ")] public string $key; #[Description("メソッド")]
public function execute( #[Description("引数")]$arg) : void { } }
PHPにおけるアトリビュートとは • メタデータをコードの宣⾔時に埋め込むことができる • 実⾏時にリフレクションAPIで読み取って使⽤する • 様々な⽤途で使⽤できる • ロジックの共通化 •
IDEへの補助的な情報の通知 • クラス、メソッド、関数、パラメータ、プロパティ、クラス定数に指定できる
<?php class SampleClass { public $keyA; public $keyB; public function
__construct($keya, $keyb) { $this->keyA = $keya; $this->keyB = $keyb; if($this->keyA === null) { throw new Exception($property->getName() . "は必須のプロパティです。"); } } } • 活⽤法①:バリデーションの共通化 • コンストラクタ実⾏時のバリデーションをアトリビュートで共通化する。
活⽤法①:バリデーションの共通化 <?php class SampleClass { use Validator; #[Required] public $keyA;
public $keyB; public function __construct($keya, $keyb) { $this->keyA = $keya; $this->keyB = $keyb; $this->validate($this); }
活⽤法①:バリデーションの共通化 <?php trait Validator { function validate($input): bool { $reflection
= new ReflectionObject($input); foreach ($reflection->getProperties() as $key => $property) { $isRequired = $property->getAttributes(Required::class) > 0; if ($isRequired && $property->getValue($input) === null) { throw new Exception($property->getName() . "は必須のプロパティです。"); } }
活⽤例②:ロギング処理の共通化 • アトリビュートを付加したメソッドについて、 実⾏開始時と完了時にログを出⼒する • Ray.Aopというフレームワークを使⽤する • AOP(アスペクト指向プログラミング)のための機能を提供する
活⽤例②:ロギング処理の共通化 LogSample (処理を注⼊したいクラス) Log (処理の注⼊先を指定するア トリビュート) Ray.Aop LogInterceptor (注⼊する処理の実装) 特定の関数に指定
#[Log]を指定するクラスに対して、 インスタンス化時にLogInterceptor を注⼊する
活⽤例②:ロギング処理の共通化 #[Attribute(Attribute::TARGET_METHOD)] class Log { } class LogSample { #[Log]
public function LogSample($arg1, $arg2) { echo ("LogSample() を実⾏しています" . "¥n"); return "LogSample()のReturn"; }
活⽤例②:ロギング処理の共通化 class LogInterceptor implements MethodInterceptor { public function invoke(MethodInvocation $invocation)
{ // 処理実⾏前 echo (date(DATE_ATOM) . ":" . $invocation->getMethod()->getName() . "の実⾏前 引数:" . json_encode($invocation->getArguments()) . "¥n"); // 実処理の実⾏ $result = $invocation->proceed(); // 処理実⾏後 echo (date(DATE_ATOM) . ":" . $invocation->getMethod()->getName() . "の実⾏後 戻り値:" . $result . "¥n"); }
活⽤例②:ロギング処理の共通化 $pointcut = new Pointcut( (new Matcher())->any(), (new Matcher())->annotatedWith(Log::class), [new
LogInterceptor()] ); $bind = (new Bind())->bind(LogSample::class, [$pointcut]); $tmpDir = __DIR__ . '/tmp'; $sample = (new Weaver($bind, $tmpDir))->newInstance(LogSample::class, []); $sample->LogSample("arg1", "arg2");
活⽤例②:ロギング処理の共通化 実⾏結果… > 2022-11-28T22:01:17+00:00:LogSampleの実⾏前 引数:{“0”:“arg1”,“1”:“arg2”} ←LogInterceptorのLog(実⾏前) > LogSample() を実⾏しています ←LogSampleのLog
> 2022-11-28T22:01:17+00:00:LogSampleの実⾏後 戻り値:LogSample()のReturn ←LogInterceptorのLog(実⾏後)
まとめ • PHPのアトリビュートを使うことでコードにメタデータを付加できる • 付加したメタデータを実⾏時に読み取ることでロジックの共通化ができる
ご清聴ありがとうございました