Maike: explode() erzeugt Leerzeichen wo keine sein sollten!

Hallo liebes Self-Forum,

ich hab ein großes Problem. Ich hab ein Script geschrieben, das nicht so funktioniert wie ich mir das vorstelle:

<?PHP
echo "<html><head></head><body>";

$file = "test.txt";
$datei = file($file);

for($x=0;$x<count($datei);$x++)
{
 $parts = explode("|", $datei[$x]);
 $gid   = trim($parts[0]);
 $bid   = trim($parts[1]);
 $timestamp  = trim($parts[2]);
 $ip   = trim($parts[3]);
 $name   = trim($parts[4]);
 $kommentar  = trim($parts[5]);
 echo "$gid, $bid, $timestamp, $ip, $name, $kommentar <br>\n";
}
echo "</body></html>";
?>

Inhalt der test.txt:
1|3|1046249704|80.145.122.17|test|Hi Andy, BACK IN BLACK, wie wir dich kennen. *g*|
1|3|1055159178|80.145.122.17||so sind sie halt, die WIB|

Ausgabe des Scripts:
<html><head></head><body>ÿþ1, 3, 1 0 4 6 2 4 9 7 0 4, 8 0 . 1 4 5 . 1 2 2 . 1 7, t e s t, H i   A n d y ,   B A C K   I N   B L A C K ,   w i e   w i r   d i c h   k e n n e n .   * g * <br>
1, 3, 1 0 5 5 1 5 9 1 7 8, 8 0 . 1 4 5 . 1 2 2 . 1 7, , s o   s i n d   s i e   h a l t ,   d i e   W I B <br>
</body></html>

Das Problem:
Erstmal wird er erste Wert falsch eingelesen "ÿþ1" statt "1".
Aber das viel größere Problem ist ja, dass hinter jedes Zeichen ein Leerzeichen gemacht wird, das da nicht hingehört. Kann sich das jemand erklären bevor ich noch verzweifle`?

Danke für eure Mühe.

Maike

  1. Hallo Maike.

    $parts = explode("|", $datei[$x]);

    Probier mal fgetcsv() aus anstatt explode.
    Also zb. so:
    $fp = fopen($file,'r');
    while($parts[] = fgetcsv($fp,1000,"|"));
    Damit hast du mit $parts einen zweidimensionalen Array mit den Daten.
    Ein bischen musst du das natürlich noch anpassen.

    Mfg _Siro.

    1. Hi Siro,

      danke für deinen Tip.

      Ich würde es nur gerne auf dem Weg machen wie ich es angefangen hab. Ich hab dafür schon den halben Mittag gebraucht weil ich mich in PHP nicht so auskenne. Ich dachte wäre vielleicht irgend ein Anfängerfehler der gleich von euch erkannt wird.

      Danke trotzdem.

      Maike

      1. Hallo.

        Ich würde es nur gerne auf dem Weg machen wie ich es angefangen hab. Ich hab dafür schon den halben Mittag gebraucht weil ich mich in PHP nicht so auskenne. Ich dachte wäre vielleicht irgend ein Anfängerfehler der gleich von euch erkannt wird.

        OK. Ich will mal nicht so sein.
        Ich habe mir deinen Quelltext kopiert und bei mir funktioniert's wunderbar.
        Vielleicht ist's ja die Text-Datei.

        MfG _Siro.

  2. $datei = file($file);

    for($x=0;$x<count($datei);$x++)

    Nur als Tipp: Hier kannst Du auch

    foreach ($datei as $zeile)

    anwenden. Du sparst Dir damit die lästige Schreiberei der Indexvariablen beim Zugriff auf das Feld.

    {
    $parts = explode("|", $datei[$x]);

    echo "$gid, $bid, $timestamp, $ip, $name, $kommentar <br>\n";

    Ausgabe des Scripts:
    ÿþ1, 3, 1 0 4 6 2 4 9 7 0 4, 8 0 . 1 4 5 . 1 2 2 . 1 7, t e s t, H

    Die Datei ist im utf-16-Format gespeichert. utf-16 ist eine Speicherart für Unicode, bei der für jedes Zeichen 16 Bits, also zwei Byte verwendet werden. Das "ÿþ" am Anfang kennzeichnet hier (grob gesagt) die Unicode-Speicherung, die Leerzeichen entstehen dadurch, daß jedes Zeichen zwei statt wie seit Anno Dazumal üblich einem Byte einnimmt. Du bzw. So eine Datei muß man natürlich auch "Zwei-Byte-Weise" auslesen, nicht Ein-Byte-Weise, wie Du bzw. Dein PHP es gerade macht.

    Es ist prinzipiell eine feine Sache, daß Du Unicode verwendest, weil Du Dir und Deiner Kundschaft damit viel Ärger ersparst. Mit herkömmlichen, 8-bittigen Zeichensätzen (8 Bit=256 Schriftzeichen) lassen sich nicht alle Schriftzeichen weltweit darstellen, selbst das Eurosymbol ist in vielen Zeichensätzen nicht vorhanden und in denen, in denen es vorhanden ist, liegt es an unterschiedlichen Positionen (Nummer 128 bei windows-1252, Nummer 164 bei iso-8859-15).
    Unicode umfasst 32 Bit, das ist Raum für mehr als vier Milliarden Zeichen. Unicode wird von allen großen und kleinen Herstellern untersützt, Probleme mit inkompatiblen oder unzulänglichen Zeichensätzen werden in Zukunft also hoffentlich nicht mehr auftreten.

    Aber zu Deinem Problem: Am einfachsten wäre es für Dich wahrscheinlich, den Dateiinhalt vor Weiterverarbeitung in einen herkömmlichen Zeichensatz zu konvertieren. PHP bietet dafür die iconv()-Funktion, siehe http://de.php.net/manual/de/function.iconv.php:

    $datei = file("test.txt");
    $datei[0] = substr($datei[0], 2); // utf-Markierungsbytes entfernen

    foreach ($datei as $zeile) {
        $zeile = iconv("UTF-16","ISO-8859-1",$zeile);
        [...]
    }

    Bei "ISO-8859-1" muß der Zeichensatzname stehen, der von Dir benutzt wird. Verwendest Du in HTML (und indirekt auch in PHP) ausschließlich die &-Umschreibungen für Sonderzeichen (ü = ü usw.), kannst Du den allgemeinen Standard ISO-8859-1 stehen lassen, ansonsten kommt es auf Deinen Rechner und Texteditor an. Unter Windows wäre das beispielsweise windows-1252.

    Abschließend stellt sich natürlich die Frage, wie Du überhaupt an diese utf-16-Datei gekommen bist? So üblich ist dieses Format nicht, normalerweise findet man utf-8 oder eben einen alten Zeichensatz wie iso-8859-x oder windows-1252.

  3. hi,

    Aber das viel größere Problem ist ja, dass hinter jedes Zeichen ein Leerzeichen gemacht wird, das da nicht hingehört. Kann sich das jemand erklären bevor ich noch verzweifle`?

    ähm, hallo?
    hast du die geringste ahnung davon, was du da tust?

    tipp:
    suche doch mal in folgenden string, den du da ausgibst, nach leerzeichen - dann erklärt sich auch recht leicht das "wunder", wo diese wohl herstammen mögen.

    echo "$gid, $bid, $timestamp, $ip, $name, $kommentar <br>\n";

    gruss,
    wahsaga

    1. hm,

      ach so, du meintest die anderen leerzeichen ...

      gruss,
      wahsaga