de.comp.lang.php.* FAQ

13.2. Wie kann ich ein externes Programm von PHP aus starten?

Keywords: Programm | ausfuehren | extern

Antwort von Kristian Köhntopp

PHP kennt nicht weniger als fünf Mechanismen, um externe Kommandos (z. B. Unix-Shellbefehle) von PHP aus zu starten. Alle diese Mechanismen können zu einem Sicherheitsrisiko werden, wenn man Benutzereingaben Bestandteil der ausgeführten Kommandos oder Dateinamen werden lässt.

Durch Anwendung der Funktion EscapeShellCmd() kann man das Risiko etwas vermindern (etwa: system(escapeshellcmd($cmd))). Dennoch empfiehlt es sich, die Parameter, die in die Gestaltung von $cmd eingehen, sorgfältig zu prüfen.

Externe Kommandos werden bei Verwendung von CGI PHP unter der Identität des CGI-Wrappers ausgeführt, bei Verwendung einer Modulversion von PHP mit der Identität des Webservers (siehe auch Webserver verstehen und tunen von Kristian Köhntopp).

Will man ein externes Kommando einfach nur ausführen, kann man das betreffende Kommando einfach in Backticks setzen:

  `touch yyy`;

Dies wird im selben Verzeichnis wie das PHP-Script die Datei yyy erzeugen, falls der Webserver dort Schreibrecht hat.

Alternativ kann man ein Kommando durch die Funktion exec() starten lassen. Auch hier ist die Ausgabe nicht sichtbar, kann aber in einem Array abgelegt werden:

  exec("cat /etc/group", $lines, $result);
  echo "result = $result<br>";

  echo "Lines<br>\n";
  foreach ($lines as $k => $v) {
    echo "k=$k v=$v<br>\n";
  }

Die Ausgabe des Befehls wird im Feld $lines zur Verfügung gestellt, der Exitcode des Befehls in $result.

Die Funktion system() gibt die Ausgabe des Unix-Kommandos dagegen an den Webserver weiter. Ebenso passthru() :

  system("ls -l", $result);
  echo "Result: $result<br>\n";

  passthru("ls -l", $result);
  echo "Result: $result<br>\n";

Schließlich kann man externe Kommandos noch mit Hilfe der Funktion popen() starten:

  $fp = popen("ls -l", "r");
  while($line = fgets($fp, 1024)) {
    printf("%s<br>\n", $line);
  }

Im safe_mode unterliegt die Programmausführung weiteren Einschränkungen.

Antwort von Johannes Frömter

PHP wartet bei der Ausführung externer Programme auf deren Beendigung, d. h. das PHP-Script ist solange blockiert, bis das aufgerufene Programm fertig ist. Um dies zu vermeiden, muss man den Output des Programms umleiten, z. B. nach /dev/null:

exec("programm >/dev/null 2>&1");

Antwort von Frank Wiegand

Sollte die Ausführung des externen Programmes fehlschlagen, dann muss man diese Punkte überprüfen:

  • Enthalten das Kommando oder die Argumente shellspezifische Sonderzeichen? Diese Zeichen haben in Shells u. U. eine besondere Bedeutung und müssen entsprechend escaped werden: &, ;, `, ', ", |, *, ?, ~, <, >, ^, (, ), [, ], {, }, $ und \. Hilfreich sind hierbei die Funktionen escapeshellcmd() und escapeshellarg() .

  • Stimmt der Pfad, falls der Programmname nicht absolut gesetzt ist? Da PHP oft unter einer anderen Benutzer-ID als der eigenen läuft, muss man damit rechnen, dass die Umgebungsvariable $PATH (in PHP: $_ENV['PATH']) anders gesetzt ist. Die absolute Angabe des Pfades löst dieses Problem.

  • Hat der Benutzer, unter dem PHP läuft, Ausführungsrechte für das Programm? Herausfinden läßt sich das, indem man in einer Shell die Rechte mit ls -l /pfad/zum/kommando überprüft (das x-Bit muss entsprechend gesetzt sein). Alternativ kann man auch die Funktion is_executable() (funktioniert nicht unter Windows!) benutzen.

Hilfreich bei der Fehlersuche ist die Umleitung der Standard-Fehlerausgabe auf die Standardausgabe:

  print `/pfad/zum/kommando arg1 arg2 2>&1`;

Valid HTML 4.01! Valid CSS!

13.2. Wie kann ich ein externes Programm von PHP aus starten?
http://www.php-faq.de/q/q-php-externes-programm.html
Archiv der de.comp.lang.php-FAQ Dies ist eine Archivseite von 2008 und wurde seitdem nicht geändert. Das dclp-FAQ-Team