(PHP 8)
Os atributos PHP fornecem metadados estruturados e legíveis por máquina para classes, métodos, funções, parâmetros, propriedades e constantes. Eles podem ser inspecionados no momento da execução por meio da API Reflection, permitindo comportamento dinâmico sem modificar o código. Os atributos fornecem uma maneira declarativa de anotar código com metadados.
Atributos permitem o desacoplamento da implementação de um recurso de seu uso. Enquanto interfaces definem estrutura ao impor métodos, atributos fornecem metadados em vários elementos, incluindo métodos, funções, propriedades e constantes. Diferentemente de interfaces, que impõem implementações de métodos, atributos anotam código sem alterar sua estrutura.
Atributos podem complementar ou substituir métodos de interface opcionais fornecendo metadados em vez de
estrutura imposta. Considere uma interface ActionHandler
que representa uma
operação em um aplicativo. Algumas implementações podem exigir uma etapa de configuração, enquanto outras não.
Em vez de forçar todas as classes que implementam ActionHandler
a definir um
método setUp()
, um atributo pode indicar requisitos de configuração. Essa abordagem
aumenta a flexibilidade, permitindo que os atributos sejam aplicados várias vezes quando necessário.
Exemplo #1 Implementando métodos opcionais de uma interface com Atributos
<?php
interface ActionHandler
{
public function execute();
}
#[Attribute]
class SetUp {}
class CopyFile implements ActionHandler
{
public string $fileName;
public string $targetDirectory;
#[SetUp]
public function fileExists()
{
if (!file_exists($this->fileName)) {
throw new RuntimeException("Arquivo não existe");
}
}
#[SetUp]
public function targetDirectoryExists()
{
if (!file_exists($this->targetDirectory)) {
mkdir($this->targetDirectory);
} elseif (!is_dir($this->targetDirectory)) {
throw new RuntimeException("Diretório de destino $this->targetDirectory não é um diretório");
}
}
public function execute()
{
copy($this->fileName, $this->targetDirectory . '/' . basename($this->fileName));
}
}
function executeAction(ActionHandler $actionHandler)
{
$reflection = new ReflectionObject($actionHandler);
foreach ($reflection->getMethods() as $method) {
$attributes = $method->getAttributes(SetUp::class);
if (count($attributes) > 0) {
$methodName = $method->getName();
$actionHandler->$methodName();
}
}
$actionHandler->execute();
}
$copyAction = new CopyFile();
$copyAction->fileName = "/tmp/foo.jpg";
$copyAction->targetDirectory = "/home/user";
executeAction($copyAction);