Downloadskript setzt Leerzeichen in meine Datei

Hallo Zusammen!

Habe ein Problem mit meinem Downloadskript. Ausgangssituation:

In einer MySQL Datenbank befinden sich Word-Dokumente im XML-Format (WordProcessing ML). Diese sind in der Datenbank als BLOB gespeichert. Über das Download-Skript in PHP sollen diese Dateien nun heruntergeladen werden können.

PHP:
<?php

	session_start (); 
	if (!isset ($_SESSION["user_id"])) 
	{ 
		header ("Location: formular.php"); 
	} 

	$id = $_GET['id'];

    $db = new mysqli($db_host, $db_user, $db_pass, $db_db);
	if(mysqli_connect_errno() == 0)
	{
		$sql = 'SELECT '.$blob.' FROM dokumente WHERE id = ?';
		$stmt = $db->prepare($sql);
		$stmt->bind_param("i",$id);
		$stmt->execute();
		
		if($stmt->bind_result($doc))
		{
			$stmt->fetch();
			//Dateityp
			header( 'Content-type: application/octet-stream' );
			// Größe der Datei
			header( 'Content-Length: ' . strlen( $doc ) );
			//Dateiname
			header("Content-Disposition: attachment; filename=$filename");
			// Ausgeben der Datei
			echo $doc;
		}

		else
		{
			die("Fehler in bind_result!");
		}
	}
	else
	{
		die("Fehler: Es konnte keine Verbindung zur Datenbank aufgebaut werden!");
	}
?>

Der Download funkioniert, jedoch wird in die Datei am Anfang ein Leerzeichen eingefügt, so dass diese mit
Code:
 <xml version="1.0">
statt mit
Code:
<xml version="1.0">
beginnt. Word kann die Datei so nicht öffnen. Weiß jemand wie ich das Leerzeichen weg bekomme? Mit
PHP:
echo substr($doc, 1);
erhalte ich
Code:
 xml version="1.0">
Das Leerzeichen muss also schon vorher ausgegeben werden. Ich bin für jede Hilfe dankbar!
 
Hi,

So wie ich das sehe, wird da kein Leerzeichen vor der Ausgabe der Daten geschrieben. Kann ja auch nicht, da du die header-Funktion nicht aufrufen kannst, wenn du schon eine Ausgabe hattest.

Daher tippe ich eher auf dein $doc. Liegen die Daten UTF-8 kodiert vor? Dann solltest du nicht substr() nehmen, sondern die mb_substr(). Die normale substr kann nicht mit Multi-Byte Zeichen umgehen.

mb_substr() hat die selben Parameter wie substr(), Details gibts hier.

Gruß
BK
 
mb_substr() funktioniert leider auch nicht. Es schneidet wieder das Zeichen nach dem Leerzeichen ab. Der Zeichensatz der MySQL Tabelle ist Latin1.
 
Hi,

um mal die Vermutung, dass das Leerzeichen vorher ausgegeben wird wegzuräumen, versuche mal folgendes:

PHP:
<?php
    ob_start();
    session_start (); 
    if (!isset ($_SESSION["user_id"])) 
    { 
        header ("Location: formular.php"); 
    } 

    $id = $_GET['id'];

    $db = new mysqli($db_host, $db_user, $db_pass, $db_db);
    if(mysqli_connect_errno() == 0)
    {
        $sql = 'SELECT '.$blob.' FROM dokumente WHERE id = ?';
        $stmt = $db->prepare($sql);
        $stmt->bind_param("i",$id);
        $stmt->execute();
        
        if($stmt->bind_result($doc))
        {
            $stmt->fetch();
            //Dateityp
            header( 'Content-type: application/octet-stream' );
            // Größe der Datei
            header( 'Content-Length: ' . strlen( $doc ) );
            //Dateiname
            header("Content-Disposition: attachment; filename=$filename");
            // Ausgeben der Datei
           ob_end_clean();
            echo $doc;
        }

        else
        {
            die("Fehler in bind_result!");
        }
    }
    else
    {
        die("Fehler: Es konnte keine Verbindung zur Datenbank aufgebaut werden!");
    }
?>

Hierbei wird erstmal jedliche Ausgabe gepuffert und dann vor der eigentlichen Ausgabe der XML-Daten gelöscht. Somit kann nichts vorher ausgegeben werden ;)

Was mir noch einfällt: Hast du vielleicht vor dem <?php am Anfang vielleicht ein Leerzeichen? Welche Kodierung hat das Script?

Gruß
BK
 
ob_end_clean(); war die Lösung. Aber wo kommt das Leerzeichen her? Das Downloadskript wird über einen Link mit
HTML:
target="_blank"
gerufen. Entsteht das Leerzeichen vielleicht durch die Headerangaben die ich vorher mache?

Vielen Dank
 
Hi,

das ist wirklich sehr komisch. Normalerweise wirft ein Aufruf der header-Funktion eine Warnung, sobald schon eine Ausgabe stattgefunden hat. header() modifiziert ja nur die Kopfdaten der Datei, der ist unabhängig vom Inhalt.
Aber nunja ;) Ich tippe mal darauf, dass du ein Leerzeichen vor dem "<?php" stehen hast. Schau mal mit einem Editor, der die Kodierung der Dateien auch korrekt darstellen kann, ob du da was findest (z.B.: mit Notepad++).

Gruß
BK
 
Habs das Leerzeichen gefunden. Die Zeilen
PHP:
    session_start (); 
    if (!isset ($_SESSION["user_id"])) 
    { 
        header ("Location: formular.php"); 
    }
habe ich hier zur Übersicht in die Datei geschrieben. Eigentlich stehen die in einer separaten Datei, welche incudiert wird. Dort war nicht vor dem <?php Tag ein Leerzeichen sondern hinter dem ?> Tag am Ende der Datei ein Leerzeichen.
 
Zurück