Как работают атрибуты PHP 8?
и В PHP 8, был введен в attributos, которые могут быть использованы в классы или методы.
Например:
namespace MyExample;
use Attribute;
#[Attribute]
class MyAttribute
{
const VALUE = 'value';
private $value;
public function __construct($value = null)
{
$this->value = $value;
}
}
// b.php
namespace Another;
use MyExample\MyAttribute;
#[MyAttribute]
#[\MyExample\MyAttribute]
#[MyAttribute(1234)]
#[MyAttribute(value: 1234)]
#[MyAttribute(MyAttribute::VALUE)]
#[MyAttribute(array("key" => "value"))]
#[MyAttribute(100 + 200)]
class Thing
{
}
#[MyAttribute(1234), MyAttribute(5678)]
class AnotherThing
{
}
и у меня есть некоторые сомнения относительно того:
- Как я могу получить значения этих атрибутов, определенных в класс или метод?
- Какова цель атрибуты? Атрибуты имеет целью изменить поведение метода/класса, или просто дополнительные данные?
1 answers
Какова цель атрибуты? Атрибуты имеет целью изменить поведение метода/класса, или просто дополнительные данные?
Согласно документации:
Атрибуты позволяют добавлять метаданные, структурированные и разборчивым в заявления в коде: классов, методов, функций, параметров, свойств и констант класса может быть целевой атрибут. Метаданные, определенные размещение атрибутов могут быть проверены во время выполнения с помощью Api Reflection [...]
Таким образом, атрибуты, не имеет целью изменить поведение метода или функции, как и в случае Decorator Python, но да, только добавить метаданные (дополнительную информацию).
Как я могу получить значения этих атрибутов, определенных в класс или метод?
, Как сказано в документации, вы должны использовать Reflection API. Reflection API позволяет доступ к информации, класс, функция, метод, параметры и etc.
Например:
#[Attribute]
class Route
{
public function __construct(protected string $path) {}
public function getPath()
{
return $this->path;
}
}
class UsuariosController
{
#[Route("/usuarios")]
public function index()
{
}
}
Вы могли бы получить эту информацию так:
$reflection_method = new ReflectionMethod(UsuariosController::class, 'index');
foreach ($reflection_method->getAttributes(Route::class) as $reflection_attribute) {
$route = $reflection_attribute->newInstance();
echo $route->getPath(), "\n"; // "/usuarios"
}
Обратите внимание, что класс, который представляет ваш пользовательский атрибут, нужно всегда содержать заявление #[Attribute]
в своих заявлениях.
Кроме того, обратите внимание, что метод Reflection::getAttributes
возвращает array
ReflectionAttribute
. Это потому, что вы можете заявить более одного атрибута в класс или метод.
См.:
class UsuariosController
{
#[Route("/usuarios")]
#[Route("/usuarios/listar")]
#[RouteName("usuarios.listar")
public function index()
{
//
}
}
В Этом вопрос, есть ответ, который объясняет природу лучше из атрибутов: