php - 替代 Stream_Copy_To_Stream() php

标签 php memory upload stream copy

我现在正在一个文件共享网站上工作,遇到了一个小问题。我使用的是上传文件 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 是我能看到的上传文件的第一个实例

最佳答案

如果你尝试像这样分块读取文件,你会得到更好的结果吗?:

$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);

关于php - 替代 Stream_Copy_To_Stream() php,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11679723/

相关文章:

c - 在 OS X 中读取其他进程的内存?

memory - CPU物理地址空间如何映射到物理DRAM?

PHP-FFMpeg 允许多个输入

php - 强制 Composer 更新包

php - 重定向但仍继续处理 exec()

php - 成功响应时显示 div

ios - MKMapSnapshotter WatchKit 内存错误

php - 在 Symfony2 中上传多个文件?

PHP 扩展上传进度 - 返回负总字节数和剩余时间

django - 如何使用 Dropbox 作为 Django 媒体文件存储?