ubuntuusers.de

PHP Problem: \n, \r in String entfernen.

Status: Gelöst | Ubuntu-Version: Nicht spezifiziert
Antworten |

DenniX

Avatar von DenniX

Anmeldungsdatum:
3. Juni 2007

Beiträge: 380

Hey ihr,

da wir hier im Forum "Shell und Programmieren" sind frage ich direkt mal hier nach.

Ich habe ein PHP Script, welches eine PING Abfrage an einen Server ausführt. Insgesamt 5 Stück.
Diese Abfrage wird mit "system()" ausgeführt. (exec() hab ich auch schon probiert)

Diese Ausgabe speicher ich in $result.
Nun soll er mit preg_replace() die Zeilenumbrüche durch ";;;" ersetzen, also hab ich folgenden Code genommen:

           if(SYSTEM_OS == "unix")
           {
                $result  = system("ping -c ".$count." -w ".$count." -s 8 ".$host);
                system("killall ping");// kill all ping processes in case there are some stalled ones
           }
           else
           {
                $result  = system("ping -n ".$count." ".$host);
           }
      
           $result       = preg_replace("/\r|\n/s", ";;;", $result);

Danach habe ich mit echo die Variable $result ausgegeben und das Ergebnis ist: Keine ";;;" an Stelle der Zeilenumbrüche ☹
Er hat sie nicht ersetzt.

Komisch finde ich: In einem anderen Script funktioniert es bzw. mit normalen fest vorgegeben Zeichenketten.
Ich hab es testweise auch schon mit "/n" versucht (auf einen Rat eines Kollegen), aber das bringt erst Recht nix.

Mit exec() bewirkt das alles nur, dass ich die letzte Zeile bekomme ☹

Kann mir da jemand weiter helfen?

Mein Ziel ist es im Prinzip, jede Zeile in ein Array zu bekommen.
Vor hatte ich es mit einem "Trennzeichen" wie ";;;". Die Zeilen sollten also im Endeffekt so aussehen:
PING 1;;;PING 2;;;PING 3;;;
und diese dann mit explode() in Arrays speichern.

Liebe Grüße,
DenniX

PS: PHP5 auf einem Ubuntu Linux System. (7.10)

fred.reichbier

Anmeldungsdatum:
14. Dezember 2006

Beiträge: 350

Hallo,

wenn du nur alle Pingzeilen in ein Array bekommen willst, benutze doch explode oder preg_match_all. Ich habe mal mit dem Regexp-Evaluator eine Lösung erzeugt:

<?PHP
  //
  // Text, der durchsucht werden soll
  //
  $subject = '12 bytes from fg-in-f104.google.com (72.14.221.104): icmp_seq=1 ttl=245
12 bytes from fg-in-f104.google.com (72.14.221.104): icmp_seq=2 ttl=245
12 bytes from fg-in-f104.google.com (72.14.221.104): icmp_seq=3 ttl=245
12 bytes from fg-in-f104.google.com (72.14.221.104): icmp_seq=4 ttl=245
';
  //
  // Der Reguläre Ausdruck
  //
  $pattern = '/^(.+)$/iUm';
  //
  // RegExp auswerten
  //
  $result = preg_match_all($pattern, $subject, $subpattern);
  //
  // Ergebnis ausgeben
  //
  echo '<p>Der verwendete Reguläre Ausdruck trifft auf den zu durchsuchenden Text '.
       (($result) ? $result.' mal ' : 'nicht ').'zu.</p>';
  //
  // Unterausdrücke ausgeben
  //
  echo '<pre>'.print_r($subpattern, TRUE).'</pre>';
?> 

Der Modifier i bedeutet, dass Groß- und Kleinschreibung ignoriert wird (unnötig in dem Fall), U, dass er ungreedy arbeitet und m, dass ^ und $ zeilenweise gelten, und das ist der wichtigste Modifier 😉

Wie gesagt, beim Evaluator funktionierts, ob ich dein Problem nicht falsch verstanden habe, weiß ich jetzt aber nicht 😉

Gruß Fred

DenniX

(Themenstarter)
Avatar von DenniX

Anmeldungsdatum:
3. Juni 2007

Beiträge: 380

Wenn ich folgendes im Code habe:

  $subject = '12 bytes from fg-in-f104.google.com (72.14.221.104): icmp_seq=1 ttl=245
12 bytes from fg-in-f104.google.com (72.14.221.104): icmp_seq=2 ttl=245
12 bytes from fg-in-f104.google.com (72.14.221.104): icmp_seq=3 ttl=245
12 bytes from fg-in-f104.google.com (72.14.221.104): icmp_seq=4 ttl=245
';

Dann funktioniert das bei mir auch mit preg_replace und explode zusammen.
Ich möchte ja von einer PING Abfrage die wie folgt aussieht:

PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.044 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.045 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.039 ms
64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.043 ms
64 bytes from 127.0.0.1: icmp_seq=5 ttl=64 time=0.039 ms

–- 127.0.0.1 ping statistics –-
5 packets transmitted, 5 received, 0% packet loss, time 3999ms
rtt min/avg/max/mdev = 0.039/0.042/0.045/0.002 ms

Jede Zeile in einem Array haben.

Mein Problem ist allerdings das er mit "system("ping 127.0.0.1 -c 5 -w 5");" die Zeilenumbrüche nicht entfernen kann und mit ";;;" ersetzen (mit preg_replace).
Somit habe ich dann die komplette PING Abfrage in einem Array (Element 0).

Meine Frage konkret also: wieso entfernt er mit preg_replace("/\r|\n/s", ";;;", $result); keine Zeilenumbrüche einer PING Abfrage.
Wenn ich ein festen String habe (wie z.B. in deinem Code $subject), geht das ohne Probleme!)

Die Ausgabe über "print_r($result)" ist immer:

Array
(
[0] ⇒ rtt min/avg/max/mdev = 13.892/13.962/14.032/0.070 ms
)

Das Array soll bzw MUSS aber so aussehen:

Array
(
[0] ⇒ PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
[1] ⇒ 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.044 ms
[2] ⇒ 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.045 ms
[3] ⇒ 64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.039 ms
[4] ⇒ 64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.043 ms
[5] ⇒ 64 bytes from 127.0.0.1: icmp_seq=5 ttl=64 time=0.039 ms
[6] ⇒ –- 127.0.0.1 ping statistics –-
[7] ⇒ 5 packets transmitted, 5 received, 0% packet loss, time 3999ms
[8] ⇒ rtt min/avg/max/mdev = 0.039/0.042/0.045/0.002 ms
)

fred.reichbier

Anmeldungsdatum:
14. Dezember 2006

Beiträge: 350

Ah, jetzt verstehe ich 😉
Wirf mal einen Blick in die Doku, insbesondere auf diese Sätze:

Gibt die letzte Zeile der Befehlsausgabe bei Erfolg, andernfalls FALSE zurück.
Wenn Sie auf die direkte Rückgabe/ Ausgabe eines Befehls angewiesen sind, dann benutzen Sie stattdessen die Funktion passthru().

Gruß Fred

Edit: *uffza* wohl doch nicht so richtig, passthru scheint die Ausgabe auszugeben, und nicht in eine Variable zu schreiben. Vielleicht hilft dir popen oder proc_open. Eine Q&D-Lösung wäre, mit ob_start die Ausgabe abzufangen 😉

DenniX

(Themenstarter)
Avatar von DenniX

Anmeldungsdatum:
3. Juni 2007

Beiträge: 380

Das Leben könnte so einfach sein *gg*

Habe jetzt passthru(); und mein Ergebnis ist:

PING 87.230.21.216 (87.230.21.216) 8(36) bytes of data. 16 bytes from 87.230.21.216: icmp_seq=1 ttl=55 time=14.3 ms 16 bytes from 87.230.21.216: icmp_seq=2 ttl=55 time=13.7 ms –- 87.230.21.216 ping statistics –- 2 packets transmitted, 2 received, 0% packet loss, time 999ms rtt min/avg/max/mdev = 13.729/14.035/14.342/0.328 ms

Array
(
[0]
)

er gibt einmal die komplette PING Abfrage aus (wie bei system()), dort wo ich die Abfrage ausführe, und dann wo ich print_r($result) ausführe, zeigt er mir garnichts mehr an ☹

Hm...

DenniX

(Themenstarter)
Avatar von DenniX

Anmeldungsdatum:
3. Juni 2007

Beiträge: 380

Edit: *uffza* wohl doch nicht so richtig, passthru scheint die Ausgabe auszugeben, und nicht in eine Variable zu schreiben. Vielleicht hilft dir popen oder proc_open. Eine Q&D-Lösung wäre, mit ob_start die Ausgabe abzufangen 😉

Werde ich mal eben ausprobieren ☺
Melde mich sofort wieder.

DenniX

(Themenstarter)
Avatar von DenniX

Anmeldungsdatum:
3. Juni 2007

Beiträge: 380

           if(SYSTEM_OS == "unix")
           {
                $handle = popen("ping -c ".$count." -w ".$count." -s 8 ".$host, "r");
                while (!feof($handle)) {
                     $result .= fgets($handle, 4096);
                }
                pclose($handle);
           }
           else
           {
                // Bla bla, für Windows.
           }
      
           $result       = preg_replace("/\r|\n/s", ";;;", $result);

Das Ergebnis:
Alle Ping Abfrage-Zeilen in einer Zeile mit ";;;" getrennt 😀

Vielen vielen Dank ☺

Hast mir sehr geholfen.

LG,
DenniX

Antworten |