Signatur
Beschreibung
CommonMark\Interfaces\IVisitable ist Teil der CommonMark-Erweiterung für PHP und definiert den Vertrag für Knoten im Abstract Syntax Tree (AST), die von einem IVisitor traversiert werden können. Es handelt sich um das klassische Visitor-Entwurfsmuster: Knoten implementieren dieses Interface, um das Besuchen zu erlauben, ohne die eigene Klasse mit unterschiedlicher Logik aufzublasen.
Durch die Trennung von Struktur (Knoten/IVisitable) und Verhalten (Visitor/IVisitor) lässt sich neue Verarbeitungslogik hinzufügen – z. B. Rendering, Analyse oder Transformation des Markdown-AST –, ohne bestehende Knotenklassen ändern zu müssen.
Typischerweise wird IVisitable von Knotenklassen wie CommonMark\Node oder deren Unterklassen implementiert. Eigene Knotentypen, die in den Visitor-Mechanismus der CommonMark-Erweiterung eingebunden werden sollen, müssen dieses Interface ebenfalls implementieren.
- Implementierung: Knotenklasse implementiert
IVisitableund ruft inaccept()die passende Methode des Visitors auf. - Zusammenspiel: Wird immer zusammen mit
CommonMark\Interfaces\IVisitorverwendet. - Anwendungsfall: AST-Traversierung, Rendering-Pipelines, Linting, Statistiken über Markdown-Inhalte.
Beispiele
Eigenen Knoten als IVisitable implementieren
<?php
use CommonMark\Interfaces\IVisitable;
use CommonMark\Interfaces\IVisitor;
// Eigener Knoten-Typ, der besucht werden kann
class MyCustomNode implements IVisitable
{
public string $content;
public function __construct(string $content)
{
$this->content = $content;
}
// IVisitable erfordert die accept()-Methode
public function accept(IVisitor $visitor): void
{
$visitor->enter($this);
// Ggf. Kinder-Knoten ebenfalls besuchen lassen
$visitor->leave($this);
}
}
// Einfacher Visitor, der den Inhalt ausgibt
class PrintVisitor implements IVisitor
{
public function enter(IVisitable $node): ?int
{
if ($node instanceof MyCustomNode) {
echo 'Betrete Knoten: ' . $node->content . PHP_EOL;
}
return null;
}
public function leave(IVisitable $node): ?int
{
if ($node instanceof MyCustomNode) {
echo 'Verlasse Knoten: ' . $node->content . PHP_EOL;
}
return null;
}
}
$node = new MyCustomNode('Hallo Welt');
$visitor = new PrintVisitor();
$node->accept($visitor);
CommonMark AST mit Visitor traversieren
<?php
use CommonMark\Parser;
use CommonMark\Interfaces\IVisitable;
use CommonMark\Interfaces\IVisitor;
use CommonMark\Node;
// Visitor zählt alle Knoten im AST
class NodeCountVisitor implements IVisitor
{
public int $count = 0;
public function enter(IVisitable $node): ?int
{
$this->count++;
return null;
}
public function leave(IVisitable $node): ?int
{
return null;
}
}
$parser = new Parser();
$document = $parser->parse('# Überschrift\n\nEin **fetter** Absatz.');
$counter = new NodeCountVisitor();
$document->accept($counter);
echo 'Anzahl Knoten im AST: ' . $counter->count . PHP_EOL;
// Wichtig · Fallstricke
Hinweis zur Erweiterung: CommonMark\Interfaces\IVisitable gehört zur PECL-Erweiterung commonmark (pecl.php.net/package/commonmark), die separat installiert werden muss. Sie ist nicht Teil des PHP-Kerns.
Das genaue Interface-Protokoll (Methodenname accept(), Rückgabetypen) kann je nach Version der Erweiterung leicht variieren. Ein Blick in die jeweilige Versionsdokumentation oder den Quellcode der Erweiterung ist empfehlenswert, bevor eigene Knotentypen implementiert werden.
Beim Traversieren tiefer ASTs mit vielen verschachtelten Knoten kann die rekursive accept()-Kette zu einem Stack-Überlauf führen. Bei sehr großen Markdown-Dokumenten sollte die Tiefe des AST im Blick behalten werden.