Playing a little bit with the new PHP 8 attributes (annotations) (https://stitcher.io/blog/attributes-in-php-8) I started to create my own ones.
Simple example:
namespace CisToolsAttribute; use Attribute; use CisToolsExceptionBadAttributeMetadataException; /** * For defining a description. */ #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD | Attribute::TARGET_FUNCTION)] class Description { /** * @param string $description * @throws BadAttributeMetadataException */ public function __construct(string $description) { if (strlen($description) < 10) { throw new BadAttributeMetadataException("This is description is too short."); } } }
Hoping that the following code would throw an BadAttributeMetadataException
unfortunately it finishes successfully:
use CisToolsAttributeDescription; #[Description("quack")] class Test { public function __construct() { echo "hello world"; } } new Test();
Is there away to validate the metadata passed for (custom) attributes? Most probably the attributes have to be instantiated automatically somehow.
Advertisement
Answer
Everything is possible – as of today I have implemented a working solution for this problem which can very well be used in libraries (just in case somebody needs that too):
function cis_shutdown_validate_attributes() { if(!defined('CIS_DISABLE_ATTRIBUTE_VALIDATION')) { foreach(get_declared_classes() as $class) { try { $reflection = new ReflectionClass($class); } catch (Throwable $throwable) { continue; } $attributes = $reflection->getAttributes(); foreach ($attributes as $attribute) { $attribute->newInstance(); } } } } register_shutdown_function('cis_shutdown_validate_attributes');
(You may also autoload it: Composer/PSR – How to autoload functions?)