在PHP中获取对象的实例ID

Ali*_*xel 28 php resources class object instance

我刚才在StackOverflow上学到了我们可以得到任何资源的"实例ID",例如:

var_dump(intval(curl_init()));  // int(2)
var_dump(intval(finfo_open())); // int(3)
var_dump(intval(curl_init()));  // int(4)
var_dump(intval(finfo_open())); // int(5)
var_dump(intval(curl_init()));  // int(6)
Run Code Online (Sandbox Code Playgroud)

我需要类似的东西,但适用于类:

class foo {
    public function __construct() {
        ob_start();
        var_dump($this); // object(foo)#INSTANCE_ID (0) { }
        echo preg_replace('~.+#(\d+).+~s', '$1', ob_get_clean());
    }
}

$foo = new foo();  // 1
$foo2 = new foo(); // 2
Run Code Online (Sandbox Code Playgroud)

上面的工作,但我希望更快的解决方案,或至少,一个不涉及输出缓冲区.请注意,这不一定在构造函数中使用,甚至不必在类本身内部使用!

spl_object_hash() 不是我想要的,因为这两个对象产生相同的哈希

以前的问题包含一个错误的spl_object_hash输出示例; 确保两个对象同时存在会产生稍微不同的哈希:

var_dump(spl_object_hash($foo));  // 0000000079e5f3b60000000042b31773
var_dump(spl_object_hash($foo2)); // 0000000079e5f3b50000000042b31773
Run Code Online (Sandbox Code Playgroud)

像资源一样转换为int似乎不适用于对象:

注意:类foo的对象无法转换为int.

有没有使用对象属性快速获取相同输出的方法

此外var_dump(),我通过反复试验发现debug_zval_dump()也输出了对象实例,遗憾的是它还需要输出缓冲,因为它不会返回结果.

Ste*_*rig 34

spl_object_hash()可以帮到你.它

返回对象的唯一标识符

对于给定的实例,它总是相同的.

OP评论后编辑:

您可以使用静态类属性实现此类行为,例如:

class MyClass 
{
    private static $_initialized = false;

    public function __construct()
    {
        if (!self::$_initialized) {
            self::$_initialized = true;
            // your run-only-once code 
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但实际上这对你原来的问题没有任何意义.

  • 请注意,来自`spl_object_hash`文档:"当一个对象被销毁时,它的哈希可以重用于其他对象." 我遇到过这种情况,这使得某些目的无用. (10认同)

Art*_*cto 19

嗯,是的,扩展名.

请注意,可以重用用于同时销毁的对象的句柄.

用.构建 phpize && ./configure && make && make install

testext.h

#ifndef PHP_EXTTEST_H
# define PHP_EXTTEST_H
# ifdef HAVE_CONFIG_H
#  include<config.h>
# endif
# include <php.h>
extern zend_module_entry testext_module_entry;
#define phpext_testext_ptr &testext_module_entry
#endif
Run Code Online (Sandbox Code Playgroud)

testext.c

#include "testext.h"

PHP_FUNCTION(get_object_id)
{
    zval *obj;
    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &obj)
            == FAILURE) {
        return;
    }

    RETURN_LONG(Z_OBJ_HANDLE_P(obj));
}

static zend_function_entry ext_functions[] = {
    PHP_FE(get_object_id, NULL)
    {NULL, NULL, NULL, 0, 0}
};

zend_module_entry testext_module_entry = {
    STANDARD_MODULE_HEADER,
    "testext",
    ext_functions, /* Functions */
    NULL, /* MINIT */
    NULL, /* MSHUTDOWN */
    NULL, /* RINIT */
    NULL, /* RSHUTDOWN */
    NULL, /* MINFO */
    NO_VERSION_YET,
    STANDARD_MODULE_PROPERTIES
};

ZEND_GET_MODULE(testext)
Run Code Online (Sandbox Code Playgroud)

config.m4中

PHP_ARG_ENABLE(testext,
  [Whether to enable the "testext" extension],
  [  enable-testext         Enable "testext" extension support])

if test $PHP_EXTTEST != "no"; then
  PHP_SUBST(EXTTEST_SHARED_LIBADD)
  PHP_NEW_EXTENSION(testext, testext.c, $ext_shared)
fi
Run Code Online (Sandbox Code Playgroud)

测试脚本

<?php
$a = new stdclass();
$b = new stdclass();
var_dump(get_object_id($a));
var_dump(get_object_id($b));
Run Code Online (Sandbox Code Playgroud)

产量

int(1)
int(2)