sha1_file

Calculates the SHA-1 digest of a file's contents without loading the whole file into memory.

Signature
sha1_file(string $filename, bool $binary = false): string|false
  • Added in PHP 4.3.0

Parameters

ParameterTypeDescription
$filenamestringPath of the file to hash. Supports fopen() stream wrappers.
$binaryoptionalbool= falseWhen true, returns the digest as 20 raw bytes instead of 40 hexits.

Return value

string|falseThe 40-character hexadecimal digest, the raw 20-byte digest when binary is true, or false on failure.

Errors

Does not throw. Returns false and emits an E_WARNING when the file cannot be read.

sha1_file() streams a file through SHA-1 and returns a 160-bit digest of its contents. Like md5_file(), it reads in chunks, so memory use does not scale with file size.

When to reach for it

Reach for it when a protocol or vendor works in SHA-1: checksum lists distributed as .sha1 files, Git-adjacent tooling, and older asset pipelines. For your own integrity checks hash_file('sha256', ...) is the better default, and hash_file('xxh3', ...) is dramatically faster when you only need a fingerprint.

What trips people up

The return type is string|false and there is no exception on failure — a missing or unreadable file gives false plus an E_WARNING. Test with === false so the failure is explicit.

The digest is 40 characters, not 32. Storing it in a column sized for MD5 truncates it silently, and truncated SHA-1 values collide far more often than developers expect.

The hash also covers contents only. Two files with different names, owners and timestamps but identical bytes produce the same digest, and a file whose metadata changed produces the same digest as before. If you need to notice metadata changes, hash the metadata alongside the content yourself.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Verify a release archive against a vendor-published .sha1 checksum file.
  • Build a content-addressed cache where the digest becomes the stored filename.
  • Compare two large files for equality without reading both into memory.

Frequently asked questions

What is the difference between sha1_file and hash_file('sha1', ...)?

Nothing in the result — hash_file() is the generic form that also accepts sha256, xxh3 and every other name from hash_algos(). Prefer hash_file() when the algorithm might change.

Why does sha1_file return false?

The file is missing, is a directory, or the PHP process lacks read permission. An E_WARNING is raised alongside the false return, so check the result with === false.

Is sha1_file safe for verifying downloads?

Not against a deliberate attacker, since SHA-1 chosen-prefix collisions are practical. Use hash_file('sha256', ...) when the file could have been substituted on purpose.

More examples

Comparing two large files without loading them

Equality is decided from two 40-character digests rather than by reading 10 KB (or 10 GB) into memory twice. The approach scales to files far larger than memory_limit.

Example · php
<?php
file_put_contents('left.bin',  str_repeat('AB', 5000));
file_put_contents('right.bin', str_repeat('AB', 5000));
file_put_contents('other.bin', str_repeat('AC', 5000));

var_dump(sha1_file('left.bin') === sha1_file('right.bin'));
var_dump(sha1_file('left.bin') === sha1_file('other.bin'));
echo sha1_file('left.bin'), PHP_EOL;

array_map('unlink', ['left.bin', 'right.bin', 'other.bin']);

Content-addressed storage

The file is renamed to its own digest, so re-uploading identical content lands on the same path and needs no second copy. The final check confirms the stored file still hashes to the name it was given.

Example · php
<?php
$body = "report contents\n";
file_put_contents('upload.tmp', $body);

$digest = sha1_file('upload.tmp');
$stored = substr($digest, 0, 2) . '-' . substr($digest, 2) . '.blob';
rename('upload.tmp', $stored);

echo $stored, PHP_EOL;
var_dump(sha1_file($stored) === $digest);
unlink($stored);

Discussion

  • Be the first to comment on this lesson.