Upgrade to Pro — share decks privately, control downloads, hide ads and more …

PHPにおけるアトリビュートの活用方法

will1992114
November 30, 2022

 PHPにおけるアトリビュートの活用方法

PHPerのための「PHPフレームワーク」を語り合うPHP TechCafe
で発表
https://rakus.connpass.com/event/264108/

will1992114

November 30, 2022
Tweet

Other Decks in Programming

Transcript

  1. <?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() . "は必須のプロパティです。"); } } } • 活⽤法①:バリデーションの共通化 • コンストラクタ実⾏時のバリデーションをアトリビュートで共通化する。
  2. 活⽤法①:バリデーションの共通化 <?php class SampleClass { use Validator; #[Required] public $keyA;

    public $keyB; public function __construct($keya, $keyb) { $this->keyA = $keya; $this->keyB = $keyb; $this->validate($this); }
  3. 活⽤法①:バリデーションの共通化 <?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() . "は必須のプロパティです。"); } }
  4. 活⽤例②:ロギング処理の共通化 #[Attribute(Attribute::TARGET_METHOD)] class Log { } class LogSample { #[Log]

    public function LogSample($arg1, $arg2) { echo ("LogSample() を実⾏しています" . "¥n"); return "LogSample()のReturn"; }
  5. 活⽤例②:ロギング処理の共通化 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"); }
  6. 活⽤例②:ロギング処理の共通化 $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");