The engine acts on a few attributes itself. #[\Deprecated] (8.4) makes a function, method or class constant emit a deprecation, as Subsection 4.11.9 showed; 8.5 extends it to traits and global constants. #[\SensitiveParameter] (8.2) replaces an argument in stack traces with a SensitiveParameterValue, so passwords stay out of logs. #[\NoDiscard] (8.5) warns when a caller ignores a return value; casting the call to (void) marks a deliberate discard.
<?php
ini_set('zend.exception_ignore_args', '0'); // production php.ini hides arguments
ini_set('zend.exception_string_param_max_len', '15'); // ...and prints strings as '...'
function login(string $user, #[\SensitiveParameter] string $password): never {
throw new RuntimeException('Login failed');
}
#[\NoDiscard('the discounted price is the only result')]
function discounted(int $cents, int $pct): int { return intdiv($cents * (100 - $pct), 100); }
try { login('ann', 'hunter2'); }
catch (RuntimeException $e) { echo $e->getTraceAsString(), "\n"; }
discounted(2000, 10); // result dropped: warning
(void) discounted(2000, 10); // deliberate discard: silent#0 /tmp/ch04-11/builtins.php(10): login('ann', Object(SensitiveParameterValue))
#1 {main}
PHP Warning: The return value of function discounted() should either be used or intentionally
ignored by casting it as (void), the discounted price is the only result in
/tmp/ch04-11/builtins.php on line 12#[\Override] (8.3, and on properties since 8.5) states that a member must replace one from a parent class or interface. Misspell the method, or rename the parent's, and the class no longer compiles: a lable() marked this way fails with "Book::lable() has #[\Override] attribute, but no matching parent method exists". Put it on every overriding method. PHP 8.5 marks some of its own functions with #[\NoDiscard] too: ignoring the result of flock() or DateTimeImmutable::setDate() now warns.