Wenn PHP über das Web hinausgeht
\nStellen Sie sich eine Situation vor: Sie müssen einen Dämon schreiben, der Systemlogs überwacht, parst und Benachrichtigungen an Telegram sendet. Oder vielleicht müssen Sie einen eigenen Aufgabenplaner erstellen, der nicht von cron abhängt. Was, wenn Sie Ihren eigenen einfachen Webserver oder Proxy schreiben müssten? Die meisten Entwickler würden sofort zu Python, Go oder C greifen. Aber was, wenn ich Ihnen sage, dass PHP auch Systemprogrammierung kann? Und das ziemlich gut.
\nPHP ist nicht nur eine Sprache für "WordPress-Websites". Seine CLI-Version (Command Line Interface) ist ein vollwertiges Werkzeug für die Systemadministration, die Arbeit mit Prozessen, Netzwerk-Sockets und sogar die Dämonisierung. In diesem Artikel werden wir untersuchen, wie man PHP für die Systemprogrammierung einsetzt, und zeigen echte Codebeispiele, die unter Linux funktionieren.
\n\nVorbereitung: Was Sie wissen müssen
\nStellen Sie zunächst sicher, dass PHP mit CLI-Unterstützung und den Erweiterungen pcntl (Prozessverwaltung), posix (Systemaufrufe) und sockets (Socket-Programmierung) installiert ist. In den meisten Linux-Distributionen geschieht dies mit einem Befehl:
sudo apt install php-cli php-pcntl php-posix php-sockets\nDie Verfügbarkeit der Erweiterungen können Sie mit php -m | grep -E 'pcntl|posix|sockets' überprüfen. Wenn alles vorhanden ist – los geht's.
Arbeit mit Prozessen: fork und exec
\nPHP ermöglicht das Erstellen von Kindprozessen mit der Funktion pcntl_fork(). Dies ist ein leistungsstarker Mechanismus für die parallele Ausführung von Aufgaben. Betrachten wir ein Beispiel, das drei Kindprozesse startet, die jeweils ihre eigene Arbeit erledigen.
<?php\n$workers = 3;\n$pids = [];\n\nfor ($i = 0; $i < $workers; $i++) {\n $pid = pcntl_fork();\n if ($pid == -1) {\n die("Prozess konnte nicht erstellt werden");\n } elseif ($pid) {\n // Elternprozess: PID des Kindes speichern\n $pids[] = $pid;\n echo "Kindprozess mit PID: $pid erstellt\\n";\n } else {\n // Kindprozess\n echo "Kindprozess " . getmypid() . " hat die Arbeit aufgenommen\\n";\n sleep(rand(2, 5)); // Arbeit simulieren\n echo "Kindprozess " . getmypid() . " beendet\\n";\n exit(0);\n }\n}\n\n// Eltern wartet auf die Beendigung aller Kindprozesse\nforeach ($pids as $pid) {\n pcntl_waitpid($pid, $status);\n echo "Prozess $pid mit Status $status beendet\\n";\n}\n?>\nDieser Code demonstriert grundlegendes Multitasking in PHP. Sie können parallele Aufgaben ausführen – Logs parsen, Dateien verarbeiten, Netzwerkanfragen durchführen. In der Systemprogrammierung ist dieser Ansatz unverzichtbar, wenn große Datenmengen ohne Blockierung des Hauptthreads verarbeitet werden müssen.
\n\nAusführung externer Befehle
\nDie Funktion exec() und ihre Varianten (shell_exec(), system()) ermöglichen das Ausführen beliebiger Systembefehle. Für echte Systemprogrammierung ist jedoch proc_open() besser geeignet – es bietet volle Kontrolle über Ein-/Ausgabe und die PID des Prozesses.
<?php\n$descriptorspec = [\n 0 => ["pipe", "r"], // stdin\n 1 => ["pipe", "w"], // stdout\n 2 => ["pipe", "w"] // stderr\n];\n\n$process = proc_open('ping -c 4 8.8.8.8', $descriptorspec, $pipes);\n\nif (is_resource($process)) {\n // Ausgabe lesen\n $output = stream_get_contents($pipes[1]);\n fclose($pipes[1]);\n fclose($pipes[2]);\n proc_close($process);\n \n echo "Ergebnis von ping:\\n$output";\n}\n?>\nDieser Ansatz ermöglicht die Integration von PHP mit beliebigen Systemdienstprogrammen – von ps bis ffmpeg.
Signalverarbeitung: Einen höflichen Dämon erstellen
\nJeder ernsthafte Dämon muss Betriebssystem-Signale korrekt verarbeiten. PHP ermöglicht über die Erweiterung pcntl das Abfangen von Signalen (SIGTERM, SIGHUP, SIGUSR1 und andere). Dies ist eine Schlüsselqualifikation