替代Stream_Copy_To_Stream()php [英] Alternative to Stream_Copy_To_Stream() php

查看:59
本文介绍了替代Stream_Copy_To_Stream()php的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在一个文件共享站点上工作,但遇到了一个小问题.我正在使用可以正常工作的上载单据uploadify,但是如果用户希望我希望对上载的文件进行加密.现在,我有执行此操作的代码,如下所示,但是我的服务器只有1GB或内存,并且使用stream_copy_to_stream似乎占用了内存中实际文件的大小,并且我的最大上载大小为256,所以我知道一个糟糕的事实网站上线并且多个人一次上传大文件时,这种情况就会发生.根据我下面的代码,几乎没有使用和内存的替代方案,甚至根本没有,我什至不在乎是否需要更长的时间,我只需要这样做即可.我有此版本的下载版本,因为我将文件直接解密并立即传递到浏览器,因此它在下载时解密,虽然我的效率很高,但此上传问题看起来并不理想.感谢您的帮助.

I am working on a file sharing site right now and I've run into a small problem. I am using the upload scrip uploadify which works perfectly but if the user wants i want the uploaded file to be encrypted. Now i have working code that does this as shown below but my server only has 1GB or memory and using stream_copy_to_stream seems to take up the size of the actually file in memory and my max upload size is 256 so i know for a fact that something bad is going to happen when the site goes live and multiple people upload large files at once. Based on my code below is there any alternative that barely uses and memory or none at all, I wouldnt even care if it takes longer i just need this to work. I have the download version of this working because i have the file directly decrypted and immediately passed through to the browser so it decrypts as it downloads which i though was pretty efficient but this upload problem doesn't look to good. Any help is appreciated.

$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是我可以看到的上载文件的第一个实例

temp_file is the first instance that i can see of the uploaded file

推荐答案

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

Do you have better results if you try reading the file in chunks like this?:

$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_copy_to_stream 之前先调用 stream_set_chunk_size .code>设置复制到目标时用于从源流读取的缓冲区的大小.

You might also try calling stream_set_chunk_size prior to calling stream_copy_to_stream to set the size of the buffer it uses to read from the source stream when copying to the destination.

希望有帮助.

我使用此代码进行了测试,并且上传700MB的电影文件时,PHP的峰值内存使用量为524,288字节.看起来 stream_copy_to_stream 会尝试将整个源文件读取到内存中,除非您通过传递length和offset参数的块将其读取.

I tested with this code and when uploading a 700MB movie file, the peak memory usage of PHP is 524,288 bytes. It looks like stream_copy_to_stream will try to read the entire source file into memory unless you read it in chunks passing the length and offset arguments.

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

这篇关于替代Stream_Copy_To_Stream()php的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