When processing hash operations in PHP, the set of functions hash_init() , hash_update() and hash_final() are a very powerful combination. They provide a streaming (segmented) way to calculate hash values, which is suitable for processing large files or chunked data, and is more efficient than using the hash() function at one time.
This article will explain in detail how to correctly use hash_update() and hash_final() , and point out the things to be paid attention to.
The basic process of these three functions is as follows:
Initialize the hash context:
$context = hash_init('sha256');
Updated data multiple times:
hash_update($context, 'Part of the data1');
hash_update($context, 'Part of the data2');
Get the final hash value:
$hash = hash_final($context);
Complete example:
<?php
$context = hash_init('sha256');
hash_update($context, 'Hello ');
hash_update($context, 'World!');
$finalHash = hash_final($context);
echo "Final hash value: " . $finalHash;
?>
1?? The context cannot be used again after hash_final() is called
When you call:
$hash = hash_final($context);
The context $context is destroyed , and you can no longer use it to continue calling hash_update() or hash_final() , otherwise an error will be reported.
If you want to continue counting other hashes on the same data stream, you need to call hash_init() again.
2?? Use hash_copy() as a branch
If you need to get multiple branch results based on the same context, you can use hash_copy() :
$context = hash_init('sha256');
hash_update($context, 'Part of the data');
$copy = hash_copy($context);
hash_update($context, 'SubsequentA');
$hashA = hash_final($context);
hash_update($copy, 'SubsequentB');
$hashB = hash_final($copy);
In this way, $hashA and $hashB are the results of different branches.
3?? Update by block when processing large files
For large files, you can read and call hash_update() in chunks:
<?php
$context = hash_init('sha256');
$handle = fopen('largefile.bin', 'rb');
while (!feof($handle)) {
$chunk = fread($handle, 8192);
hash_update($context, $chunk);
}
fclose($handle);
$finalHash = hash_final($context);
echo "Large file hash value: " . $finalHash;
?>
This avoids the memory pressure caused by reading files at one time.
4?? Use in URL scenarios
If you are streaming data via HTTP request, for example:
<?php
$url = 'https://gitbox.net/sample-file.bin';
$context = hash_init('sha256');
$handle = fopen($url, 'rb');
if ($handle) {
while (!feof($handle)) {
$chunk = fread($handle, 8192);
hash_update($context, $chunk);
}
fclose($handle);
$finalHash = hash_final($context);
echo "Remote file hash value: " . $finalHash;
} else {
echo "Unable to open URL。";
}
?>
Be careful: Make sure that allow_url_fopen is enabled in php.ini , otherwise fopen() cannot open the URL directly.
5?? Choose the right algorithm
The first parameter of hash_init() is the algorithm name. It is recommended to use modern algorithms such as sha256 and sha512 instead of old md5 or sha1 , because the latter is no longer safe.