In PHP, the hash_final function is a tool used to complete an incremental hash context and return the final hash value. It is usually used in conjunction with functions such as hash_init , hash_update , etc., to handle hash calculations of large data or streaming data. However, many developers will encounter some common problems when using hash_final . This article will analyze these problems in detail and provide solutions.
The definition of hash_final is as follows:
string hash_final ( HashContext $context [, bool $raw_output = FALSE ] )
$context : hash context created by hash_init .
$raw_output : If set to true , output raw binary data; otherwise, output lowercase hexadecimal string.
Simple example:
$context = hash_init('sha256');
hash_update($context, 'hello');
$finalHash = hash_final($context);
echo $finalHash;
Phenomenon:
Once hash_final is called, the associated $context becomes invalid. If you try to use the same context again, for example:
$context = hash_init('sha256');
hash_update($context, 'hello');
$final1 = hash_final($context);
$final2 = hash_final($context); // mistake!
Will cause a warning or an error.
Solution:
If you need to reuse the context, call hash_copy before hash_final :
$context = hash_init('sha256');
hash_update($context, 'hello');
$contextCopy = hash_copy($context);
$final1 = hash_final($context);
$final2 = hash_final($contextCopy);
Phenomenon:
Many people only take string output by default, ignoring that $raw_output = true actually returns binary. If you use echo to output directly, you will get garbled code:
$context = hash_init('sha256');
hash_update($context, 'hello');
$final = hash_final($context, true);
echo $final; // Garbage codes may be displayed
Solution:
To display readable content, you can use bin2hex or base64_encode :
$final = hash_final($context, true);
echo bin2hex($final);
Phenomenon:
When using hash for large files or big data streams, using hash() directly consumes a lot of memory:
$hash = hash('sha256', file_get_contents('largefile.dat'));
Solution:
Use hash_init + hash_update to stream:
$context = hash_init('sha256');
$handle = fopen('largefile.dat', 'rb');
while (!feof($handle)) {
$data = fread($handle, 8192);
hash_update($context, $data);
}
fclose($handle);
$finalHash = hash_final($context);
Phenomenon:
The same input data is inconsistent with the hash values calculated in PHP in other languages (such as Python, Node.js).
Solution:
make sure:
The input encoding is consistent (UTF-8 vs UTF-16).
Whether there are additional line breaks or spaces.
Computed the same way (original vs encoded text).
Example: Calculate the SHA-256 hash of a UTF-8 encoded string using PHP:
$context = hash_init('sha256');
hash_update($context, mb_convert_encoding($input, 'UTF-8'));
$finalHash = hash_final($context);
Phenomenon:
When hash verification of the URL, normalization is ignored, resulting in different hashes for the same address:
$url1 = 'https://gitbox.net/page';
$url2 = 'https://gitbox.net/page/';
Solution:
Normalize the URL before calculation, for example:
function normalizeUrl($url) {
$parsed = parse_url($url);
$scheme = $parsed['scheme'] ?? 'http';
$host = $parsed['host'] ?? '';
$path = rtrim($parsed['path'] ?? '/', '/');
return "$scheme://$host$path";
}
$context = hash_init('sha256');
hash_update($context, normalizeUrl('https://gitbox.net/page/'));
$finalHash = hash_final($context);