PHP, exec und Sonderzeichen

Disclaimer: Dieser Thread wurde aus dem alten Forum importiert. Daher werden eventuell nicht alle Formatierungen richtig angezeigt. Der ursprüngliche Thread beginnt im zweiten Post dieses Threads.

PHP, exec und Sonderzeichen
Ich hab mir einen kleinen Filemanager geschrieben (unterdessen auch schon ewig her) und den wollte ich jetzt um folgenden Funktion erweitern:
Ich möchte mir „den Inhalt“ von .tar.*'s anzeigen lassen.
Das versuche ich wie folgt zu lösen:

[code]<?php

exec(‚tar -tf tar.tar.bz2‘,$out);

foreach($out as $line)
{
echo $line.PHP_EOL;
}

?>[/code]

tar.tar.bz2 ist mein Archiv mit einer Datei namens „lülülü.log“.

Wenn ich das lokal in meiner Shell ausführe haut das auch wunderbar hin:

[quote]chris@genua:/home/chris/Desktop$ php5-cgi tartest.php
X-Powered-By: PHP/5.3.6-12
Content-type: text/html

lülülü.txt[/quote]

Sobald ich das aber am Server (sowohl lokal als auch online) teste bekomme ich im Browser folgende Ausgabe

Was für eine Art der Darstellung ist das und wie bekomme ich daraus meine ü wieder ? :slight_smile:

Grüße Chris


Das ist UTF-8 (perl -e ‘print “l\303\274l\303\274l\303\274.txt”’ > x && file x), du musst dem Browser sagen, dass der Inhalt in diesem Encoding ist.


Hmm, irgendwie hab ich mir schon gedacht dass ich da über UTF-8 stolper.
Allerdings: Wie bekomm ich das direkt in PHP hin ?

header('Content-Type: text/html; charset=utf-8');

und

echo utf8_decode($line).PHP_EOL;

tuen nicht ganz das was ich mir vorgestellt hab :slight_smile:


Wenn das ganze in UTF-8 ist, sollte der Header eigentlich reichen - utf8_decode() macht was anderes! Kenne mich mit PHP aber nicht wirklich aus.


[code=php]<?php
$str = ‘lülülü.txt’;

header(‘Content-Type: text/html; charset=utf-8’);
echo $str.PHP_EOL;[/code]

