1

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.

5
  • Unrelated, but you're committing two grave sins: using MD5 (it's completely broken, and should be entirely erased from our minds, except to warn against it), and using string concatenation as a form of hash mixing.
    – Alexander
    Sep 8, 2019 at 22:27
  • This would work great if there was a hash function h, for which some mixing function h(a) + h(b) = h(a+b) existed, and with and inverse subtraction h(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
    – Alexander
    Sep 8, 2019 at 22:28
  • 1
    @Alexander Do understand, this is not for security reasons, I'm just using MD5 as a facilitator for an unique string. Yes, that would work great, but...what should I look for that does that?
    – coolpasta
    Sep 9, 2019 at 3:59
  • I don't know, otherwise I would have answered your question. :)
    – Alexander
    Sep 9, 2019 at 4:40
  • "this is not for security reasons, I'm just using MD5 as a facilitator for an unique string" Don't do that. Even using it for something as mundane sounding as a Hash Table's hash function leaves you susceptible to Denial-of-Service attacks. Bet you didn't know that. And neither did I, which is why I think it's good for people like us to defer to the opinions of security experts, which quite unanimously say that MD5 needs to fall off the face of the earth.
    – Alexander
    Sep 9, 2019 at 4:42

1 Answer 1

1

You are doing this to avoid heavy operations. So once the heavy operation is done, can you set a flag on that object say $this->heavyOperationDone = true?

In your loop on objects, you can check this flag and do the heavy operation accordingly.

You can have another factory / object that manages the array of objects keyed by getUniqueObjectIdentifier. In this holder-object you can have a method getUnprocessedObjects() which will give you definite list of objects which are pending heavy operations.

You may try to have globally unique identifier by com-create-guid

1
  • This is actually what I ended up doing after wrangling with the code for so long. The one, exceptionally efficient way to do this is get all the object identifiers and compute the hash using the LtHash algorithm but there's no implementation in PHp as of yet. LtHash allows you to compute a hash based on strings and unpack it to get the original strings.
    – coolpasta
    Sep 25, 2019 at 18:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.