MSSQLに接続していくつかの値を検索し、バイナリ形式で保存されているファイルを取得するphpコードがあります。テーブルには、ファイル名、ヘッダ、バイナリデータがあります。現在のところ私のコードはファイルを期待通りにダウンロードしていますが、ファイル名にスペースがあると、スペースが区切り文字として動作しているかのように、名前が短くなります。例えばdbの値 "This example is file.pdf"出力されたファイル名 "This"とブラウザはpdfの種類を認識します。スクリプトで短縮されたファイル名
マイ多少の機能のコードは以下の通りです:
/* 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);
}
私は問題は、ファイル名はDB内VARCHAR(255)として保存され、何とか「Content-Disposition」ヘッダ行を破壊していることであると思われます。研究は私にこのページをもたらしましたが、VARCHARを扱う方法や、推測(「ファイル」をダウンロードしていますが)の "index.php"というファイル名を取得しようとすると、
$filename = sqlsrv_get_field($stmt, 1, SQLSRV_PHPTYPE_VARCHAR);
は、私はまた、障害のあるヘッダ行の代わりにこれを試してみた:
は$filename = sqlsrv_get_field($stmt, 1, SQLSRV_PHPTYPE_STREAM(SQLSRV_ENC_BINARY)))
それはまだ、ファイル名を遮断します。ファイル名にスペースがない場合、コードは完全に実行されます。
BONUS:ダウンロードダイアログを表示するのではなく、ファイルをファイルシステムに保存する方法を知っている人はいますか?このコードは、私が書いているデータ・マイグレーション・スクリプトのためのコンセプトの証明であり、それはまた、非常に参考になる:)
私はPHPに精通していませんが、私はperlや他の言語で同様の問題に直面しました。おそらく、$ filenameを引用符で囲む必要があります(またはPHPの対応する代替方法...)?ショートカットを作成するときに、ウィンドウパスとファイル名を使用する必要がありますか?次のように見えるかもしれません:header( "Content-Disposition:attachment; filename = '$ filename'"); – Tyron78
応答してくれてありがとう、それを試してみました。今は ** 'This ** ファイル名の先頭に一重引用符が追加されました! – Daniel
私が言及したように:私はPHPに精通していません。私が達成しようとしていたのは、ヘッダーが次のように見えるということでした。Content-Disposition:attachment; filename = "$ filename"またはContent-Disposition:添付ファイル。 filename = '$ filename'。$ filenameは文字列で置き換えます。例えば内容 - 処分:添付;ファイル名= "これは例のファイルです.pdf" – Tyron78