#[\SensitiveParameter] — Keep Secrets Out of Stack Traces
PHP stack traces helpfully include every argument passed to every frame. That is wonderful while debugging and catastrophic the moment a password, an API key, or a card number rides along into your logs, your error tracker, and whatever third party ingests them.
function connect(string $user, string $password, string $host) {
throw new RuntimeException('Connection refused');
}
connect('admin', 'hunter2', 'db.internal');
// Before 8.2, the trace hands your password to the log file:
// #0 /app/db.php(12): connect('admin', 'hunter2', 'db.internal')
One attribute, and the engine redacts that argument everywhere a trace is rendered.
function connect(
string $user,
#[\SensitiveParameter] string $password,
string $host,
) {
throw new RuntimeException('Connection refused');
}
connect('admin', 'hunter2', 'db.internal');
// #0 /app/db.php(12): connect('admin', Object(SensitiveParameterValue), 'db.internal')
It costs one line, it applies to every trace the engine produces, and it works no matter which logger, error handler, or monitoring service eventually formats the exception. The value is wrapped in a SensitiveParameterValue object, so it is still there for code that genuinely needs it and gone from every string rendering.
PHP's own extensions use it. PDO::__construct, password_verify(), and the various database connect functions all mark their credential parameters, which means a stray exception in your data layer stopped leaking your database password the day you upgraded to 8.2.
Significance: Security by Default
#[\SensitiveParameter] moves the guarantee to the declaration site, where it is written once and cannot be forgotten by the next person to catch that exception.