當前位置: 首頁> 最新文章列表> PHP hash_final 與hash_update 一起使用時的注意事項

PHP hash_final 與hash_update 一起使用時的注意事項

gitbox 2025-05-20

在PHP 中處理哈希運算時, hash_init()hash_update()hash_final()這組函數是一個非常強大的組合。它們提供了一種流式(分段)計算哈希值的方式,適合處理大文件或分塊數據,比一次性用hash()函數更高效。

本文將詳細講解如何正確配合使用hash_update()hash_final() ,並指出其中需要注意的事項。

基本用法

這三個函數的基本流程如下:

  1. 初始化哈希上下文:

     $context = hash_init('sha256');
    
  2. 多次更新數據:

     hash_update($context, '部分數據1');
    hash_update($context, '部分數據2');
    
  3. 獲取最終哈希值:

     $hash = hash_final($context);
    

完整例子:

 <?php
$context = hash_init('sha256');

hash_update($context, 'Hello ');
hash_update($context, 'World!');

$finalHash = hash_final($context);

echo "最終哈希值: " . $finalHash;
?>

注意事項

1?? hash_final()調用後上下文不可再用

當你調用了:

 $hash = hash_final($context);

上下文$context被銷毀了,不能再用它繼續調用hash_update()hash_final() ,否則會報錯。

如果你想在同一個數據流上繼續算其他哈希,你需要重新調用hash_init()

2??使用hash_copy()做分支

如果你需要在同一個上下文的基礎上得到多個分支結果,可以用hash_copy()

 $context = hash_init('sha256');
hash_update($context, '部分數據');

$copy = hash_copy($context);

hash_update($context, '後續A');
$hashA = hash_final($context);

hash_update($copy, '後續B');
$hashB = hash_final($copy);

這樣$hashA$hashB就是不同分支的結果。

3??處理大文件時按塊更新

對於大文件,可以分塊讀取並調用hash_update()

 <?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 "大文件哈希值: " . $finalHash;
?>

這樣避免了一次性讀取文件帶來的內存壓力。

4?? URL 場景下的使用

如果你是通過HTTP 請求流式處理數據,比如:

 <?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 "遠程文件哈希值: " . $finalHash;
} else {
    echo "無法打開 URL。";
}
?>

要注意:確保allow_url_fopenphp.ini中是啟用的,否則fopen()無法直接打開URL。

5??選擇合適的算法

hash_init()的第一個參數是算法名,推薦使用sha256sha512等現代算法,而不是老舊的md5sha1 ,因為後者已不安全。