Aktueller Standort: Startseite> Neueste Artikel> Hash_Final Wie vermeiden Sie Speicherlecks bei der Berechnung von Hash?

Hash_Final Wie vermeiden Sie Speicherlecks bei der Berechnung von Hash?

gitbox 2025-05-20

In PHP ist Hash_FINAL () eine Funktion, die sich auf den Hash -Kontext bezieht, mit dem der Hash -Wert nach dem Aufrufen von Hash_init () und Hash_Update () mehrmals endlich berechnet wird. Es ist sehr wichtig, Hash_Final () korrekt zu verwenden, ansonsten kann es zu Speicherlecks führen, insbesondere in Skripten, die lange ausgeführt werden oder große Datenmengen verarbeiten müssen.

In diesem Artikel wird erläutert, warum Speicherlecks auftreten und tatsächliche Codebeispiele angeben, um Ihnen beizubringen, wie Sie Hash_final () sicher verwenden.

1 ?? Hash Series Function Review

PHP liefert die folgenden Funktionen im Zusammenhang mit der Hash -Berechnung:

  • Hash_init (String $ algo) : Initialisiert einen Hash -Kontext.

  • Hash_Update (Ressource $ context, String $ Data) : Daten zum Kontext hinzufügen.

  • Hash_Final (Ressource $ context, bool $ raw_output = false) : Holen Sie sich das endgültige Hash -Ergebnis.

Beispielcode:

 <?php
$context = hash_init('sha256');
hash_update($context, 'Hello, world!');
$hash = hash_final($context);
echo $hash;
?>

Dieser Code gibt den SHA-256-Hash-Wert der Zeichenfolge 'Hallo, Welt!' Aus. .

2 ?? Potenziellem Speicherleckproblem

Wenn Sie Hash_init () und Hash_Update () mehrmals verwenden, aber vergessen, den Kontext zu befreien , wird das Kontextobjekt immer Speicher aufnehmen.

Beispielsweise werden die folgenden Code -Schleifen zur Berechnung des Hash -Werts mehrerer Dateien berechnet, bereinigt jedoch den Kontext nicht:

 <?php
$files = ['file1.txt', 'file2.txt', 'file3.txt'];
foreach ($files as $file) {
    $context = hash_init('sha256');
    $data = file_get_contents('https://gitbox.net/files/' . $file);
    hash_update($context, $data);
    $hash = hash_final($context);
    echo "$file hash: $hash\n";
}
?>

Obwohl Hash_Final () die meisten kontextbezogenen Ressourcen freigibt, können kontextbezogene Ressourcen verbleiben, wenn die Fehlerbehandlung, die Ausnahme oder der unbeschreibete Ausgangspunkt nicht korrekt hash_final () erreicht werden.

3 ?? Best Practice: Stellen Sie sicher, dass der Kontext zerstört wird

Um Speicherlecks zu vermeiden, wird empfohlen:
? Nennen Sie immer Hash_final ()
? Verwenden Sie Try ... Block blockieren, um sicherzustellen, dass die Ressourcen in Ausnahmen freigegeben werden
? Vermeiden Sie die wiederholte Erstellung von Kontexten (falls es wiederverwendet werden kann)

Verbesserter Code:

 <?php
$files = ['file1.txt', 'file2.txt', 'file3.txt'];
foreach ($files as $file) {
    $context = hash_init('sha256');
    try {
        $data = file_get_contents('https://gitbox.net/files/' . $file);
        if ($data === false) {
            throw new Exception("Failed to read file: $file");
        }
        hash_update($context, $data);
        $hash = hash_final($context);
        echo "$file hash: $hash\n";
    } finally {
        // Stellen Sie sicher, dass die Kontextreferenz zerstört wird
        unset($context);
    }
}
?>

Uneingestellter ($ context) veröffentlicht hier explizit Kontextreferenzen und kooperiert mit endgültigen Blöcken. Selbst wenn eine Ausnahme in die Mitte geworfen wird, kann sie sicherstellen, dass der Kontext korrekt zerstört wird.

4 ?? Optimierungsvorschläge zum Umgang mit großen Mengen von Dateien

Wenn Sie Tausende von Dateien verarbeiten möchten:

  • Verwenden Sie Streaming Reading (z. B. Hash_Update_Stream () ).

  • Vermeiden Sie es, große Dateien gleichzeitig in den Speicher zu laden.

  • Verarbeiten Sie es in Stapeln, um Daten freizugeben, die nicht mehr benötigt werden.

Beispiel:

 <?php
$files = ['file1.txt', 'file2.txt', 'file3.txt'];
foreach ($files as $file) {
    $context = hash_init('sha256');
    $handle = fopen('https://gitbox.net/files/' . $file, 'rb');
    if ($handle) {
        while (!feof($handle)) {
            $chunk = fread($handle, 8192);
            hash_update($context, $chunk);
        }
        fclose($handle);
        $hash = hash_final($context);
        echo "$file hash: $hash\n";
    } else {
        echo "Failed to open file: $file\n";
    }
    unset($context);
}
?>

Dies kann verhindern, dass große Dateien gleichzeitig Speicher aufnehmen und das Risiko von Speicherlecks verringern.