Attributes overview
Overzicht van Attributen
PHP-attributen bieden gestructureerde, machine-leesbare metadata voor klassen, methoden, functies, parameters, eigenschappen en constanten. Ze kunnen tijdens runtime worden geïnspecteerd via de Reflection API, waardoor dynamisch gedrag mogelijk is zonder de code te wijzigen. Attributen bieden een declaratieve manier om code te annoteren met metadata.
Attributen maken het mogelijk om de implementatie van een functie te scheiden van het gebruik ervan. Terwijl interfaces structuur definiëren door methoden af te dwingen, bieden attributen metadata over meerdere elementen, waaronder methoden, functies, eigenschappen en constanten. In tegenstelling tot interfaces, die methodenimplementaties afdwingen, annoteren attributen code zonder de structuur ervan te wijzigen.
Attributen kunnen optionele interface-methoden aanvullen of vervangen door metadata te bieden in plaats van afgedwongen structuur. Overweeg een interface die een operatie in een applicatie vertegenwoordigt. Sommige implementaties hebben mogelijk een opstartstap nodig, terwijl andere dat niet doen. In plaats van alle klassen die de interface implementeren te dwingen een opstartmethode te definiëren, kan een attribuut de opstartvereisten aangeven. Deze benadering vergroot de flexibiliteit, waardoor attributen indien nodig meerdere keren kunnen worden toegepast.
Voorbeeld: Optionele methoden van een interface implementeren met Attributen
<?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("File does not exist");
}
}
#[SetUp]
public function targetDirectoryExists()
{
if (!file_exists($this->targetDirectory)) {
mkdir($this->targetDirectory);
} elseif (!is_dir($this->targetDirectory)) {
throw new RuntimeException("Target directory $this->targetDirectory is not a directory");
}
}
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);