Ports benutzen (PHP)

Wechseln zu: Navigation, Suche

Einleitung

Da es schon einen netten Artikel über die Benutzung von Standard-Ports unter Linux in C/C++ gibt und ich die serielle Schnittstelle erst kürzlich unter PHP für mich entdeckt habe, war der Schritt einen Artikel, der an den für C/C++ gedachten angelehnt ist, bereits absehbar...

Nun werden sich einige fragen warum jemand überhaupt unter PHP schnittstellen direkt verwenden will...

Hier ist vielleicht interessant für welche Zwecke ich PHP missbraucht habe.

Also es wandern Daten über die Serielle rein und sollen in eine Datenbank geschrieben werden. Weiter sollen diese jetzt in der Datenbank stehenden Werte per HTTP (ist am einfachsten zu implementieren) wieder ausgelesen werden können. Ich habe also einen netten Server gebraucht, der über RS232 Daten holen, über HTTP Daten ausgeben und nebenbei auch alles in einer Datenbank speichern kann...

PHP war zwar nicht mein 1. Gedanke aber als ich bei NanoWeb über eine PHP-Daemon-Class gestolpert bin war alles klar ;)

PHP5 unterstützt Objekt-Orientierte Entwicklung und bietet eine gute Unterstützung für Datenbanken aller Art... (ich habe mich der Einfachheit halber auf SQLite beschränkt)

Daher ist PHP meiner Meinung nach ausgezeichnet geeignet um schnell solche Probleme zu bewältigen.

Dieser Artikel ist derzeit im Prinzip nur eine Umgestaltung der zugehörigen Manual Pages... nach Durchsicht meines bestehenden Codes am Wochenende (hoffentlich das letzte im Juni und nicht ein späteres ;) werde ich hier den kompletten Daemon unter GPL oä. zur Verfügung stellen...

Voraussetzungen

Man sollte sich in PHP auskennen und nötigenfalls in der Lage sein PHP neu zu kompilieren (siehe PHP-Manual XXII. Direkte Ein-/Ausgabe Funktionen => Um die DIO Funktionen benutzen zu können, muss PHP mit der Option --enable-dio konfiguriert werden.)


Allgemein

Unter PHP greift man auf Schnittstellen über die 'Direct-IO'-Funktionen zu, die da wären:

void dio_close( resource fd ) Schliesst die Datei
mixed dio_fcntl ( resource fd, int cmd [, mixed arg] ) Ändert den Dateideskriptor
resource dio_open ( string filename, int flags [, int mode] ) Öffnet eine Datei mit den angegebenen Rechten
string dio_read ( resource fd [, int n] ) Liest n Bytes und gibt sie zurück, ist n nicht angegeben wird ein 1K Block gelesen
int dio_seek ( resource fd, int pos, int whence ) Setzt den Dateizeiger
array dio_stat ( resource fd ) Liefert Statusinformationen über eine Datei
void dio_tcsetattr ( resource fd, array options ) Setzt Terminalattribute und die Baudrate für einen seriellen Port
bool dio_truncate truncate ( resource fd, int offset ) Schneidet eine Datei ab
int dio_write ( resource fd, string data [, int len] ) Schreibt Daten in eine Datei


Weitere Erfordernisse (wie zum Beispiel die Rechtevergabe damit der PHP-User auf die Schnittstellen zugreifen kann finden sich im Artikel Ports benutzen (GCC) !


Beispiel

Folgendes Beispiel ist im PHP-Manual zu finden... es Bedarf meiner Meinung nach keiner Erklärung (die oben aufgeführten Funktionen und deren Beschreibung im PHP Manual sollten alles Offene kurz und gut erläutern).

<?php

$fd = dio_open('/dev/ttyS0', O_RDWR | O_NOCTTY | O_NONBLOCK);

dio_fcntl($fd, F_SETFL, O_SYNC);

dio_tcsetattr($fd, array(
  'baud' => 9600,
  'bits' => 8,
  'stop'  => 1,
  'parity' => 0
)); 

while (1) {

  $data = dio_read($fd, 256);

  if ($data) {
      echo $data;
  }
} 

?> 

In diesem Beispiel find ich die Zeile

$data = dio_read($fd, 256);

unglücklich, da die Funktion dio_read immer 256 Bytes liest und erst danach einen String zurückliefert.

Dagegen liefert

$data = dio_read($fd, 1);

jedes einzelne byte => Das was man reinschickt wird auch sofort angezeigt und nicht immer blockweise.

Damit wäre dieses Script (über die Konsole gestartet) schon ein einfaches Terminal.

Die Daemon Class muss ich noch überarbeiten, da in der von mir verwendeten Klasse einfach zu viele Fehler bzw. unzulänglichkeiten im Code vorhanden sind => ReWrite ;)

--Hans 21:43, 24. Jun 2005 (CEST)

Siehe auch