7

私は現在、ファイル共有サイトで作業していて、小さな問題に遭遇しました。私は完全に機能するアップロード スクリプト uploadify を使用していますが、ユーザーが望む場合は、アップロードされたファイルを暗号化する必要があります。現在、以下に示すようにこれを行う作業コードがありますが、サーバーには1GBまたはメモリしかなく、stream_copy_to_streamを使用するとメモリ内の実際のファイルのサイズが占有されるようで、最大アップロードサイズは256なので、何か悪いことがあるという事実を知っていますサイトが稼働し、複数の人が一度に大きなファイルをアップロードしたときに発生します。以下の私のコードに基づいて、メモリをほとんど使用しない、またはまったく使用しない代替手段があります。ファイルを直接復号化してすぐにブラウザに渡したので、これのダウンロードバージョンが機能しているため、ダウンロード時に復号化されますが、これはかなり効率的でしたが、このアップロードの問題はうまくいきません。どんな助けでも大歓迎です。

$temp_file = $_FILES['Filedata']['tmp_name'];
    $ext = pathinfo($_FILES['Filedata']['name'], PATHINFO_EXTENSION);
    $new_file_name = md5(uniqid(rand(), true));
    $target_file = rtrim(enc_target_path, '/') . '/' . $new_file_name . '.enc.' . $ext;

    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
    $key = substr(md5('some_salt' . $password, true) . md5($password . 'more_salt', true), 0, 24);
    $opts = array('iv' => $iv, 'key' => $key);

    $my_file = fopen($temp_file, 'rb');

    $encrypted_file_name = $target_file;
    $encrypted_file = fopen($encrypted_file_name, 'wb');

    stream_filter_append($encrypted_file, 'mcrypt.rijndael_128', STREAM_FILTER_WRITE, $opts);
    stream_copy_to_stream($my_file, $encrypted_file);

    fclose($encrypted_file);
    fclose($my_file);
    unlink($temp_file);

temp_file は、アップロードされたファイルを確認できる最初のインスタンスです

4

1 に答える 1

6

このようにファイルをチャンクで読み取ろうとすると、より良い結果が得られますか?:

$my_file = fopen($temp_file, 'rb');

$encrypted_file_name = $target_file;
$encrypted_file = fopen($encrypted_file_name, 'wb');

stream_filter_append($encrypted_file, 'mcrypt.rijndael_128', STREAM_FILTER_WRITE, $opts);
//stream_copy_to_stream($my_file, $encrypted_file);

rewind($my_file);

while (!feof($my_file)) {
    fwrite($encrypted_file, fread($my_file, 4096));
}

また、呼び出しstream_set_chunk_size前に呼び出しstream_copy_to_streamて、宛先にコピーするときにソースストリームから読み取るために使用するバッファーのサイズを設定することもできます。

お役に立てば幸いです。

編集:私はこのコードでテストし、700MBのムービーファイルをアップロードするとき、PHPのピークメモリ使用量は524,288バイトです。stream_copy_to_stream長さとオフセットの引数を渡してチャンクで読み取らない限り、ソースファイル全体をメモリに読み込もうとするようです。

$encrypted_file_name = $target_file;
$encrypted_file = fopen($encrypted_file_name, 'wb');

stream_filter_append($encrypted_file, 'mcrypt.rijndael_128', STREAM_FILTER_WRITE, $opts);

$size = 16777216;  // buffer size of copy
$pos  = 0;         // initial file position

fseek($my_file, 0, SEEK_END);
$length = ftell($my_file);    // get file size

while ($pos < $length) {
    $writ = stream_copy_to_stream($my_file, $encrypted_file, $size, $pos);
    $pos += $writ;
}

fclose($encrypted_file);
fclose($my_file);
unlink($temp_file);
于 2012-07-27T00:09:36.980 に答える