Skip to content

Commit 9d0377e

Browse files
committed
Attachment content hash added
1 parent 25fa1a0 commit 9d0377e

File tree

1 file changed

+32
-12
lines changed

1 file changed

+32
-12
lines changed

src/Attachment.php

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
* @property string type
2929
* @property string content_type
3030
* @property string id
31+
* @property string hash
3132
* @property string name
3233
* @property string description
3334
* @property string filename
@@ -44,6 +45,8 @@
4445
* @method string setContentType(string $content_type)
4546
* @method string getId()
4647
* @method string setId(string $id)
48+
* @method string getHash()
49+
* @method string setHash(string $hash)
4750
* @method string getSize()
4851
* @method string setSize(integer $size)
4952
* @method string getName()
@@ -74,17 +77,18 @@ class Attachment {
7477
* @var array $attributes
7578
*/
7679
protected array $attributes = [
77-
'content' => null,
78-
'type' => null,
79-
'part_number' => 0,
80+
'content' => null,
81+
'hash' => null,
82+
'type' => null,
83+
'part_number' => 0,
8084
'content_type' => null,
81-
'id' => null,
82-
'name' => null,
83-
'filename' => null,
84-
'description' => null,
85-
'disposition' => null,
86-
'img_src' => null,
87-
'size' => null,
85+
'id' => null,
86+
'name' => null,
87+
'filename' => null,
88+
'description' => null,
89+
'disposition' => null,
90+
'img_src' => null,
91+
'size' => null,
8892
];
8993

9094
/**
@@ -203,10 +207,26 @@ protected function fetch(): void {
203207
$this->content_type = $this->part->content_type;
204208
$this->content = $this->oMessage->decodeString($content, $this->part->encoding);
205209

210+
// Create a hash of the raw part - this can be used to identify the attachment in the message context. However,
211+
// it is not guaranteed to be unique and collisions are possible.
212+
// Some additional online resources:
213+
// - https://en.wikipedia.org/wiki/Hash_collision
214+
// - https://www.php.net/manual/en/function.hash.php
215+
// - https://php.watch/articles/php-hash-benchmark
216+
// Benchmark speeds:
217+
// -xxh3 ~15.19(GB/s) (requires php-xxhash extension or >= php8.1)
218+
// -crc32c ~14.12(GB/s)
219+
// -sha256 ~0.25(GB/s)
220+
// xxh3 would be nice to use, because of its extra speed and 32 instead of 8 bytes, but it is not compatible with
221+
// php < 8.1. crc32c is the next fastest and is compatible with php >= 5.1. sha256 is the slowest, but is compatible
222+
// with php >= 5.1 and is the most likely to be unique. crc32c is the best compromise between speed and uniqueness.
223+
// Unique enough for our purposes, but not so slow that it could be a bottleneck.
224+
$this->hash = hash("crc32c", $this->part->getHeader()->raw."\r\n\r\n".$this->part->content);
225+
206226
if (($id = $this->part->id) !== null) {
207227
$this->id = str_replace(['<', '>'], '', $id);
208-
}else{
209-
$this->id = hash("sha256", uniqid((string) rand(10000, 99999), true));
228+
}else {
229+
$this->id = $this->hash;
210230
}
211231

212232
$this->size = $this->part->bytes;

0 commit comments

Comments
 (0)