Get Instance ID of an Object in PHP

I’ve learn a while ago on StackOverflow that we can get the “instance ID” of any resource, for instance:

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)

I need something similar but applied to classes:

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

The above works but I was hoping for a faster solution or, at least, one that didn’t involve output buffers. Please note that this won’t necessarily be used within the constructor or even inside the class itself!

spl_object_hash() is not what I’m looking for because the two objects produce identical hashes:

var_dump(spl_object_hash($foo));  // 000000005111e639000000003a87b42e
var_dump(spl_object_hash($foo2)); // 000000005111e639000000003a87b42e

Casting to int like resources doesn’t seem to work for objects:

Notice: Object of class foo could not be converted to int.

Is there a quick way to grab the same output without using object properties?

Besides var_dump(), I’ve discovered by trial and error that debug_zval_dump() also outputs the object instance, unfortunately it also needs output buffering since it doesn’t return the result.

To the down voters: explain your reasons or, if you think this is a basic question, suggest a solution.

How to get instance ID with PHP

I’m looking for a way to get the instance ID of a given object / resource with PHP, the same way var_dump() does: var_dump(curl_init()); // resource #1 of type curl var_dump(curl_init()); // resource

Client Object Model Sharepoint How to get the Instance ID

So In my sharepoint site contents page i have an application. Can anyone tell me how to get the instance id of it. so that i can invoke the link : http://testingwebcompany.sharepoint.com/_layouts/15/a

Get Amazon EC2 Instance ID via PHP

I’m looking to create a PHP script that will echo the unique ID of an Amazon EC2 instance. Anyone know how to do this? Found a way via command line: http://af-design.com/blog/2010/07/27/testing-your-a

Access object members from Instance ID

I’m getting the Instance ID of an object from collision_line() Now that I have this instance, I want to get it’s image_angle, but I get an ‘unknown variable’ message when I try that. What should I do?

Get php file from instance of object [duplicate]

This question already has an answer here: Finding the PHP File (at run time) where a Class was Defined 2 answers Is it possible in PHP to get the file location of an object? The object is an in

Get instance by instance-id

