Возобновление контекста хеширования файла без сохранения состояния
Короче вопрос
Как можно "возобновить hash_context" в PHP?
Фон и текущая ситуация
Цель программного обеспечения - получить большой кусок файла по частям (синхронно), рассчитать как MD5, так и SHA1 этого файла и сгенерировать ссылку для загрузки (полного файла). Что-то вроде Rapidshare, но вместо того, чтобы отправлять файл полностью, отправка фрагмента файла по фрагменту.
В настоящее время программное обеспечение работает с этой логикой:
Он получает куски файлов (10 МБ кусков большого файла) синхронно за файловую сессию. После получения всех фрагментов мне нужно вычислить MD5 и SHA1 для файла, который занимает очень много времени для файлов размером более 1 ГБ.
Псевдокод для финализатора файла (когда все чанки получены):
$fileKey = $_GET['KEY'];
$ctxMd5 = hash_init('md5');
$ctxSha1 = hash_init('sha1');
$fh = fopen('file/containing/all_chunks.tmp', 'r');
while(!feof($fh)) {
$data = fread($fh, CHUNK_SIZE);
hash_update($ctxMd5, $data);
hash_update($ctxSha1, $data);
}
$md5 = hash_final($ctxMd5);
$sha1= hash_final($ctxSha1);
saveFileHashes($fileKey, $md5, $sha1);
Проблема в том, что, когда все фрагменты загружены, пользователь должен ждать, пока скрипт вычислит оба хэша, что очень расстраивает.
Решение проблемы
Я хотел бы изменить логику приема следующим образом:
Вместо вычисления хешей, когда все чанки получены и сохранены, я хотел бы возобновить или создать новый контекст хеширования, увеличить контекст, сохранить состояние контекста хеширования и сохранить файловый чанк, когда каждый чанк получен.
Псевдокод для чанкового получателя:
$chunkData = getIncommingChunkData();
$fileKey = $_GET['KEY'];
$ctxMd5 = resumeMd5HasingContext($fileKey);
$ctxSha1 = resumeSha1HasingContext($fileKey);
hash_update($ctxMd5, $chunkData);
hash_update($ctxSha1, $chunkData);
saveMd5HashingContext($fileKey, $ctxMd5)
saveSha1HashingContext($fileKey, $ctxSha1)
appendFileChunk($fileKey, $chunkData);
Эта проблема
Основная проблема заключается в том, что ресурсы PHP не сериализуемы, а также hash_init не обеспечивает способ возобновления контекста.
Хотелось бы узнать, как добиться всего изложенного выше?
1 ответ
Просто идея решить проблему: возможно, вам следует отделить процесс приема от процесса конкатенации / хеширования.
Когда вы инициализируете передачу, ваш сценарий может запустить постоянный сценарий, который выполняется в фоновом режиме, ожидает фрагменты, вычисляет хэши для каждого фрагмента, которые становятся доступными, добавляет их в файл и завершает работу, когда все фрагменты получены, все в одиночное исполнение.
Ваш сценарий приема просто переместит загруженные файлы чанка во временный каталог, чтобы сделать их доступными для постоянного процесса.