Я пытаюсь получить уникальные идентификаторы для экземпляров объектов в PHP 5 +.
Функция, spl_object_hash()
доступно от PHP 5.2, но я задаюсь вопросом, существует ли обходное решение для более старых версий PHP.
Существует несколько функций в комментариях к php.net, но они не работают на меня. (Упрощенное) первое:
function spl_object_hash($object){
if (is_object($object)){
return md5((string)$object);
}
return null;
}
не работает с собственными объектами (такими как DOMDocument), и второе:
function spl_object_hash($object){
if (is_object($object)){
ob_start();
var_dump($object);
$dump = ob_get_contents();
ob_end_clean();
if (preg_match('/^object\(([a-z0-9_]+)\)\#(\d)+/i', $dump, $match)) {
return md5($match[1] . $match[2]);
}
}
return null;
}
похож на него, мог быть крупный уничтожитель производительности!
У кого-либо есть что-нибудь их рукавом?
Я провел несколько быстрых тестов. Я действительно думаю, что вам лучше хранить настоящие обратные вызовы в своей функции bind (), используя bind ('evt_name', array ($ obj, 'callback_function'))
. Если вы абсолютно хотите пойти по маршруту spl_object_hash, а не хранить ссылки с привязками событий, вы увидите что-то вроде этого:
Реализация var_dump / extract и hash id:
function spl_object_hash_var_dump($object){
if (is_object($object)){
ob_start();
var_dump($object);
$dump = ob_get_contents();
ob_end_clean();
if (preg_match('/^object\(([a-z0-9_]+)\)\#(\d)+/i', $dump, $match)) {
return md5($match[1] . $match[2]);
}
}
return null;
}
Простая реализация ссылок:
function spl_object_dumb_references(&$object) {
static $hashes;
if (!isset($hashes)) $hashes = array();
// find existing instance
foreach ($hashes as $hash => $o) {
if ($object === $o) return $hash;
}
$hash = md5(uniqid());
while (array_key_exists($hash, $hashes)) {
$hash = md5(uniqid());
}
$hashes[$hash] = $object;
return $hash;
}
По сути, эта функция была в 5-50 раз хуже, чем классовая справочная функция по всем направлениям, так что не стоит о ней беспокоиться.
Ссылки на хранилище по реализации класса:
function spl_object_hash_references(&$object) {
static $hashes;
if (!isset($hashes)) $hashes = array();
$class_name = get_class($object);
if (!array_key_exists($class_name, $hashes)) {
$hashes[$class_name] = array();
}
// find existing instance
foreach ($hashes[$class_name] as $hash => $o) {
if ($object === $o) return $hash;
}
$hash = md5(uniqid($class_name));
while (array_key_exists($hash, $hashes[$class_name])) {
$hash = md5(uniqid($class_name));
}
$hashes[$class_name][$hash] = $object;
return $hash;
}
И вы получите результатов, которые выглядят так . Резюме: реализация ссылок на основе классов лучше всего работает около n / 50 классов - в лучшем случае ей удается достичь 1/3 производительности реализации на основе var_dump
, а обычно намного хуже.
Реализация var_dump
кажется приемлемой, хотя и не идеальной. Но если вы не выполняете слишком много таких поисков, это не будет для вас узким местом. Особенно в качестве запасного варианта для PHP <5.2 boxen.