I need to get the instance by instance-id, is it possible to do it without requesting a list of all instances? I’ve tried: ec2_conn = boto.connect_ec2(aws_access_key_id=key, aws_secret_access_key=acce

PHP get index of object [duplicate]

Possible Duplicate: Get Instance ID of an Object in PHP I’m new to OOP and I have an object. If I: var_dump($obj); I get: object(stdClass)[55] public ‘date’ => int 1295297161 public ‘id’ => i

PHP Instance object with path

I’m trying to create an instance of an object with a path like(C:/wamp/www…) In a new project I have this method, and I try with that to instance an object of an another project. public function get

PHP OOP save instance of object in instance or only the id?

I am a little bit confused how to implement the following OO structure in PHP. I have a class ‘User’ and a class ‘UserGroup’ a ‘User’ is part of one ‘UserGroup’. In the database the user table has a f

php object within object, getting the top level object instance

I am experimenting with PHP OOP what i’m trying to find out is, Is it possible to access a object instance from withing a object that was created in this object instance? sounds confusing, so here is

Answers

Have a look at spl_object_hash(). Usage example:

$id = spl_object_hash($object);

Note that you’ll need PHP 5 >= 5.2.0 for that to work.

spl_object_hash() could help you out here. It

returns a unique identifier for the object

which is always the same for a given instance.

EDIT after OP comment:

You could implement such a behavior using a static class property, e.g:

class MyClass 
{
    private static $_initialized = false;

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

But actually this has nothing to with your original question.

I don’t have the PECL runkit enabled to test this, but this may allow you to remove the constructor code from the class definition after the first time that an instance of the class has been created.

Whether you can remove the constructor from within the constructor would be an interesting experiment.

Well, yes, with an extension.

Note that the handles used for objects that were, in the meantime, destroyed, can be reused.

Build with 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

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)

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

Test script

<?php
$a = new stdclass();
$b = new stdclass();
var_dump(get_object_id($a));
var_dump(get_object_id($b));

Output

int(1)
int(2)

If you don’t want to use output buffering… perhaps use var_export instead of var_dump?

As long as you implement the base class all the classes you’re going to need this from, you can do something like this:

class MyBase
{
    protected static $instances = 0;
    private $_instanceId  = null;
    public function getInstanceId()
    {
        return $this->_instanceId;
    }

    public function __construct()
    {
        $this->_instanceId = ++self::$instances;
    }
}

class MyTest extends MyBase
{
    public function Foo()
    {
        /* do something really nifty */
    }
}

$a = new MyBase();
$b = new MyBase();

$c = new MyTest();
$d = new MyTest();


printf("%d (should be 1) /n", $a->getInstanceId());
printf("%d (should be 2) /n", $b->getInstanceId());
printf("%d (should be 3) /n", $c->getInstanceId());
printf("%d (should be 4) /n", $d->getInstanceId());

The output would be:

1 (should be 1) 
2 (should be 2) 
3 (should be 3) 
4 (should be 4) 

What you’re trying to do, is actually Aspect-Oriented Programming (AOP).

There are at least a couple of frameworks available for AOP in PHP at this point:

  • seasar (formerly PHPaspect) is a larger framework integrating with Eclipse – the screenshot shows you a little code snippet that answers your question, weaving some code around a particular new statement throughout a project.
  • php-aop is a lightweight framework for AOP.
  • typo3 has an AOP framework built in.

This may be overkill for your needs, but you may find that exploring the kind of thinking behind ideas like these will lead you down the rabbithole, and teach you new ways to think about software development in general – AOP is a powerful concept, allowing you to program in terms of strategies and concerns, or “aspects”.

Languages like PHP were designed to solve programming tasks – the concept of APO was designed to solve a programmer’s tasks. When normally you would need to think about how to ensure that a particular concern gets fulfilled every time in your codebase, you can think of this as simply an “aspect” of how you’re programming, implement it in those terms directly, and count on your concerns to be implemented every time.

It requires less discipline, and you can focus on solving the practical programming tasks rather than trying to architect your way through high-level structural code requirements.

Might be worth 5 minutes of your time, anyway 😉

Good luck!

Alix, your solution in the question was exactly what I needed, but actually breaks when there’s an object in an object, returns the last # in the var_dump. I fixed this, made the regex faster, and put it in a nice little function.

/**
 * Get global object ID
 * From: http://stackoverflow.com/questions/2872366/get-instance-id-of-an-object-in-php
 * By: Alix Axel, non-greedy fix by Nate Ferrero
 */
function get_object_id(&$obj) {
    if(!is_object($obj))
        return false;
    ob_start();
    var_dump($obj);// object(foo)#INSTANCE_ID (0) { }
    preg_match('~^.+?#(/d+)~s', ob_get_clean(), $oid);
    return $oid[1]; 
}

This is a bit late to the party but I didn’t see this answer and just recently implemented something similar for a debugging class ( to handle circular references). As you guys may or may not know the normal printing functions such as var_export, have limited or no circular reference support.

As noted the spl_object_hash is unique per instance, the problem I had with it is that it is ugly. Not really suited to printing for my debugger as it’s something like this 000000006ac56bae0000000044fda36f which can be hard to compare to say this 000000006ac56bae0000000044fda35f. So like the OP stated what I wanted was just a number of the instance ( I only really needed this on a per class basis ).

Therefor the simple solution for me was to do the following.

    $class = get_class( $input );
    $hash = spl_object_hash( $input );
    if( !isset( $objInstances[ $class ] )){
        $objInstances[ $class ] = array();
    }

    $output = 'object(%s) #%s (%s){%s}'; //class, instance, prop_count, props
    if( false === ( $index = array_search($hash, $objInstances[ $class ] ) ) ){
        $index = count($objInstances[ $class ]); //set init index for instance
        $objInstances[ $class ][] = $hash;
        // .... debugging code
        $output = 'debugging result.', //sprintf 
    }else{
        $output = sprintf( $output, $class, $index, 0, '#_CIRCULAR_REFRENCE_#');
    }

Obviously the debugging code is way more complex, but the essential thing here is that by tracking the class and spl hash in $objInstances I can easily assign my own instance numbers outside of the class. This means I don’t need some ugly hack ( that affects the class’s code ) to get a reference number. Also, I don’t need to display the “ugly” spl hash. Anyway my full code for this outputs something like this.

$obj = new TestObj();
$obj1 = new TestObj();

$obj->setProProp($obj1);
$obj1->setProProp($obj); //create a circular reference 

object(TestObj) #0 (7){
    ["SOME_CONST":const] => string(10) 'some_const',
    ["SOMEOTHER_CONST":const] => string(16) 'some_other_const',
    ["SOME_STATIC":public static] => string(6) 'static',
    ["_PRO_STATIC":protected static] => string(10) 'pro_static',
    ["someProp":public] => string(8) 'someProp',
    ["_pro_prop":protected] => object(TestObj) #1 (7){
        ["SOME_CONST":const] => string(10) 'some_const',
        ["SOMEOTHER_CONST":const] => string(16) 'some_other_const',
        ["SOME_STATIC":public static] => string(6) 'static',
        ["_PRO_STATIC":protected static] => string(10) 'pro_static',
        ["someProp":public] => string(8) 'someProp',
        ["_pro_prop":protected] => object(TestObj) #0 (0){#_CIRCULAR_REFRENCE_#},
        ["_proProp":protected] => string(7) 'proProp'
    },
    ["_proProp":protected] => string(7) 'proProp'
}

As you can see it’s very easy to see where object(TestObj) #0 (0){#_CIRCULAR_REFRENCE_#} came from now. I wanted to keep this debugging code as close to the native var_dump which outputs this.

object(TestObj)#7 (3) {
  ["someProp"]=> string(8) "someProp"
  ["_pro_prop":protected]=> object(TestObj)#10 (3) {
    ["someProp"]=> string(8) "someProp"
    ["_pro_prop":protected]=> *RECURSION*
    ["_proProp":protected]=> string(7) "proProp"
  }
  ["_proProp":protected]=> string(7) "proProp"
}

The difference here is I needed the return as a string, not output to the browser. I also wanted to be able to show class constants, static properties, and private properties ( with flags to change what the debugger outputs, and the depth limit). And, I wanted a bit more information as to what the circular reference was instead of just *RECURSION* which doesn’t tell me anything.

Hope it helps someone in the future.