calculate an unique id from an array/class
Asked Answered
S

3

10

I use a data class to feed templates my data, I want to calculate a unique id from the data in the data class so I can check if the template with that data is already in cache and then serve that version.

so a function to get an unique id from an array of a class would help me out.

something like this works but is rather costly md5(serialize($classdata))

I'm hoping there is some function to get the unique id without serializing all data, or at least not to have to in php.

edit:
I celebrated too soon, the unique id is only the same in the current instance a restart of the same script makes another id, which then of course is not in cache.

testscript used:

<?php
class foo {}
$f = new foo;
print spl_object_hash($f);

I'll explain in some more depth

class template_data implements IteratorAggregate, ArrayAccess, Countable {
    
    private $_data;
    
    //some methods for the overloaded classes
    //
    
    //the getId function
    public function getId() {
        return hash('md5',serialize($this->_data));
    }
    
}

$t = new template('file');
$d = new template_data('some data');
$t->addData($d);
$t->display();

Now if the data given to the template engine is in cache it uses that version preventing to having to re-parse the template for the dataset.

This is a simplistic view of the template_data, it is actually lazy loading and uses memcached dataid's so the data isn't actually fetched till it is used in the template.

Sicyon answered 19/1, 2011 at 10:8 Comment(0)
C
5

You could try spl_object_hash()

From the docs

This function returns a unique identifier for the object. This id can be used as a hash key for storing objects or for identifying an object.

Craps answered 19/1, 2011 at 10:13 Comment(2)
ok so after some testing the object hash is different every instance of php, so if i reload the page a few times i get a new unique hash every time, i need the hashes to remain the same across multiple php instances/page refreshesSicyon
spl_object_hash() will generate a unique hash for the object compared to other objects in current memory, not across the board. And even then, when an object is destroyed, its hash may be reused for other objectsReticule
T
2

PHP does not create unique IDs that persist between executions for objects, this means that you are going about producing the desired behavior correctly. So while there is no good answer for the asked question I can give some suggestions to reduce the cost of producing your IDs.

First you can use json_encode rather than serialize. Second, you can store the value, so that multiple calls to the function will not re-serialize the data every time.

The json_encode function is not only faster than serialize, but it also produces a shorter string as output.

http://cw-internetdienste.de/2015/05/04/serialize-vs-json_encode/

class template_data implements IteratorAggregate, ArrayAccess, Countable {

    private $_data;
    private $_id;

    //
    //some methods for the overloaded classes
    //

    //the getId function
    public function getId() {
        if(empty($this->_id))
            $this->_id = hash('md5',json_encode($this->_data));

        return $this->_id;
    }
}

Lastly; the best solution will probably be to cache the output of the template using the route, or arguments as the basis for the unique cache keys rather than the individual data sets used.

Thereby answered 22/2, 2016 at 4:2 Comment(0)
C
1

Why not look into and overriding the __toString() method on the object to get and hash the relevant data in the object.

For example

class Object
{
    // Some vars
    public $name = "Jake";
    public $age = 26;
    public $dob = "1/1/10"

    // the toString method
    public function __toString()
    {
         return md5($this->name . $this->age . $this->dob);
    }
}

// Create new object
$object = new Object();

// echo the object, this automatically calls your __toString method
echo $object

In this situation you don't use serialize, which is costly, instead just use __toString() to generate your own unique id based on variables stored with the object.

Craps answered 19/1, 2011 at 21:24 Comment(5)
this is what i use now hash('md5',serialize($this->_data)) from inside the class over the stored data, but its a rather costly operation to do so over recordsets, especially if they contain hundrets of records. I was looking for something more low lv for the gain in speedSicyon
the classdata i need serialized is in a datacontainer class, wich gets usually the query results from the db, it has an internal array the $_data wish stores the data, i can iterate the array and merge it to one string, and then md5 that but thats slower than serialize, i use a public method getId() instead of casting the object to string wich is the __toString method for, not to mention the $_data array can contain nested array, wich in your example should be recursively added together to one big string to perform the md5 over, that making the array to string part is the slow partSicyon
I think maybe we need to strip this back to the original issue. Why do you need a unique ID for an object which is maintained between PHP instances/requests?Craps
to be able to tell if the template parsed with the data is in cache, the template key used is <filename>|<filemtime>|<lifetime>|<dataid>Sicyon
added some more details to my post, but i still just need to have an unique id of an array, seems so simple doesnt it ^^ alas i cant find howSicyon

© 2022 - 2024 — McMap. All rights reserved.