PHP Native AttributesPHP native attributes

In PHP 8.0, PHP added native attributes to its vast arsenal of features. Later, the first native attribute, aka, available in the core of PHP, appeared. Here they are, for quick reference.

In PHP 8.3, there are 5 native attributes.

  • PHP 8.0
    • Attribute
  • PHP 8.1
    • ReturnTypeWillChange
    • SensitiveParameter
  • PHP 8.2
    • AllowDynamicProperties
  • PHP 8.3
    • Override
  • PHP 8.4
    • None so far

PHP Native Attributes

Attribute is the attribute to make a class a valid Attribute class. This definition sound pretty meta, but it is quite simple : there must be a first class that defines what an attribute is.

It is not compulsory, although, as a gesture of courtesy to the next developer : just add it to every attribute class, and all will be fine.

Available since PHP 8.0.

ReturnTypeWillChange

ReturnTypeWillChange characterize a method, whose returntype will change in child classes. This prevents PHP from emitting an error about a possible type mismatch.

It was created when the native PHP method JsonSerializable::jsonSerialize()received the mixed returntype. Although that type is the universal type, as it accepts everything, PHP reports a type mismatch with any method which doesn’t use that type. Adding this attribute relax that constraint.

It only works with PHP native methods, and has no effect on custom methods.

<?php

class x implements JsonSerializable { 
    #[\ReturnTypeWillChange] 
    function jsonSerialize() {} 
}

?>

 

Here is a list of PHP native interfaces and methods, which may require their usage :

  • JsonSerializable::jsonSerialize()
  • SessionHandlerInterface::open()
  • SessionHandlerInterface::close()
  • SessionHandlerInterface::read()
  • SessionHandlerInterface::write()
  • SessionHandlerInterface::destroy()
  • SessionHandlerInterface::gc()
  • Iterator::current()
  • Iterator::next()
  • Iterator::key()
  • Iterator::valid()
  • Iterator::rewind()
  • Countable::count()
  • IteratorAggregate::getIterator()
  • php_user_filter::filter()
  • ArrayAccess::offsetGet()
  • ArrayAccess::offsetSet()
  • ArrayAccess::offsetUnset()
  • ArrayAccess::offsetExists()
  • RecursiveIterator::getChildren()
  • FilterIterator::accept()
  • Exception::__wakeup()

Available since PHP 8.1.

SensitiveParameter

SensitiveParameter mark arguments as security sensitive, so that they will be automatically masked when a debug backtrace is displayed. Here is an example :

<?php

function passwordHash($user, #[SensitiveParameter] string $password) {
    var_dump(debug_backtrace());
}

passwordHash('my', 'password');
?>

With PHP 8.2, the result is the following :

Array
(
   [0] => Array
      (
         [file] => /Users/famille/Desktop/analyzeG3/test.php
         [line] => 7
         [function] => foo
         [args] => Array
           (
              [0] => my
              [1] => SensitiveParameterValue Object
           )
         )
      )

Properties are not covered by this parameter. For them, there is already the __debugInfo(), which may be used to hide any sensitive value, instead of displaying it.

Available in PHP 8.2.

AllowDynamicProperties

AllowDynamicProperties relaxes the compulsory property definition that starts with PHP 8.2. The default behavior is now to declare explicitely all properties. Yet, since dynamic properties are a valid use case, albeit a rare one, it is possible to relax this constraint by using this attribute.

<?php

#[AllowDynamicProperties]
class x { }

$x = new x;
// In PHP 8.2 : PHP Deprecated:  Creation of dynamic property x::$foo is deprecated 
$x->foo = 1;

?>

Another option is to use the Stdclass or extend it. This class is built-in with that attribute.

Available in PHP 8.2.

Override

The override attribute is used to explicitly indicate that a method in a subclass is overriding a method in the parent class. This attribute has no special effect, unlike other PHP native attribute. It simply state the intention to override a parent method. It is mainly used for documentation and be used by static code analysers.

<?php
class Foo {
    function x() {
        echo __METHOD__ . PHP_EOL;
    }
}

class Bar extends Foo { 
    function x() { 
       echo __METHOD__ . PHP_EOL; 
    } 
} 
?>

Available in PHP 8.3.