Ich gegen das Web

Der Blog von jemanden der gegen das Web kämpft.

Über diesen Blog

Sebastian schreibt hier manchmal über seinen Kampf gegen das Internet. Wer da wohl gewinnt?

Zahl des Tages

39

Navigation

PHPStorm und PSR-11 Container

Autovervollständigung in PHPStorm für PSR-11 Container aktivieren

phpstorm-und-psr-11-container

Das Ziel von PSR-11 besteht darin zu standardisieren, wie Frameworks und Bibliotheken einen Container verwenden um (gemeinsame) Objekte und Parameter abzurufen. Egal ob nun PHP-DI oder eine andere PSR-11-Kompatible Bibliothek genutzt wird: Es macht Spaß und hilft besseren Code zu schreiben.

Wer wie ich PHP Storm nutzt, wird sicherlich irgendwann mal den Wunsch gehabt haben, auch bei Containern die Autovervollständigung zu nutzen. Das ist relativ einfach über die Attribution im Quellcode mithilfe von PHPDoc zu realisieren. Dazu wird bei der Deklination der Variable einfach das @var Attribute auf die Klasse gesetzt:

<?php // File1.php
/** @var Psr\Log\LoggerInterface LoggerInterface **/ $loggerInterface = $container->get(\Logger::class);

Nun hatte ich jedoch den Fall, dass ich in einem anderen Datei-Scope (also innerhalb von PHP Storm in einem zweiten Dokument, welches nicht direkt, sondern nur über Composer in den PHP-Code-Scope eingebunden wird) zu arbeiten hatte. Ich hatte also die Dateien File1.php und File2.php. Und die IDE konnte nicht erkennen, dass File2.php auf das Objekt aus File1.php zurückgriff.

Innerhalb von File2.php funktionierte der Container natürlich (und ich erhalte den entsprechenden Service bzw. die Funktionen/Methoden), jedoch war die Autovervollständigung auf die identische Attribution angewiesen (im Datei-Scope von File2.php). Grundsätzlich ist dies kein wirkliches Problem (auch wenn dadurch der Garbage Collector ein wenig mehr Futter erhielt). Jedoch hätte eine Implementierung eines anderen Interfaces ein komplettes Reflecten des PHP-Codes notwendig gemacht. Hand aufs Herz: Auch das ist schnell in PHP Storm gemacht.

PHP Storm bietet aber noch eine weitere Möglichkeit die Autovervollständigung für PSR-11 kompatible Container zu realisieren: durch PhpStorm advanced metadata. Dabei wird eine Datei mit dem Namen .phpstorm.meta.php im Root-Verzeichnis des Projektes angelegt.

In dieser werden dann die verschiedenen Provider/Services definiert, die dann im Script genutzt werden. Jedoch gibt es da noch ein Problem: Aktuell werden nur Konstanten und Strings unterstützt. Für die Klassen die über ::class definiert werden, funktioniert es nicht. Zumindest nicht ganz sauber. Ich war nicht der einzige mit der Absicht bzw. dem Problem und so wurde hier schon der Feature-Wunsch artikuliert.

Damit das ganze nun doch funktioniert, wird in der PHPSTORM_META nicht die Klasse mit ::class eingebunden, sondern als String FQDN hinterlegt. Für mein Logger-Beispiel bedeutet dies:

<?php
namespace PHPSTORM_META {

    override(\Psr\Container\ContainerInterface::get(),
        map([
            '\Logger' => \Psr\Log\LoggerInterface::class
        ])
    );
}

Am Ende des Tages funktioniert es genau so wie es soll. Auch wenn es eigentlich zwei verschiedene Dinge sind, die hier zum Funktionieren vermischt werden. Aber es funktioniert. Der Vorteil besteht nun darin, dass an einer zentralen Stelle die notwendige Konfiguration vorgenommen werden und im eigentlich Code auf die Methoden und Attribute der Container zurückgegriffen werden kann.

Januar 10, 2021

Es wurden noch keine Kommentare verfasst, sei der erste!