2

メールファイルからファイルを取り除いた後、base 64 エンコードでサーバーのハードドライブにファイルを保存するシステムがあります。

ファイルを元の形式に再度変更したいのですが、php でそれを行うにはどうすればよいですか?

これは私がファイルを保存しようとした方法ですが、有効なファイルを作成していないようです:

$start = $part['starting-pos-body'];
$end = $part['ending-pos-body'];
$len = $end-$start;
$written = 0;
$write = 2028;
$body = '';
while ($start <= $end) {
 fseek($this->stream, $start, SEEK_SET);
 $my = fread($this->stream, $write);
 fwrite($temp_fp, base64_decode($my));
 $start += $write;
}
fclose($temp_fp);
4

3 に答える 3

3

@traylz は、失敗すべきではないのに失敗する理由を明確にしています。ただし、base64_decode()大きな画像でも失敗する場合があります。私は 6 ~ 7 MB のファイルを問題なく扱ってきましたが、このサイズを超えていないので、次のように単純なはずです。

$dir = dirname(__FILE__);
// get the base64 encoded file and decode it
$o_en = file_get_contents($dir . '/base64.txt');
$d = base64_decode($o_en);

// put decoded string into tmp file
file_put_contents($dir . '/base64_d', $d);

// get mime type (note: mime_content_type() is deprecated in favour
// for fileinfo functions)
$mime = str_replace('image/', '.', mime_content_type($dir . '/base64_d'));
rename($dir . '/base64_d', $dir . '/base64_d' . $mime);

chunk_split()以下が失敗した場合は、関数をデコード操作に追加してみてください。

$d = base64_decode(chunk_split($o_en));

だから私は何を言っているのですか...必要がない限りループを忘れてください...phpのmime検出を信頼しない場合は、元のファイル拡張子を保持してください。大きなファイルで作業する場合は、操作で使用chunk_split()します。base64_decode()

注:すべての理論はテストされていません

編集:ほとんどの場合フリーズする可能性が高い大きなファイルのfile_get_contents()場合、必要なものを読み取り、ファイルに出力するため、RAM はほとんど使用されません:

$chunkSize = 1024;
$src = fopen('base64.txt', 'rb');
$dst = fopen('binary.mime', 'wb');
while (!feof($src)) {
    fwrite($dst, base64_decode(fread($src, $chunkSize)));
}
于 2013-10-22T07:44:42.087 に答える
1

あなたの問題は、2028 チャンクを読み取り、チャンクを読み取った後に start<=end をチェックすることです。そのため、エンド ポインターを超えて読み取るため、<= の代わりに <= をチェックする必要があります (0 バイトの読み取りを避けるため)

また、 fread は現在の位置から読み取るため、反復ごとに fseek する必要はありません。ループから fssek を取り出すことができます(whileの前)。なぜ2028なのですか? これを試してください:

fseek($this->stream, $start, SEEK_SET);
while ($start < $end) {
    $write = min($end-$start,2048);
    $my = fread($this->stream, $write);
    fwrite($temp_fp, base64_decode($my));
    $start += $write;
}
fclose($temp_fp);
于 2013-10-22T07:07:53.267 に答える