[m]% file -i test.php
test.php: text/x-php; charset=utf-8
% wget --save-headers -qO- [#]http://localhost/test.php[/#]
[color=gray]HTTP/1.0 200 OK
X-Powered-By: PHP/5.3.3-7+squeeze3
Content-Type: text/html; charset=utf-8
Content-Length: 14
Connection: keep-alive
Date: Fri, 15 Jul 2011 13:34:55 GMT
Server: lighttpd/1.4.28

lülülü.txt[/color][/m]

Auch mit Opera, Firefox, Chrome und IE getestet… funktioniert.


Das Problem hängt imho auch mit dem exec zusammen - nicht generell mit Sonderzeichen.

str_replace('\303\274','ü',$line);

Damit kann ich das “\303\274” wieder zu einem ü machen, was dann auch richtig ausgegeben wird.
Allerdings ist die Frage die mich beschäftigt eher wie ich generell diese \xxx\xxx loswerde.
Dieses einzelne zurückübersetze überzeugt mich nicht, bei einem ‘ä’ würde das obige wieder failen.

Grüße Chris


schon mal sowas wie [m]shell_exec(‘LANG=en_US.utf-8; somecommand -foo’);[/m] probiert? Also das Encoding fuer das exec explizit zu setzen?


[code=php]<?php
exec(‘tar -tf foo.tar’, $str);

header(‘Content-Type: text/html; charset=utf-8’);
foreach ($str as $line) {
echo $line.PHP_EOL;
}
[/code]

[m]% tar -tf foo.tar
lülülü.txt
% tar -tf foo.tar | file -i -
/dev/stdin: text/plain; charset=utf-8
% wget --save-headers -qO- [#]http://localhost/test.php[/#]
[color=gray]HTTP/1.0 200 OK
X-Powered-By: PHP/5.3.3-7+squeeze3
Content-Type: text/html; charset=utf-8
Content-Length: 14
Connection: keep-alive
Date: Fri, 15 Jul 2011 14:06:45 GMT
Server: lighttpd/1.4.28

lülülü.txt[/color][/m]

Wieder mit Opera, Firefox, Chrome und IE getestet… funktioniert.

Ist deine PHP-Option [m]magic_quotes_runtime[/m] auf [m]On[/m] gesetzt? Dann darf ich das PHP Manual zitieren: “This feature has been DEPRECATED as of PHP 5.3.0. Relying on this feature is highly discouraged.” (http://de3.php.net/manual/en/security.magicquotes.php)


[quote]chris@genua:/home/chris$ wget --save-headers -qO- http://localhost/tartest.php
HTTP/1.0 200 OK
X-Powered-By: PHP/5.3.6-12
Content-Type: text/html; charset=utf-8
Content-Length: 32
Connection: keep-alive
Date: Fri, 15 Jul 2011 14:22:32 GMT
Server: lighttpd/1.4.28

l\303\274l\303\274l\303\274.txt[/quote]
Genau deinen Code getestet, John Late.
In Chromium und Iceweasel hauts bei mir nicht hin

magic_quotes_runtime ist aus.

meisterT, das hatte ich auch schon probiert, ohne Erfolg…

Grüße Chris


Überprüf die Einstellung zur Sicherheit nochmal mit [m]ini_get()[/m]. Ansonsten kannst du dir das zur Not mit [m]stripslashes()[/m] zurechtfrickeln…


magic_quotes_runtime ist wirklich aus :wink:

Wird wohl auf gefrickel rauslaufen, wenns direkt / “elegant” nicht mag.

Danke aber soweit !


Au weia, hier wird ziemlich viel durcheinander gewürfelt…

Also wenn du den Content-Type-Header setzt und sagst, dass du UTF-8 auf der Webseite verwendest, dann darfst du natürlich nicht mit utf8_decode() von UTF-8 nach Latin1 konvertieren, das widerspricht sich doch.

Dann hab ich hier gesehen, dass jemand den Dateinamen mit den Umlauten direkt in der PHP-Datei als String geschrieben hat. Da kommt’s natürlich noch drauf an, in welcher Zeichenkodierung die PHP-Datei gespeichert wurde. Unter Windows wird das Latin1 sein (wenn nicht anders im Editor ausgewählt), Linux verwendet gerne mal für alles ungefragt und ohne BOM UTF-8.

Ansonsten kenne ich diese \oktal-Notation nur vom Dateisystem unter Linux. Das dürfte nicht viel mit PHP zu tun haben. Zudem ja noch ein Linuxprogramm gestartet wird, und PHP einfach nur dessen Ausgabe übernimmt. Versuch doch mal, den tar-Befehl direkt auf der Webserver-Maschine in einer Shell auszuführen. Wenn dort was anderes passiert, kannst du die Umgebungsvariablen (LANG etc.) mit denen aus dem PHP-Aufruf (system(‘env’) oder so) vergleichen.


[quote=Yves]
Dann hab ich hier gesehen, dass jemand den Dateinamen mit den Umlauten direkt in der PHP-Datei als String geschrieben hat. Da kommt’s natürlich noch drauf an, in welcher Zeichenkodierung die PHP-Datei gespeichert wurde.[/quote]

Darum habe ich das ja extra verifiziert…


Yeah, danke Yves :slight_smile:

Das mit den Systemvariablen wars.

Während das hier

[code]<?php
header(‘Content-Type: text/html; charset=iso-8859-1’);

putenv(“LANG=en_US.UTF-8”);
exec(‘tar -tf tar.tar.bz2’,$out);

foreach($out as $line)
{
echo utf8_decode($line).PHP_EOL;
}
?>[/code]
tut was ich möchte (aka “die Sonderzeichen passen”),

tut das hier

[code]<?php
header(‘Content-Type: text/html; charset=iso-8859-1’);

exec(‘LANG=en_US.UTF-8; tar -tf tar.tar.bz2’,$out);

foreach($out as $line)
{
echo utf8_decode($line).PHP_EOL;
}
?>[/code]
eben nicht was es soll.

Das mit dem utf-8 im Header / utf8_decode() war nur eine Auflistung was ich schon alles probiert hatte - es war mir anfangs egal, welches encoding das ganze hat, es musste primär erstmal Sonderzeichen anzeigen - was es jetzt tut :slight_smile:

Als Anmerkung:
Das System auf dem das gecodet wurde ist (erstmal) auch die “Webserver-Maschine” - ein Debian Wheezy :wink:

Grüße und Danke, Chris


Es wird was in die Umgebung geschrieben, die (anscheinend, ist nicht dokumentiert) an neue Unterprozesse - hier tar - vererbt wird. Damit wirkt sich die Variable auf tar aus.

Es wird eine Variable gesetzt und danach in einem separaten Aufruf tar gestartet. Die neue Variable wird nicht an tar exportiert. In Bash müsstest du vor die Variablenzuweisung noch ‚export‘ schreiben, aber ob das in exec() auch so funktioniert, weiß ich nicht. Wenn du den Strichpunkt einfach weglassen würdest, könnte es aber auch funktionieren! (Das ist das übliche Vorgehen.) auch @meisterT

Tja, wenn man Zeichenkodierung nicht versteht und einfach irgendwas macht und dann noch will, dass es irgendwie funktioniert, dann wird man erstmal lange rumfrickeln und sich später wundern, warum es irgendwann plötzlich nicht mehr geht. Wenn man Zeichenkodierung dagegen versteht (erster Ansatz: ein Byte und ein Zeichen sind grundverschiedene Dinge), kommt man schnell zu zuverlässigen Ergebnissen. :wink:


Vor allem freut man sich, wenn man sein Webprojekt an allen Enden von Anfang an auf UTF-8 aufsetzt. Mittendrin zu konvertieren ist saunervig


Mag sein, dass das man ein Webprojekt direkt von Anfang an sauber auf UTF-8 trimmen sollte - allerdings bastel ich hier an meinem Browser-Filemanager rum, den ich vor ca 2 Jahren geschrieben hab.
Da sind viele Sachen auf eine Art und Weise gemacht, wie ich sie heute nicht mehr tuen würde - allerdings ist dieser Filemanager eines meiner Erzeugnisse die ich oft nutze.
Das ganze setzt auf AJAX auf (was ich weiterhin so machen würde :wink: ), von daher sollte es relativ einfach sein das Encoding zu ändern - das Projekt besteht ja hauptsächlich aus „kleinen Files“ - vll. sollte ich das mal angehen g

Dazu nochmal.

export LANG=en_US.UTF-8; tar -tf tar.tar.bz2

haut hin

LANG=en_US.UTF-8 tar -tf tar.tar.bz2

und das auch Tisch->Kopf

Grundlegend, das glaube ich zumindest, habe ich „Zeichenkodierung“ verstanden - eine Zahl muss ja nicht - und tut sie auch nicht - in jedem Zeichensatz das gleiche bedeuten - mal ganz davon abgesehn dass es Zeichensätze gibt die „etwas größer“ sind - und die einzelnen Zeichen damit uU auch mehr Speicherplatz benötigen :slight_smile:

Natürlich weiß ich bei weitem nicht alles - meine PHP-Skills hab ich mir auch per „learning by failing“ angeeignet (gilt im übrigen auch für JS / HTML) und mögen daher teilweise ein wenig verquer erscheinen g

Mit diesen Worten :slight_smile:


Hehe, UnivIS vor genau einem Jahr… :cool:


Hallo Leute, ich habe auch ein ähnliches Problem, es soll mein Aktueller Status bei Facebook (kein Plugin) über einen Crawler direkt abgelesen werden, sodass ich diesen auf ein Blog posten kann. Ich bin mir jedoch nicht sicher, wie kann ich die Position auf der Webseite dem Crawler genau zeigen, woher er sich den Content nimmt?
Ich hab sowas auf Seiten wie http://kleinanzeigen-muenchen.de/ wo offenbar die Anzeigen gecrawed und ausgegeben werden und auch auf http://www.lottovergleich.com/lottozahlen/ gesehen. Hat jemand von euch eine Idee? Mache ich das nur über den

Tag wo die Info gespeichert ist? Vielen Dank!