I have an array of objects and I'm trying to see, through each request, whether or not a new member appeared in my collection.
The way I currently do it is, I require each member of the collection to implement an IdentifiableInterface
that must return a string with an unique handle for each object, as such:
interface IdentifiableInterface
{
public function getUniqueObjectIdentifier(): string;
}
And I compute the collection's identity by md5'ing the strings:
$array = getCollectionOfObjects();
$identity = '';
foreach( $array as $array_item ) {
$identity .= $array_item->getUniqueObjectIdentifier();
}
return md5( $identity );
Issues:
- If two objects have the same unique identifier and are therefore the same, the system will detect that a new member was added (since it'll generate a new md5 string) when, technically, it wasn't.
- I can't know whether or not my string is truly unique. The identity is an md5 hash where the order of the input strings matters for the output.
- Tied to point 2), I can't go back to check if an item was added in the past so that, if it actually was, I'd pick another handler for the new one.
- I can't just simply store each collection member's ID, maybe. I'm trying to avoid looping unecessarily over hundreds of items, dozens of times in a request.
I've chosen this approach initially due to the fact that in PHP ReflectionClass
is costly and inspecting each class deeply just doesn't work when talking about hundreds of objects (for which case I developed this system specifically).
What I am trying to achieve by computing this identity is to not re-run the same heavy operations on 200-300 objects and just retrieve the output of these operations from the database.
As such, I'm looking for a hashing method that allows me to also unpack it easily.
h
, for which some mixing functionh(a) + h(b) = h(a+b)
existed, and with and inverse subtractionh(a+b) - h(b) = h(a)
. That way, you don't recompute the hashes for everything, but only mix in and pull out hashes of elements being added/removed