PHP mit Onlineaktualisierung
der henry
- php
Hallo,
ich arbeite mich gerade in PHP ein und hätte Fragen zu Aktualisierung von Messdaten auf einer Webseite.
Früher habe ich dies mit Perl (cgi) und JS / Ajax erledigt.
Durch den Austausch von Perl mit PHP ist nun die Frage wie ich dies am "günstigsten" in Zukunft löse.
Wieder über ajax/fetch oder ???
Ich könnte auch die html Seite parsen und alle "Messwerte" vor der Ausgabe befüllen und ausgeben.
Wie könnte ich dies lösen ... ?
Fragen zu Aktualisierung von Messdaten von Messdaten auf einer Webseite
Wieder über ajax/fetch oder ???
Kommt darauf an. Damit ist
a) eine Aktualisierung der Daten möglich, ohne dass die gesamte Webseite neu gebaut und geladen werden muss.
b) Die Nutzung der Daten ist auch in ganz anderen Anwendungen und Zusammenhängen möglich, wenn das für den Transport genutzte Datenformat einer Norm (JSON, CSV,..., und „Ach! Auch“ XML) entspricht.
Wenn Du das alles nicht brauchst kannst Du eine statische HTML-Seite auch entweder beim Abruf der Seite oder z.b. per Cronjob erzeugen. Es kommt auch hier drauf an, was Du willst oder brauchst.
Ich könnte auch die html Seite parsen und alle "Messwerte" vor der Ausgabe befüllen und ausgeben.
Du bekommst die Messdaten als HTML-Seite? Klingt unbequem.
→ Beschreib mal Dein Anliegen und die Voraussetzungen umfassender.
Austausch von Perl mit PHP
Holla! So hab ich anno 2005 auch angefangen. Das war damals eine Wohnungssuchmaschine, die ich - weil ich es lernen wollte - zunächst 1:1 von Perl auf PHP umgeschrieben habe.
Hallo,
vielleicht eine Idee: Wenn die verschiedenen Messwerte mit PHP als XML erzeugt werden, dann könnte die XML ja so aussehen:
<messwerte>
<messwert1>13</messwert1>
<messwert2>Apfel</messwert2>
<messwert3>dunkel</messwert3>
<messwert4>fertig</messwert4>
</messwerte>
So werden jeweils nur die aktuellen (sich ändernden) Messwerte überliefert. Die dazugehörige XSL-Datei erzeugt dann das HTML mit den sich ändernden Messwerten. Da werden nur jeweils wenige Bytes gesendet, da sich das xsl und css nicht ändern, wenn sich nur Messwerte ändern 😀
Viel Erfolg,
Hans
Hallo Henry,
Wieder über ajax/fetch oder ???
Wenn die Daten live in der Website stehen und bspw. alle 5 Sekunden aktualisiert werden sollen, dann ja.
Ich könnte auch die html Seite parsen und alle "Messwerte" vor der Ausgabe befüllen und ausgeben.
DAS kapiere ich nun gar nicht. Welche HTML Seite willst Du wo parsen?
Eine billige, aber schlechte Lösung ist, in den <head> der Seite einen refresh einzusetzen (siehe Wiki):
<meta http-equiv="refresh" content="5">
Die Seite lädt sich dann alle 5s neu, und wenn das eine PHP Seite ist, kann sie die Messwerte neu befüllen. Aber das flackert rum, stört beim Scrollen und ist ein Gruß aus dem letzten Jahrtausend.
Eine einfache Lösung ist: Im JavaScript über setInterval einen 5s Timer setzen und darüber den Ajax-Ablauf anstoßen.
PHP-seitig ein spezielles Script verwenden, das nicht text/html als Ausgabetyp erzeugt, sondern bspw. application/xml oder application/json.
JSON ist insofern einfacher, weil man dafür ein assoziatives Array in PHP aufbauen kann und mit json_encode einfach umwandeln kann
$data = [ "foo" => 3, "bar" => 17, "werte" => [ 4,7,9] ];
header("ETag: \"" . (new DateTimeImmutable())->format('c') . "\"");
header('Content-Type: application/json; charset=UTF-8');
echo json_encode($data);
ergibt
{"foo":3,"bar":17,"werte":[4,7,9]}
Das ständig neue ETag verhindert das Caching des Abfrageergebnisses. Einen aus Client-Sicht identischen Service kannst Du übrigens auch mit ASP.NET und C# programmieren.
Im JavaScript dann einfach in einer async-Funktion dies:
setInterval(refreshData, 5000);
async function refreshData() {
const response = await fetch("api.php");
if (response.ok) {
const data = await response.json();
// Ergebnis in data.foo, data.bar und data.werte
}
}
Das ist natürlich nur eine Skizze.
Wenn Du einen Server hast, auf dem Du node.js hosten kannst, dann KÖNNTEST Du auch eine Websocket-Verbindung machen und Datenupdates vom node.js aus pushen, statt sie per JavaScript zu holen. Aber das ist deutlich aufwändiger, insbesondere die Dauerbetriebsfestigkeit.
Rolf
Hallo Raketenwilli, hallo Hans, hallo Rolf,
vielen Dank für eure Antworten,
... hatte wohl wieder mit Info gegeizt
Hier nochmals, mit mehr Infos:
Auf dem Server in einer Datenbank stehen die Messwerte. Diese sollen auf der Webseite (Intervall <= 5s) angezeigt/visualisiert werden.
Bei der "Perlversion" hatte/habe ich ein JS-Script das mir alle "Variablennamen" der Messwerte (bestimmtes Format der jeweiligen "ID" z.B. MK3.Temperatur oä.) auf der Webseite sammelt und diese Liste per Ajax an den Server sendet. Am Server ein cgi-Script starten und die Daten aufbereitet (Name:Messwert,x:y) und an die Webseite zurückgesendet. Auf der Webseite wiederum per JS verteilt ... fertig.
Da ich in/bei PHP neu bin, suche ich das Optimum, bevor ich mich dran setzen will ... naja, oder so ähnlich. 😜 Es hat sich ja in den letzten Jahrzehnten schon etwas getan ....
Die Möglichkeit von Rolf sehe ich vorne ... bekanntes/gleiches System, nur mit PHP
Bin weiterhin für Tipps dankbar ...
Die Möglichkeit von Rolf sehe ich vorne ... bekanntes/gleiches System, nur mit PHP
Jepp! Aber eine Änderung schlage ich vor:
Am Server ein cgi-Script starten und die Daten aufbereitet (Name:Messwert,x:y) und an die Webseite zurückgesendet.
→ Ändere das Format der gesendeten Daten von einem „sehr speziellen CSV“ in JSON.
An Deiner Stelle würde ich dann die Funktionen oder Klassen zum Abrufen der Daten (Bis zum Array) und dem Erzeugen des JSON in Libary-Dateien außerhalb des Document-Root unterbringen.
So kannst Du diese Daten (den Array) leicht beim Abruf der Webseite einbauen, aber wenn der Browser den Request mit JS durchführt brauchst Du nur noch ein weiteres, bemerkenswert kleines Mini-Skript, welches die Daten in JSON umbaut und den HTTP-Header schreibt. Mit fetch oder XHRRequest abholen und einbauen ist dann ein Kinderspiel.
<?php
### Meine etwas spezielle Methode, mir bei Debuggen zu helfen:
### wenn etwas mit den Daten nicht zu stimmen scheint
### setze ich DEBUG an geeigneter Stelle auf einen
### anderen Wert als 0 oder „falsy“ und reagiere im Skript…
if ( ! defined 'DEBUG' ) {
define ('DEBUG', false );
}
## Liefert die Funktion getDataFromDBAsArray,
## welche den Array mit den Daten liefert:
require $_SERVER['DOCUMENT_ROOT'] . '../lib/getDataFromDBAsArray.php';
## Headers:
if ( DEBUG ) {
header('Content-Type: text/plain; charset=UTF-8');
} else {
header('Content-Type: application/json');
}
## striktes Verhindern des Cachens:
header('Cache-Control: no-cache');
header("Expires: 0");
header('Pragma: no-cache');
## Daten holen und senden
echo json_encode( getDataFromDBAsArray() );
if ( DEBUG ) {
echo json_encode(
getDataFromDBAsArray(),
JSON_FORCE_OBJECT | JSON_PRETTY_PRINT
);
} else {
echo json_encode(
getDataFromDBAsArray(),
JSON_FORCE_OBJECT
);
}
Hints: (Keine BOM, keine Leerzeichen oder Zeilen vor dem <?php, kein schließendes ?>)
Statt die Daten selbst mit JS zu zerlegen kannst Du dann einfach das (z.B. mit fetch abgeholtes JSON in ein Objekt umbauen lassen und dessen Werte dann auf übersichtliche Weise in Dein DOM einbauen lassen.
Hallo Raketenwilli,
so "grundsätzlich" 🤔 habe ich alles verstanden 😉
json wenn nötig, da Standard .... ist klar.
Hierzu habe ich zwei Fragen.
Das JS in der Webseite liefert mir eine Liste mit "Namen" z.B. "MS56.Temperatur5", "T2.leistung" usw.
Frage 1: Die Anfrage, Namensliste mit JS senden zum cgi-Script würde ich ohne json machen, einfach ein array an das cgi-Script schicken, oder ist es besser immer bei einen Format (json) zu bleiben, in dem Fall wäre mit json mehr trafic von der Webseite ?? json [{"Name":"MS56.Temperatur5"}{"Name":"T2.leistung"} ... ] array ["MS56.Temperatur5","T2.leistung" ... ]
Frage 2: Das cgi-script liest aus der Datenbank und liefert jeweils ein Array z.B.
Array1(
[plcvarname] => MS56.Temperatur5
[actvalue] => 123,45
[digits] => 2
[unit] => °C
...
)
Array2(
[plcvarname] => T2.leistung
[actvalue] => 67,8
[digits] => 1
[unit] => kW
...
)
Arrayx(
....
)
Ich benötige hier nicht alle Datenfelder pro "plcvarname"
Wie sende ich das am besten zur Webseite zurück ?? ... json Daten mit Array pro Datenpunkt
[ {"MS56.Temperatur5":["actvalue"=>'123,45', "unit"=>'°C']} {"T2.Leistung":["actvalue"=>'67.8', "unit"=>'kW']} ]
oder ????
Es wäre günstig wenn ich in JS z.B. mit "T2.Leistung.actvalue oder T2.leistung.unit" darauf zugreifen könnte.
Vielen Dank für eure Unterstützung !!
JSON ist insofern einfacher, weil man dafür ein assoziatives Array in PHP aufbauen kann und mit json_encode einfach umwandeln kann
Ja :-)
Sollten die Datenreihen aber als CSV-Datei vorliegen (oder so von einem „Gerät“ auslesbar sein) empfehle ich, sich mal den Linux/Unix-Befehl column anzusehen. Der macht in „Nullkommanix“ nicht nur wunderschöne Tabellen, sondern auch JSON.