1--TEST-- 2Attributes expose and verify target and repeatable data. 3--FILE-- 4<?php 5 6#[Attribute(Attribute::TARGET_FUNCTION | Attribute::TARGET_METHOD)] 7class A1 { } 8 9$ref = new \ReflectionFunction(#[A1] function () { }); 10$attr = $ref->getAttributes()[0]; 11var_dump($attr->getName(), $attr->getTarget() == Attribute::TARGET_FUNCTION, $attr->isRepeated()); 12var_dump(get_class($attr->newInstance())); 13 14echo "\n"; 15 16$ref = new \ReflectionObject(new #[A1] class() { }); 17$attr = $ref->getAttributes()[0]; 18var_dump($attr->getName(), $attr->getTarget() == Attribute::TARGET_CLASS, $attr->isRepeated()); 19 20try { 21 $attr->newInstance(); 22} catch (\Throwable $e) { 23 var_dump('ERROR 1', $e->getMessage()); 24} 25 26echo "\n"; 27 28$ref = new \ReflectionFunction(#[A1] #[A1] function () { }); 29$attr = $ref->getAttributes()[0]; 30var_dump($attr->getName(), $attr->getTarget() == Attribute::TARGET_FUNCTION, $attr->isRepeated()); 31 32try { 33 $attr->newInstance(); 34} catch (\Throwable $e) { 35 var_dump('ERROR 2', $e->getMessage()); 36} 37 38echo "\n"; 39 40#[Attribute(Attribute::TARGET_CLASS | Attribute::IS_REPEATABLE)] 41class A2 { } 42 43$ref = new \ReflectionObject(new #[A2] #[A2] class() { }); 44$attr = $ref->getAttributes()[0]; 45var_dump($attr->getName(), $attr->getTarget() == Attribute::TARGET_CLASS, $attr->isRepeated()); 46var_dump(get_class($attr->newInstance())); 47 48?> 49--EXPECT-- 50string(2) "A1" 51bool(true) 52bool(false) 53string(2) "A1" 54 55string(2) "A1" 56bool(true) 57bool(false) 58string(7) "ERROR 1" 59string(70) "Attribute "A1" cannot target class (allowed targets: function, method)" 60 61string(2) "A1" 62bool(true) 63bool(true) 64string(7) "ERROR 2" 65string(35) "Attribute "A1" must not be repeated" 66 67string(2) "A2" 68bool(true) 69bool(true) 70string(2) "A2" 71