php에서 hash_final ()은 해시 컨텍스트와 관련된 함수이며, 이는 Hash_init () 및 hash_update ()를 여러 번 호출 한 후 해시 값을 계산하는 데 사용됩니다. hash_final ()을 올바르게 사용하는 것이 매우 중요합니다. 그렇지 않으면 메모리 누출, 특히 오랫동안 실행되거나 많은 양의 데이터를 처리 해야하는 스크립트에서 메모리 누출로 이어질 수 있습니다.
이 기사에서는 메모리 누출이 발생하는 이유를 설명하고 실제 코드 예제를 제공하여 Hash_Final ()를 안전하게 사용하는 방법을 가르쳐줍니다.
PHP는 해시 계산과 관련된 다음 기능을 제공합니다.
hash_init (String $ algo) : 해시 컨텍스트를 초기화합니다.
hash_update (Resource $ 컨텍스트, 문자열 $ data) : 컨텍스트에 데이터를 추가하십시오.
hash_final (resource $ context, bool $ raw_output = false) : 최종 해시 결과를 얻습니다.
샘플 코드 :
<?php
$context = hash_init('sha256');
hash_update($context, 'Hello, world!');
$hash = hash_final($context);
echo $hash;
?>
이 코드는 문자열 'Hello, World!' 의 SHA-256 해시 값을 출력합니다. .
hash_init () 및 hash_update ()를 여러 번 사용하지만 컨텍스트를 제거하는 것을 잊어 버리면 컨텍스트 객체는 항상 메모리를 차지합니다.
예를 들어, 다음 코드는 여러 파일의 해시 값을 계산하기 위해 고리하지만 컨텍스트를 정리하지는 않습니다.
<?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";
}
?>
Hash_Final () 이 호출 될 때 대부분의 컨텍스트 관련 리소스를 출시하지만 오류 처리, 예외 또는 고려되지 않은 종료 지점이 Hash_Final ()에 올바르게 도달하지 못하면 상황 관련 자원이 유지 될 수 있습니다.
메모리 누출을 피하려면 다음과 같이 권장됩니다.
? 항상 hash_final () 호출
? 사용 시도 ... 마침내 블록을 차단하여 리소스가 예외적으로 릴리스되도록합니다.
? 컨텍스트의 반복적 인 생성을 피하십시오 (재사용 할 수있는 경우)
개선 된 코드 :
<?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 {
// 컨텍스트 참조가 파괴되었는지 확인하십시오
unset($context);
}
}
?>
Unset ($ context)는 여기에서 컨텍스트 참조를 명시 적으로 출시하고 마지막으로 블록과 협력합니다. 중간에 예외가 발생하더라도 컨텍스트가 올바르게 파괴되도록 할 수 있습니다.
수천 개의 파일을 처리하려면 다음과 같습니다.
스트리밍 읽기를 사용하십시오 (예 : hash_update_stream () ).
큰 파일을 한 번에 메모리에로드하지 마십시오.
배치로 처리하여 더 이상 필요하지 않은 데이터를 해제하십시오.
예:
<?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);
}
?>
이렇게하면 큰 파일이 한 번에 메모리를 차지하지 못하고 메모리 누출 위험이 줄어 듭니다.