Signatur
Beschreibung
hash_copy() dupliziert einen mit hash_init() erzeugten Hash-Kontext vollständig, einschließlich aller bisher über hash_update() eingespiesenen Daten. Das Ergebnis ist ein neues, unabhängiges HashContext-Objekt, dessen Weiterbearbeitung den Original-Kontext nicht beeinflusst.
Typischer Einsatzfall ist das sogenannte Merkle-Damgård-Pattern: Man verarbeitet zunächst einen gemeinsamen Daten-Prefix (z. B. einen Protokoll-Header), kopiert den Kontext und berechnet danach für verschiedene Nachrichten-Suffixe jeweils den finalen Hash – ohne den Prefix erneut hashen zu müssen. Das spart Rechenzeit bei wiederholten Hashing-Vorgängen mit gleichem Anfang.
Beide Kontexte (Original und Kopie) sind nach hash_copy() völlig unabhängig voneinander und können separat mit hash_update(), hash_update_stream() oder hash_final() weiterverwendet werden.
Seit PHP 7.2 ist HashContext ein echtes Objekt; davor war es eine interne Ressource. hash_copy() funktioniert in beiden Varianten korrekt und war die einzige zuverlässige Methode, einen Ressource-Kontext zu duplizieren, da einfaches Kopieren einer Ressource keinen tiefen Klon erzeugte.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $context Pflicht | HashContext | Ein aktiver Hash-Kontext, der zuvor mit hash_init() erzeugt wurde. Der Kontext darf sich in einem beliebigen Zwischenzustand befinden (auch ohne bisher eingespiesene Daten). |
Rückgabewert
HashContext-Objekt zurück, das eine vollständige, unabhängige Kopie des übergebenen Kontexts darstellt – inklusive aller bisher verarbeiteten Daten und des aktuellen internen Zustands.Beispiele
Gemeinsamen Prefix einmal hashen, dann verschiedene Suffixe anhängen
<?php
// Gemeinsamen Prefix vorbereiten
$context = hash_init('sha256');
hash_update($context, 'Gemeinsamer-Prefix:');
// Kontext für zwei verschiedene Nachrichten kopieren
$contextA = hash_copy($context);
$contextB = hash_copy($context);
hash_update($contextA, 'NachrichtA');
hash_update($contextB, 'NachrichtB');
$hashA = hash_final($contextA);
$hashB = hash_final($contextB);
echo 'Hash A: ' . $hashA . PHP_EOL;
echo 'Hash B: ' . $hashB . PHP_EOL;
// Zur Kontrolle: direkter Hash ohne Kontext
$direct = hash('sha256', 'Gemeinsamer-Prefix:NachrichtA');
echo 'Direkt: ' . $direct . PHP_EOL;
echo 'Gleich: ' . ($hashA === $direct ? 'ja' : 'nein') . PHP_EOL;
HMAC-Kontext duplizieren und parallel auswerten
<?php
$secret = 'geheimer-schluessel';
// HMAC-Kontext mit gemeinsamem Datenstück aufbauen
$ctx = hash_init('sha512', HASH_HMAC, $secret);
hash_update($ctx, 'Basis-Payload:');
// Kopie anlegen, bevor sich die Kontexte unterscheiden
$ctx1 = hash_copy($ctx);
$ctx2 = hash_copy($ctx);
hash_update($ctx1, 'Anfrage-1');
hash_update($ctx2, 'Anfrage-2');
$mac1 = hash_final($ctx1);
$mac2 = hash_final($ctx2);
var_dump($mac1 !== $mac2); // true — unterschiedliche MACs
// Wichtig · Fallstricke
Sicherheitshinweis: Das Kopieren eines HMAC-Kontexts ist sicher, solange der geheime Schlüssel niemals direkt exponiert wird. Die Kopie enthält zwar den internen Zustand (inklusive HMAC-Schlüsselverarbeitung), gibt den Schlüssel aber nicht über die PHP-API preis.
Ressourcen vs. Objekte: Vor PHP 7.2 war der Hash-Kontext eine resource. Ein einfaches Zuweisen ($b = $a;) kopierte lediglich den Ressource-Handle, nicht den Zustand. hash_copy() war und ist die einzig korrekte Methode zur Duplizierung.
Kein Rückgabefehler: Die Funktion wirft intern einen ValueError (PHP 8+) oder einen fatalen Fehler (PHP 7), wenn ein ungültiger Kontext übergeben wird. Es gibt keinen false-Rückgabewert – eine Fehlerbehandlung sollte daher per Exception-Handling oder vorheriger Validierung erfolgen.