spl_object_hash为PHP <5.2(对于对象实例唯一ID)
题
我试图获取对象实例唯一ID在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;
}
不与原生对象的工作(如DOM文档),并且第二:
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('evt_name', array($obj, 'callback_function'))
在bind()函数存储真正的回调。如果你绝对想要去的spl_object_hash路线,而不是存储与事件绑定的引用,你看是这样的:
:一种的var_dump /提取物和散列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-50x差,所以这是不值得担心。
:一种存储参考文献通过类实现:强>
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
实现的性能,并且它通常是多的糟糕<。 / p>
在var_dump
实施似乎是可以容忍的,但效果并不理想。但是,如果你没有做太多这类的查找,它不会成为你的瓶颈。特别是作为PHP <5.2 Boxen有
其他提示
我曾经写过一个辅助函数为WordPress每对象提供了一个独特的哈希值,它与一个柜台和专卖店每仿佛它已分配给对象的公共类属性的哈希值。下面的例子说明这样:
/**
* get object hash
*
* Returns a unique hash per object.
*
* Proxy function for wordpress installments on servers
* with a PHP version < 5.2.0.
*
* @since 3.0.2
* @note Become deprecated with version 3.2.0 (PHP 5.2 requirements)
* @param object $object
* @return string unique object hash
*/
function wp_object_hash( &$object ) {
static $prefix, $count = 0, $property = '__wphookobjhash__', $spl_function_exists;
isset( $spl_function_exists ) || $spl_function_exists = function_exists( 'spl_object_hash' );
// prefer spl_object_hash if available
if ( $spl_function_exists )
return spl_object_hash( $object );
// validate input
if ( !is_object( $object ) ) {
trigger_error( __FUNCTION__ . '() expects parameter 1 to be object', E_USER_WARNING );
return null;
}
// setup prefix and counter to generate object hash, set it to object if not set
isset( $prefix ) || ( ( $prefix = uniqid( '' ) ) && $property .= $prefix . '__' );
isset( $object->$property ) || ( $object->$property = sprintf( '%s-%08d', $prefix , ++$count ) );
return $object->$property;
}
如果您使用的是PHP 5的版本,则不需要通过引用传递参数。
这是你想要的。
我已经修复了一个非常可能的错误和精简从 bobthecow答案中的功能(其也从PHP借来的。净)这样:
if ( !function_exists( 'spl_object_hash' ) ) {
function spl_object_hash( $object )
{
ob_start();
var_dump( $object );
preg_match( '[#(\d+)]', ob_get_clean(), $match );
return $match[1];
}
}
它返回一个整数(通常在低于100范围),这对于任何对象唯一的(见此答案一>有关你看到的细节)。
P.S。我用在真实的场景该实现的此处