I have some php code that connects to a MSSQL, looks up some values and retrieves a file that is stored in binary format. The table has the filename, header and the binary data. Presently my code is downloading the file as expected however, if there is a space in the filename, the name is cut short, as if the space is acting as a delimeter. e.g. value in db "This is an example file.pdf" outputted filename "This" and the browser recognises the pdf type.
My somewhat functional code is below:
/* Retrieve and display the data.
The return data is retrieved as a binary stream. */
if ( sqlsrv_fetch( $stmt ) )
{
$noticeID = sqlsrv_get_field( $stmt, 0, SQLSRV_PHPTYPE_INT);
$filename = sqlsrv_get_field( $stmt, 1, SQLSRV_PHPTYPE_STRING("UTF-8"));
$header = sqlsrv_get_field( $stmt, 2, SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_BINARY));
$download = sqlsrv_get_field( $stmt, 3, SQLSRV_PHPTYPE_STREAM(SQLSRV_ENC_BINARY));
header('Content-Type: '.$header);
header("Content-Disposition: attachment; filename=$filename");
echo "Your file, $filename is ready for download";
fpassthru($download);
}
else
{
echo "Error in retrieving data.</br>";
print_r( sqlsrv_errors(), true);
}
I suspect that the issue is that the filename is stored as a VARCHAR(255) in the DB and somehow is breaking the "Content-Disposition" header line. Research brought me to this page but it isn't very clear on how to handle VARCHAR and when I try and "hack" it by guessing (see below) and get a filename "index.php" (although it does download the file)
$filename = sqlsrv_get_field( $stmt, 1, SQLSRV_PHPTYPE_VARCHAR);
I've also tried this in place of the faulty header line:
$filename = sqlsrv_get_field( $stmt, 1, SQLSRV_PHPTYPE_STREAM(SQLSRV_ENC_BINARY)))
It still cuts off the filename. If there is no space in the filename, the code executes perfectly.
BONUS: does anyone know how I could save the file to the filesystem rather than having a download dialog? This code is proof of concept for a data migration script I'm writing and that would also be very helpful :)