26

fputcsvJSON 文字列を受け取り、それを CSV 形式に変換し (を使用して)、その CSV をダウンロードした .csv ファイルとして使用できるようにする短い PHP スクリプトを作成しようとしています。私の考えでは、tmpfile()cron ジョブやディスク容量の不足を心配する必要はありませんでしたが、魔法を起こすことができないようです。

のPHPドキュメントreadfileから変換された例である私の試みは次のとおりです。

$tmp = tmpfile();
$jsonArray = json_decode( $_POST['json'] );
fputcsv($tmp, $jsonArray);

header('Content-Description: File Transfer');
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename='.basename($tmp));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($tmp));

ob_clean();
flush();
readfile($tmp);

Content-Dispositionおよびヘッダーが間違っているように感じContent-Transfer-Encodingますが、修正方法がわかりません。たとえば、basename($tmp)何も返されないようで、text/csvバイナリ エンコーディングとして転送されるかどうかはわかりません。同様に、echo filesize($tmp)も空白です。私がここで試みていることを行う方法はありますか?

[編集]

**以下は、受け入れられた回答の結果として私が書いた作業コードです:*

$jsonArray = json_decode( $_POST['json'], true );
$tmpName = tempnam(sys_get_temp_dir(), 'data');
$file = fopen($tmpName, 'w');

fputcsv($file, $jsonArray);
fclose($file);

header('Content-Description: File Transfer');
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename=data.csv');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($tmpName));

ob_clean();
flush();
readfile($tmpName);

unlink($tmpName);
4

4 に答える 4

8

はファイルハンドルを返すことに注意してください。ただしtmpfile()、必要なすべての関数には、ハンドルではなくファイルパス(つまり、文字列)が必要です。特にbasename、、、filesizeおよびreadfile。したがって、これらの関数呼び出しはいずれも正しく機能しません。またbasename、ファイル拡張子も返しません。好きなように呼んでください。

'Content-Disposition: attachment; filename=data.csv'

@Joshua Burnsも言うように、配列を渡すか、パラメーターをfputcsv使用していることを確認してください。assoc

于 2013-03-13T16:25:38.570 に答える
3

json_decode()デフォルトでは、要素は配列ではなくオブジェクトに変換されます。fputcsv()渡されるデータが配列であることが期待されます。

変更することをお勧めします:

$jsonArray = json_decode( $_POST['json'] );

に:

$jsonArray = json_decode( $_POST['json'], True );

そして、それで問題が解決しないかどうかを確認してください。

このような問題に取り組むときは、有効display_errorsにして設定error_reportingE_ALL、見逃しているエラーがあるかどうかを確認することを強くお勧めします。

<?php
error_reporting(E_ALL);
ini_set('display_errors', '1');

// Rest of your code here
于 2013-03-13T16:22:00.907 に答える
0

まず、この文字列を確認してください。次のように変更します。

header('Content-Disposition: attachment; filename="'.basename($tmp).'"');

私はブラウザの互換性で一度問題を抱えていました:)

于 2013-03-13T16:25:55.057 に答える
0

問題の 1 つは、tmpfile()がファイル ハンドルを返すのに対し、filesizeはファイル名をパラメーターとして受け取ることです。
次の行:

header('Content-Length: ' . filesize($tmp));

おそらく次のように評価されます。

header('Content-Length: 0');

出力が発生する前に、header() へのすべての呼び出しが実行されることを確認します。

于 2013-03-13T16:35:55.223 に答える