Die Leute beschweren sich oft, dass WordPress langsam ist. Ob dies zutrifft oder nicht, hängt von vielen Faktoren ab. Wenn jedoch Serverressourcen im WordPress-Dashboard angezeigt werden, kann dies einen Einblick in die Funktionsweise unserer WordPress-Installation geben.
In diesem Lernprogramm erstellen wir ein Plugin, um den Serverstatus anzuzeigen, einschließlich Speicherplatz, Speicherverbrauch, CPU-Nutzung und Prozessnutzung.
Wir werden auch etwas über den WordPress-Cache lernen, um zu vermeiden, dass diese Metrik immer wieder abgefragt wird, und wir werden auch WordPress-Cron-Jobs behandeln, um diese Daten automatisch zu erzeugen.
Das Administrator-Dashboard zeigt uns standardmäßig einige Blöcke an, die als Widgets bezeichnet werden. Diese schließen ein:
Die Widgets können nach Belieben neu geordnet und angezeigt oder ausgeblendet werden. Das Dashboard ist im Allgemeinen anpassbar.
Da Widgets sehr flexibel sind und direkt auf dem ersten Bildschirm des Administratorbildschirms verfügbar sind, können Sie sie verwenden, um Serverressourcen anzuzeigen: Festplattenstatus, Arbeitsspeicherauslastung, CPU-Auslastung und Informationen zum Betriebssystem. Wir nennen diese Ressourcen kurz "Metriken".
Während dieser ganzen Zeit werden wir die API für Dashboard-Widgets sowie die Rollen und Funktionen lernen, um diese Widgets für einige Benutzer verfügbar zu machen, da die Daten möglicherweise vertraulich sind.
Dazu werden wir auch einige grundlegende Linux-Befehle lernen, um Serverinformationen und Seed in unser Widget-Dashboard zu ziehen. Wir werden die Transienten-API verwenden, um diese Daten zwischenzuspeichern. Cronjobs werden genutzt, um diese Daten automatisch abzurufen, anstatt sie bei jeder Anforderung auf Anforderung abzurufen.
Die Arbeit unseres Plugins ist von Linux Dash inspiriert.
Unser Plugin unterstützt neun Arten von Metriken. Als Ergebnis werden wir neun Dashboard-Widgets haben.
Lassen Sie uns ein einfaches Plugin erstellen und es aufrufen Server-Dashboard. Wir werden mit einigen grundlegenden Dingen beginnen. Ein traditionelles Hallo Welt hilft Ihnen, ein Widget für das Dashboard hinzuzufügen.
Es ist eigentlich ganz einfach.
Erstellen eines Ordneranrufs Server-Dashboard Innerhalb WP-Inhalt / Plugins
, und eine Datei serverdashboard.php
. Das Ordnerlayout sieht so aus. Konzentrieren Sie sich einfach auf die Hauptdatei und ignorieren Sie die Bin, Tests, Widgets und so weiter.
Verwenden Sie diesen Code für serverdashboard.php
Lauf(); ?>Ich habe Namensraum verwendet
AX \ StatBoard
um Namenskollisionen mit verschiedenen Plugins-Klassen, Funktionsnamen von Designs und anderen Plugins zu vermeiden. Lauf
Hook oder Filter mit WordPress registrieren.wp_dashboard_setup
. Über diese Hooks erhalten Sie Zugriff auf die zugehörige Anpassungsoption von Dashboard. Es ermöglicht uns, das Dashboard-Widget zu WordPress hinzuzufügen oder daraus zu entfernen. wp_add_dashboard_widget
ein Widget registrieren. Es erfordert Argumente in dieser Reihenfolge:In den meisten Fällen werden Callbacks als eine einzelne Funktion, eine anonyme Funktion, ein Array von Objekten und Methoden oder als Array von Klassen- und statischen Methoden auftreten.Aktualisieren Sie Ihr Dashboard. Unser Plugin zeigt sein Widget. Beachten Sie die
Ich würde
des Widget div Elements.Lasst uns das vorantreiben. Wir zeigen ein Kreisdiagramm mit einigen Dummy-Daten. Um es einfach zu halten, verwende ich die Google Chart API. Wir werden es später ausführlich für Servermetriken verwenden, da es besser ist, diese Art von Daten zu visualisieren.
Wenn Sie Google Chart nicht mögen, können Sie es loswerden und Ihre bevorzugte Chartbibliothek einsetzen. Denken Sie daran, dass dies ein Tutorial ist, also schränken Sie sich nicht ein - verwenden Sie, was immer Sie möchten!
Wir müssen das Google Chart-Skript laden. Ändere dein Lauf()
Methode zum Registrieren eines weiteren Hooks.
öffentliche Funktion run () add_action ('wp_dashboard_setup', array ($ this, 'add_dashboard_widgets')); add_action ('admin_enqueue_scripts', array ($ this, 'add_asset'));
admin_enqueue_scripts
ist die Aktion, die Sie benötigen, um ein eigenes Skript im Administrator-Dashboard hinzuzufügen. Wir werden einen weiteren Methodenaufruf hinzufügen add_asset
in unserer Klasse für das Laden von Skripten. Die Implementierung von add_asset
.
/ ** * Javascript hinzufügen * / function add_asset () wp_enqueue_script ("google-chart", "https://www.google.com/jsapi");Wir haben die Chartbibliothek. Jetzt müssen wir es in unserem Dashboard rendern. Sie können mit Google Chart herumspielen. Wir werden ihr Beispiel jetzt wieder verwenden.
function add_dashboard_widgets () syslog (LOG_DEBUG, "Ausführen"); wp_add_dashboard_widget ('hello_world_dashboard_widget', // ein Slug zur Identifizierung dieses Widget 'Hello World'), // Widget title function () echo <<<'EOD' Hey, I'm the body of widget. Thanks for bring me to the life.Wir fügen einfach ein weiteres div-Element mit der ID hinzu hallo_piechart und rendern Sie das Diagramm in dieses Element. Mal sehen, was wir jetzt haben:Beachten Sie die ID des Widgetelements.EOD; // Funktion, um den Inhalt des Widgets zu rendern, ich verwende hier eine Schließung);
Nun, da wir wissen, wie wir einen eigenen Widgetblock zum Dashboard hinzufügen können, und jetzt, wo Google Chart zum Rendern von Informationen verwendet wird, können wir die beiden kombinieren, um weitere Informationen anzuzeigen.
Im nächsten Abschnitt erfahren Sie, wie Sie Servermetriken abrufen und Inhalte für jeden zuvor beschriebenen Typ von Servermetriken darstellen.
Beim Abrufen von Servermetriken verwenden wir den Befehl von Linux, um diese Informationen zu erhalten. In PHP können Sie backtick "oder shell_exec" verwenden, um einen Shell-Befehl aufzurufen und die Ausgabe abzurufen.
Wir können die Ausgabe analysieren, um Serverdaten zu erhalten. Um beispielsweise den Festplattenbenutzungsstatus abzurufen, können Sie den Befehl verwenden df -h
. Wir kennen das Format der Ausgabe, sodass wir es analysieren können, um das zu bekommen, was wir wollen.
$ df = 'df -h'; $ df = explodieren ("\ n", $ df); if (is_array ($ df) && count ($ df)> = 2) array_shift ($ df); // Beseitigen Sie die erste Zeile. $ Df = array_map (Funktion ($ line) wenn (leer ($ line))) return NULL; $ segment = preg_split ('/ \ s + /', $ line); return array ( 'Dateisystem' => $ segment [0], 'size' => $ segment [1], 'used' => $ segment [2], 'available' => $ segment [3], 'use_percent' => $ segment [4],; $ df); var_dump ($ df);
[command_we_run] | awk 'print $ 1, $ 3,…'
. ☁ Server Dashboard [master] ls -lh gesamt 32 -rw-r - r-- 1 kureikain staff 2.6K Apr 11 00:46 Server Dashboard.php drwxr-xr-x 3 kureikain staff 102B Mar 29 01:27 bin - rw-r - r-- 1 kureikain staff 98B 5. April 18:53 loader.js -rw-r - r-- 1 kureikain staff 321B 29. März 01:27 phpunit.xml drwxr-xr-x 4 kureikain staff 136B Mar 29 01:27 tests drwxr-xr-x 12 kureikain staff 408B Apr 13 17:37 widget -rw-r - r-- 1 kureikain staff 1.1K Apr 6 01:04 widget.php Server Dashboard [master] ls -lh | awk 'print $ 3, $ 4, $ 5, $ 9' kureikain staff 2.6K Server kureikain staff 102B bin kureikain staff 98B loader.js kureikain staff 321B phpunit.xml kureikain staff 136B testet kureikain staff 408B widget kureikain staff 1.1K widget.phpDa kann man jede Zeile von sehen
ls -la
enthält neun Felder:drwxr-xr-x 4 kureikain staff 136B 29. märz 01:27 testsDiese 9 Felder werden durch Leerzeichen getrennt:
awk 'print $ 3, $ 4, $ 5, $ 9'
und ich werde sehen:kureikain staff 136B testet
Daher können wir mit awk die Ausgabe etwas bereinigen, bevor sie in unsere PHP-Verarbeitungsfunktion einfließen.
Einige Befehle geben zusätzliche Daten aus, die wir nicht benötigen. Daher erfordert PHP ein wenig mehr Aufwand, um es aufzuräumen.
Zum Beispiel:
[vagrant @ vagrant-centos64 ~] $ free -m insgesamt verwendete freie gemeinsam genutzte Puffer zwischengespeichert Mem: 589 537 51 0 8 271 - / + Puffer / Cache: 258 330 Swap: 255 0 255
frei -m
zeigt uns die RAM-Nutzung mit Arbeitsspeicher und Auslagerungsdatei; Es enthält jedoch zwei weitere Zeilen mit total / used / free und - / + puffern / cache, die wir möglicherweise nicht benötigen. -E
Schalter. Dieser Schalter ermöglicht die Verwendung von regulärem Express für die Suche. Da wir die Zeile mit den Wörtern Mem und Swap finden möchten, lassen Sie sie mit kombinieren grep -E "Mem | Swap"
. [vagrant @ vagrant-centos64 ~] $ free -m | grep -E "Mem | Swap" Mem: 589 536 52 0 8 271 Swap: 255 0 255Es ist also viel sauberer. Kombiniere beide
grep
und awk
Wir können Daten bereinigen und bekommen nur das, was wir brauchen.[vagrant @ vagrant-centos64 ~] $ free -m | grep -E "Mem | Swap" | awk 'print $ 1, $ 2, $ 3, $ 4' Mem: 589 537 52 Tausch: 255 0 255
Wir müssen einige Befehle zum Abrufen von Servermetriken kennen lernen. Öffnen wir also die Server-Shell und versuchen Sie, den folgenden Befehl einzugeben, um einen schnellen Eindruck zu erhalten.
$ netstat -in Tabelle der Kernel-Schnittstelle Iface MTU Met RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg eth0 1500 0 5538339494 0 0 0 6216082004 0 0 0 BMRU eth0: 1 1500 0 - Keine Statistiken verfügbar - BMRU eth1 1500 0 96707328840 0 0 0 102776317608 0 0 0 BMRU eth2 1500 0 33 0 0 7 0 0 0 BMRU lo 16436 0 29461422 0 0 0 29461422 0 0 LRU
df -h Dateisystemgröße Verwendet Verwendet% Mounten auf / dev / sda7 2.0G 660M 1.3G 35% / / dev / sda8 1.0T 632G 340G 66% / home / dev / sda6 2.0G 68M 1.9G 4% / tmp / dev / sda5 20G 1,5G 18G 8% / var / dev / sda2 20G 2,1G 17G 12% / usr / dev / sda1 194M 25M 160M 14% / boot / dev / hdb1 459G 277G 159G 64% / backup tmpfs 16G 0 16G 0% / dev / shm
free -m insgesamt verwendete freie gemeinsam benutzte Puffer zwischengespeichert Mem: 32189 32129 59 0 419 9052 - / + Puffer / Cache: 22656 9532 Swap: 32767 4 3276Wir werden später noch mehr Befehle verwenden, aber oben geben Sie einige grundlegende Befehle, um zu sehen, was wir vom Server direkt in der Befehlszeile erhalten können.
Wir werden unsere ursprüngliche Klasse ein wenig überarbeiten. Beachten Sie, dass wir alle Dateien und Ordner erstellen, sofern nicht anders angegeben innerhalb unser Plugin-Verzeichnis.
Erstens möchten wir Dateien nicht manuell einschließen. Wir werden zu diesem Zweck einen automatischen Klassenlader schreiben. Wenn eine fehlende Klasse initialisiert wird, überprüfen wir den Klassennamen und versuchen, die Quellendatei aufzunehmen, die die Klassendefinition enthält.
Wir verwenden Namespaces als Pfad und Klassennamen als Dateinamen. Zum Beispiel eine Klasse foo
im Namensraum AX \ StatBoard
sollte sich im Stammverzeichnis des Plugin-Ordners befinden. Eine Klasse summen
im Namensraum AX \ StatBoard \ Bar
sollte in sein Bar \ buzz.php
In diesem Sinne beginnen wir mit der Erstellung unserer Auto Loader-Methode:
_plugin_dir. strtolower (str_replace ('\\', '/', $ classname). '.php'); if (! file_exists ($ filepath)) return false; Include $ filepath;Was passiert also hier? Unser Plugin verwendet einen Namensraum
/ **
* Setup-Variable und initialisieren Widget-Provider
* /
Funktion __construct ()
$ this -> _ plugin_dir = plugin_dir_path (__FILE__);
spl_autoload_register (array ($ this, 'load_class')));
//…
AX \ StatBoard
. Wir stellen also sicher, dass die angeforderte Klasse unter diesem Namespace von unserem Plugin behandelt wird, da unser Auto Loader diese nicht laden kann. Dann ziehen wir die aus AX \ StatBoard im Klassennamen und ersetzen Sie es durch den Pfad des Plugin-Ordners. Der Backslash \ im Namespace wird durch ersetzt / Pfadtrennzeichen und Anhängen php
Erweiterung. Das bedeutet, dass der Namespace verwendet wird, da der Pfad zum Ordner die Klassendatei enthält und der Klassenname der Dateiname ist. Das Einfügen erfolgt nur, wenn die Datei vorhanden ist. Nun, wir haben den Auto Loader, wir müssen PHP noch wissen lassen, dass wir einen Auto Loader haben, und wir wollen ihn verwenden. PHP enthält zu diesem Zweck spl_autoload_register. Wir haben es in unseren Klassenbauer gestellt.wp_add_dashboard_widget
, Wir müssen ihm den Titel und den Inhalt geben. Entsprechend jedem Widget haben wir eine Klasse, um Titel und Inhalt für das Widget zu rendern. Wir nennen diese Klasse Widget Anbieter
. Alle Widgetanbieter müssen definieren get_title ()
und get_content ()
um Inhalte zu rendern.Anbieter
Schnittstelle, und unsere Widget-Provider-Klasse muss diese Schnittstelle implementieren. Wir müssen auch einen weiteren Methodenaufruf erstellen get_metric ()
um Serverdaten abzurufen.widget / provider.php
mit diesem Inhalt:Dies ist eine Schnittstelle. Jeder Widget-Provider muss diese Schnittstelle implementieren. Daher stellen wir sicher, dass die Widget-Provider-Klasse immer über diese drei Methoden verfügt.
Wir werden eine weitere Klasse erstellenWidget
um diese Anbieter zu verwalten. Wir erstellen Providerklassen und verteilen sie anWidget
Klasse und AnsichtWidget
Klasse als zentrale Anlaufstelle, um bei Bedarf nach einem Anbieter zu fragen. Wir können einfach alles in unsere Haupt-Plugin-Datei einfügen und einfach eine Klasseninstanz mit erstellenNeu
Operator, wenn wir brauchen, aber es ist später schwer zu warten.
Wenn wir das Ding in viele Ebenen unterteilen, ist es einfacher zu testen und zu erweitern. Sobald alle Anbieter von einer einzigen Klasse verwaltet werden, können wir diese Klasse dazu verwenden, über die Menge der Anbieter dasselbe zu tun. Wir können jederzeit problemlos weitere Provider hinzufügen, indem Sie einfach ein Objekt erstellen, das die Providerklasse implementiert und diese füttertWidget
Klasse
Verfassen Sie eine Dateiwidget.php
im Stammverzeichnis des Plugin-Ordners.Auch hier verwenden wir das Singleton-Muster für unsere Widget-Klasse. Eine kurze Zusammenfassung unserer Methode hier.
Namensraum AX \ StatBoard;
Verwenden Sie AX \ StatBoard \ Widget \ Provider;
Klassen-Widget
const WIDGET_SLUG_PREFIX = 'AX';
protected $ _providers = array ();
geschütztes statisches $ _instance;
statische Funktion Instanz ()
return self :: $ _ instance = self :: $ _ instance?: new self ();
Funktion __construct ()
/ **
* Fügen Sie einen Widget-Provider hinzu
* @param String Widget Name
* @param-Provider-Objekt zur Verarbeitung von Rendering von Widget-Inhalten
* /
öffentliche Funktion add_provider ($ name, Provider $ handler)
$ this -> _ provider [$ name] = $ handler;
$ dieses zurückgeben;
/ **
* Holen Sie sich alle Anbieter oder einen bestimmten Anbieter
* /
öffentliche Funktion get_provider ($ name = NULL)
if (! $ name)
$ this -> _ provider zurückgeben;
$ this zurückgeben -> _ provider [$ name];
/ **
* Registrieren Sie ein Widget, um es zu rendern.
* /
öffentliches Funktionsregister ($ name)
$ slugid = self :: WIDGET_SLUG_PREFIX. $ name;
$ widget_provider = $ this-> get_provider ($ name);
if (leer ($ widget_provider))
falsch zurückgeben;
wp_add_dashboard_widget (
$ slugid,
$ widget_provider-> get_title (),
array ($ widget_provider, 'get_content'));
wahr zurückgeben;
- Das
add_provider
Die Methode fügt ein Widget-Provider-Objekt zur Widget-Provider-Liste hinzu. Wir verwenden auch Typhinweise, um sicherzustellen, dass das Objekt an add_provider übergeben werden muss Anbieter durch die Implementierung unsererAnbieter
Schnittstelle.- Das
get_provider
Diese Methode kann eine Liste aller Anbieter oder eines bestimmten Anbieters zurückgeben.- Das
registrieren
Diese Methode registriert unser Provider-Objekt tatsächlich bei WordPress, um ein Dashboard-Widget mit darzustellenwp_add_dashboard_widget
. Die ID des Widgets wird basierend auf dem Präfix, einer vordefinierten Konstante und dem Klassennamen des Widgets generiert. Der Titel und der Inhalt werden über gezogenget_title
und get_content
des Anbieters. Wir haben sichergestellt, dass sie unsere Provider-Schnittstelle implementieren. Mit dieser Registermethode abstrahieren wir die Implementierung des Hinzufügens des Widget zum Dashboard. Jetzt müssen wir nur noch anrufenregistrieren
mit dem Namen des Anbieters, den wir zuvor hinzufügenadd_provider
. Wenn sich die WordPress-API ändert, müssen wir nicht an jeden Ort von gehenwp_add_dashboard_widget
, Wir aktualisieren nur an einem Ort.
Rückkehr zur ursprünglichen Haupt-Plugin-Dateiserverdashboard.php
, Wir initialisieren alle Anbieter und fügen sie der Anbieterliste des Widget-Objekts hinzu._plugin_dir = plugin_dir_path (__FILE__); spl_autoload_register (array ($ this, 'load_class'))); $ this -> _ dashboard_widget = array ('server', 'cpu_load', 'ram', 'disk', 'diskio', 'software', 'ethernet', 'internetspeed', 'networkio', 'process',); foreach ($ this -> _ dashboard_widget als $ item) if (! file_exists ($ this -> _ plugin_dir. '/ widget /'. $ item. '.php')) continue; $ classname = 'AX \\ StatBoard \\ Widget \\'. ucwords ($ item); Widget :: instance () -> add_provider ($ item, neuer $ classname ());Wir werden alle Widget-Provider-Klassen unter Namespace setzenAX \ StatBoard \ Widget
und deshalb werden sie in Ordner sitzenWidget
. Wir unterstützen neun Arten von Metriken und benennen die Klasse, die dem Array entspricht_dashboard_widgets
über.
Für jedes Widget erstellen wir eine neue Instanz seines Providers und fügen es hinzuWidget
Klasse. Folgendes bekommen wir später mit dieser Struktur:
Erinnere dich daran, dass wir uns angeschlossen habenwp_dashboard_setup
, und darin rufen wir die Funktion aufwp_add_dashboard_widget
Neues Widget zum Dashboard hinzufügen. Als nächstes haben wir unsereregistrieren
Methode für diesen Zweck. Wir werden alle hinzugefügten Anbieter in einer Schleife durchlaufen und sie registrieren. Aktualisieren Sie den Inhalt vonadd_dashboard_widgets
vonserverdashboard.php
werden:
/ ** * Registrieren Sie den Dashboard-Widget-Proider, um ihn im Dashboard anzuzeigen * / function add_dashboard_widgets () $ widget = Widget :: instance (); foreach ($ widget-> get_provider () als $ name => $ provider) $ widget-> register ($ name);
Als Nächstes werden wir uns in admin_footer einhängen, um inline JavaScript am Ende der Administrationsseite zum Initialisieren des Google Chart-Klassenpakets auszugeben. UnsereLauf()
Methode wird auch für neue Hooks aktualisiert./ ** * Start zum Einrichten des Hooks * / public function run () add_action ('wp_dashboard_setup', array ($ this, 'add_dashboard_widgets')); add_action ('admin_enqueue_scripts', array ($ this, 'add_asset')); add_action ('admin_footer', array ($ this, 'footer'))); / ** * Inline-JavaScript für Diagramm * / Funktionsfußzeile () Echo ' ';
In diesem Moment haben wir die Basis abgeschlossen, und die Haupt-Plugin-Datei sollte so aussehen._plugin_dir. strtolower (str_replace ('\\', '/', $ classname). '.php'); if (! file_exists ($ filepath)) return false; Include $ filepath; / ** * Setup-Variable und initialisieren Widget-Provider * / function __construct () $ this -> _ plugin_dir = plugin_dir_path (__FILE__); spl_autoload_register (array ($ this, 'load_class'))); $ this -> _ dashboard_widget = array ('server', 'cpuload', 'ram', 'disk', 'software', 'process', 'ethernet', 'networkio', 'iostat')); foreach ($ this -> _ dashboard_widget als $ item) if (! file_exists ($ this -> _ plugin_dir. '/ widget /'. $ item. '.php')) continue; $ classname = 'AX \\ StatBoard \\ Widget \\'. ucwords ($ item); Widget :: instance () -> add_provider ($ item, neuer $ classname ()); / ** * Eine eindeutige Instanz mithilfe der App erstellen * / public static function instance () return self :: $ _ instance = self :: $ _ instance?: New self (); / ** * Start zum Einrichten des Hooks * / public function run () add_action ('wp_dashboard_setup', array ($ this, 'add_dashboard_widgets')); add_action ('admin_enqueue_scripts', array ($ this, 'add_asset')); add_action ('admin_footer', array ($ this, 'footer'))); / ** * Registrieren Sie den Dashboard-Widget-Proider, um ihn im Dashboard anzuzeigen * / function add_dashboard_widgets () $ widget = Widget :: instance (); foreach ($ widget-> get_provider () als $ name => $ provider) $ widget-> register ($ name); / ** * Assets laden: Stylesheet, JS. * / function add_asset () syslog (LOG_DEBUG, "Geladen"); wp_enqueue_script ("google-chart", "https://www.google.com/jsapi"); // wp_enqueue_script ('plugin_dir_url', plugin_dir_url (__ FILE__). '/loader.js'); / ** * Inline-JavaScript für Diagramm * / Funktionsfußzeile () Echo ' '; Dashboard :: instance () -> run ();Grundsätzlich erstellen wir eine Instanz der Hauptplugin-Klasse und rufen die run-Methode auf. Welches wiederum gerade eine Liste der Haken aufstellt. Jeder Hook ist eine andere Methode innerhalb der Klasse. Wir erstellen und registrieren auch unser Provider-Objekt mitWidget
Objekt.Was kommt als nächstes?
An diesem Punkt zeigen wir immer noch nichts an; Wir legten jedoch eine Struktur für unser Plugin fest, das mit Google Charts verbunden wurde.
Sie können das vollständige Skript von den Download-Links oben in diesem Artikel herunterladen. Wir werden im nächsten Artikel auf die Implementierungsdetails jedes Widgetanbieters eingehen. Vergewissern Sie sich, dass Sie den nächsten Teil beachten.
Ich hoffe, Ihnen hat dieser Artikel gefallen. Hinterlassen Sie Kommentare zu Ihren Gedanken und ich werde sie sicher beantworten.