toString() and Object #ID

php.internals

Lars Schultz

19 years ago
Hi there I just tried to switch from 5.1 to 5.2.3 and got thrown off right away by: "Object of class MyObject could not be converted to string" I googled a bit and also read any Messages in the internals list but couldn't find a decisive answer as to wether this will stay this way or not. In the "PHP 5 Bug Summary Report" I found Bug # 40799 "change string conversion behaviour for objects not implementing __toString()" which is still open. I don't want to complain or anything but I'd like to know wether it's feasible to wait for a change in this current, modified, behaviour or if it's going to stay this way. I used the previous behaviour mostly for debugging purposes where I wanted to get a visual (string) handle for any given object, which helps ALOT when trying to figure out wether one has a copy or the original and wether to references point to the same object....(obj1 === obj2 is not always helpful). Is there any other way than casting an object to a string to get an objects #ID? Thanks for your time. Lars

Evert | Rooftop

19 years ago
Hi Lars, In the meanwhile .. check out spl_object_hash Evert Lars Schultz wrote:

Stanislav Malyshev

19 years ago
> always helpful). Is there any other way than casting an object to a > string to get an objects #ID?
spl_object_hash?
-- Stanislav Malyshev, Zend Software Architect stas@zend.com http://www.zend.com/ (408)253-8829 MSN: stas@zend.com

Pavel Shevaev

19 years ago
On 6/30/07, Stanislav Malyshev <stas@zend.com> wrote:
> > always helpful). Is there any other way than casting an object to a > > string to get an objects #ID? > > spl_object_hash?
Guys, excuse my being a little offtopic here, but why not introduce standard "get_object_id" function in PHP6 which could be analogous to "spl_object_hash"? IMHO it's a basic functionality which deserves to be in the core...
-- Best regards, Pavel

Gwynne Raskind

19 years ago
On Jul 1, 2007, at 3:24 AM, Pavel Shevaev wrote:
>> > always helpful). Is there any other way than casting an object to a >> > string to get an objects #ID? >> >> spl_object_hash? > Guys, excuse my being a little offtopic here, but why not introduce > standard "get_object_id" function in PHP6 which could be analogous to > "spl_object_hash"? IMHO it's a basic functionality which deserves to > be in the core...
+1 on PHP_FEALIAS()ing this. -- Gwynne, Daughter of the Code "This whole world is an asylum for the incurable."

Marcus Börger

19 years ago
Hello Gwynne, no more unnecessary aliases please. marcus Sunday, July 1, 2007, 9:27:25 AM, you wrote:
> On Jul 1, 2007, at 3:24 AM, Pavel Shevaev wrote: >>> > always helpful). Is there any other way than casting an object to a >>> > string to get an objects #ID? >>> >>> spl_object_hash? >> Guys, excuse my being a little offtopic here, but why not introduce >> standard "get_object_id" function in PHP6 which could be analogous to >> "spl_object_hash"? IMHO it's a basic functionality which deserves to >> be in the core...
> +1 on PHP_FEALIAS()ing this.
> -- Gwynne, Daughter of the Code > "This whole world is an asylum for the incurable."
Best regards, Marcus

Sebastian Bergmann

19 years ago
Pavel Shevaev schrieb:
> Guys, excuse my being a little offtopic here, but why not introduce > standard "get_object_id" function in PHP6 which could be analogous to > "spl_object_hash"? IMHO it's a basic functionality which deserves to > be in the core...
SPL is "in the core" AFAIAC.
-- Sebastian Bergmann http://sebastian-bergmann.de/ GnuPG Key: 0xB85B5D69 / 27A7 2B14 09E4 98CD 6277 0E5B 6867 C514 B85B 5D69

Pavel Shevaev

19 years ago
> > SPL is "in the core" AFAIAC.
I really want to hope it will be in PHP6. Still IMHO get_object_id sounds much better than spl_object_hash and it will be much easier(and more logical) to locate this function in "Class/Object Functions" section of documentation than in SPL...
-- Best regards, Pavel

Marcus Börger

19 years ago
Hello Pavel, technically object id is neither what you get nor what you want. It is not unique and thus not helpfull and we have no intention to ever provide a function to access it. See mail archieve for reference on why we won't. Also the function resides in extension SPL so correctly it is prefixed with 'spl_'. Furthermore it is no engine specific function but an object oriented programming specific one. So SPL indeed is a very good place for it. Lastly the function per design hashes the unique input it gives as we do not want to make it more complex than necessary or give you stuff that leads to missuse. Again see mail archive for why. That said the name appears to be the best option already. marcus Sunday, July 1, 2007, 1:42:02 PM, you wrote:
>> >> SPL is "in the core" AFAIAC.
> I really want to hope it will be in PHP6. Still IMHO get_object_id > sounds much better than spl_object_hash and it will be much easier(and > more logical) to locate this function in "Class/Object Functions" > section of documentation than in SPL...
> -- > Best regards, Pavel
Best regards, Marcus

Pavel Shevaev

19 years ago
> Again see mail archive for why. That said the name appears to be > the best option already.
Oh, yes, you're right spl_object_hash does its job and does it very well, there's really no point rename it(or make an alias) into object_get_id. I should have stated more clear what I think object_get_id could actually be. How about object_get_id being a function returning the very first line of var_dump's output being applied to the object? Let me be a bit more specific, here's an example of var_dump usage: $ php -r "class Foo{};$foo = new Foo();var_dump($foo);" object(Foo)#1 (0) { } What I actually need, not the object hash but simply its unique id. And in this case "object(Foo)#1" would be just fine. How can I get it? The only way AFAIK is to surround var_dump with ob_start/ob_get_contents/ob_end_clean functions and extract this value. The problem with approach is if one has a complex object connected with a graph of other complex objects(with recursive links) var_dump may take a _very_ long time to complete. And this is what object_get_id could do - simply return object id prefixed with the class name.
-- Best regards, Pavel

Lars Schultz

19 years ago
> What I actually need, not the object hash but simply its unique id. > And in this case "object(Foo)#1" would be just fine. How can I get it?
That was my original Question too;) It's been stated that the automatic cast into a string even if it does not implement the __toString() function was "absolute nonsense"...but it really helped alot when you needed to check for errors quickly and easily. Why make something harder than it has to be. Why not allow the old behaviour as long as the __toString is not implemented? Or rather something like a default implementation which is used autmatically for every class which doesn't implement it itself? public function __toString(){ return 'Object '. get_class($this) .'('. get_object_id($this) .')'; } That'd be nice and no code breakage would result. Isn't that an approach that fits into the PHP philosophy? The new behaviour reminds me of Java's "the more userland-code, the better".

Sebastian Bergmann

19 years ago
Pavel Shevaev schrieb:
> What I actually need, not the object hash but simply its unique id.
The problem is that there is no such unique id in the current engine.
-- Sebastian Bergmann http://sebastian-bergmann.de/ GnuPG Key: 0xB85B5D69 / 27A7 2B14 09E4 98CD 6277 0E5B 6867 C514 B85B 5D69

Lars Schultz

19 years ago
> The problem is that there is no such unique id in the current engine. >
Okay!;) That's a very good reason, I guess;) Explains a lot. Why not use spl_object_hash instead of the old default behaviour?

Pavel Shevaev

19 years ago
> The problem is that there is no such unique id in the current engine.
Am I right in my guess that there's only a counter for each object type? Still being not really unique this information could be very useful and enough in many situations.
-- Best regards, Pavel

David

19 years ago
(accidentally didn't send this to the whole group at first)
> Am I right in my guess that there's only a counter for each object > type? Still being not really unique this information could be very > useful and enough in many situations.
The "counter" is global, but it's not really a counter. "Object ids" are actually handles (basically indices) into an internal array holding data to all objects currently in memory. Handles are reused when an object is destroyed so that the array could be kept as small as possible. However, if you are comparing the handles of two objects that are known to be currently in memory, if they have the same handle, then they are the same object (i.e. one spot in memory). However, if you stored the handle of the object in another area of memory so that you can check it against other objects later, it's hard to ensure that the results of that comparison is meaningful. Therefore, it's better to use spl_object_hash to actually ensure objects are the same. Internally, the hash is performed on the object handle (what you've been calling the "object id") as well as the internal list of handlers for that object (basically the "type" of the object), so there's reasonable confidence that a unique hash will be generated. It looks like it's independent of the actual properties, etc. of the object. Spl_object_hash is what you guys want. David

Stanislav Malyshev

19 years ago
> Am I right in my guess that there's only a counter for each object > type? Still being not really unique this information could be very > useful and enough in many situations.
It's more complicated than that. Basically what uniquely identifies the object is the tuple (handlers, ID) - it's more or less by definition since handlers decide what to do with an object based on ID. Now, if we talk about "pure" PHP objects (i.e. made by regular PHP user-defined classes, no tricks) then the handlers would be the same and the ID is unique. However, extensions can produce their own handlers and their own IDs, and they don't even have to adhere to the concept that (class, ID) should uniquely identify the object. I don't know of extension that creates different handler sets for the same class, but there's nothing in the engine preventing anybody from doing that - though I'm not sure it's that good an idea. So (class, ID) would probably work now, but is not guaranteed to work. Just ID would have good chance to break with some extensions. Yes, spl_object_hash uses the correct tuple - (handlers, ID).
-- Stanislav Malyshev, Zend Software Architect stas@zend.com http://www.zend.com/ (408)253-8829 MSN: stas@zend.com

Richard Lynch

19 years ago
On Sun, July 1, 2007 2:50 pm, Sebastian Bergmann wrote:
> Pavel Shevaev schrieb: >> What I actually need, not the object hash but simply its unique id. > > The problem is that there is no such unique id in the current engine.
How does PHP internally distinguish it? Surely it has some kind of pointer/address thingie... I don't think a developer CARES what the ID is (or isn't) or what it looks like, so long as it's reasonably short and fast to access, and it's not something that's only available sometimes on some systems.
-- Some people have a "gift" link here. Know what I want? I want you to buy a CD from some indie artist. http://cdbaby.com/browse/from/lynch Yeah, I get a buck. So?

David Zülke

19 years ago
Am 01.07.2007 um 21:18 schrieb Pavel Shevaev:
>> Again see mail archive for why. That said the name appears to be >> the best option already. > > Oh, yes, you're right spl_object_hash does its job and does it very > well, there's really no point rename it(or make an alias) into > object_get_id. I should have stated more clear what I think > object_get_id could actually be.
Not quite. It creates a hash of an object, so two objects with the same data yield the same hashes: var_dump(spl_object_hash(new stdClass()), spl_object_hash(new stdClass ())); - David

Lars Schultz

19 years ago
> Not quite. It creates a hash of an object, so two objects with the > same data yield the same hashes: > > var_dump(spl_object_hash(new stdClass()), spl_object_hash(new > stdClass()));
I don't believe that it's data dependent. Rather in your example the same memory-space is used for those two objects because they don't exist in parallel. The first is cleared before the second is instantiated. <? $x = new stdClass(); $y = new stdClass(); var_dump(spl_object_hash($x), spl_object_hash($y)); ?> This yields a difference.

Pavel Shevaev

19 years ago
> The first is cleared before the second is instantiated.
Oh, that clears everything, please ignore my previous post. Still, don't you think this is a bit misleading? IMHO, new object should always have the unique id(or hash in terms of spl)...
-- Best regards, Pavel

Pavel Shevaev

19 years ago
> Not quite. It creates a hash of an object, so two objects with the > same data yield the same hashes: > > var_dump(spl_object_hash(new stdClass()), spl_object_hash(new stdClass > ()));
Folks, is this really wanted behavior? Because if so, why does the following result in the same hash as well(PHP-5.2.1)? $ php -r "class Foo{};$foo = new Foo();var_dump(spl_object_hash($foo));$foo->bar = 1;var_dump(spl_object_hash($foo));" string(32) "d1f40a1cc04d8c79d09ae6262666adbb" string(32) "d1f40a1cc04d8c79d09ae6262666adbb"
> > - David >
-- Best regards, Pavel

Stephan Schmidt

19 years ago
Hi Pavel, Pavel Shevaev wrote:
> Folks, is this really wanted behavior? Because if so, why does the > following result in the same hash as well(PHP-5.2.1)? > > $ php -r "class Foo{};$foo = new > Foo();var_dump(spl_object_hash($foo));$foo->bar = > 1;var_dump(spl_object_hash($foo));" > > string(32) "d1f40a1cc04d8c79d09ae6262666adbb" > string(32) "d1f40a1cc04d8c79d09ae6262666adbb"
Because you calculate the hash for the same object. It does not matter, that you changed a property, the $foo is still the same object. Best regards, Stephan

Stanislav Malyshev

19 years ago
> Not quite. It creates a hash of an object, so two objects with the same > data yield the same hashes: > > var_dump(spl_object_hash(new stdClass()), spl_object_hash(new stdClass()));
here's the code of spl_object_hash: len = spprintf(&hash, 0, "%p:%d", Z_OBJ_HT_P(obj), Z_OBJ_HANDLE_P(obj)); md5str[0] = '\0'; PHP_MD5Init(&context); PHP_MD5Update(&context, (unsigned char*)hash, len); PHP_MD5Final(digest, &context); make_digest(md5str, digest); RETVAL_STRING(md5str, 1); See any mention of object data? It's not there.
-- Stanislav Malyshev, Zend Software Architect stas@zend.com http://www.zend.com/ (408)253-8829 MSN: stas@zend.com

Richard Lynch

19 years ago
On Sun, July 1, 2007 2:18 pm, Pavel Shevaev wrote:
> $ php -r "class Foo{};$foo = new Foo();var_dump($foo);" > object(Foo)#1 (0) { > } > > What I actually need, not the object hash but simply its unique id.
According to Marcus, it's NOT unique. But I can see that for debugging, it would be very very very useful to have a correctly named function which returns this number, whatever it is, even if it's not an ID.
-- Some people have a "gift" link here. Know what I want? I want you to buy a CD from some indie artist. http://cdbaby.com/browse/from/lynch Yeah, I get a buck. So?

Marcus Börger

19 years ago
Hello Pavel, I still fail to understand why spl_object_hash() does not work for you. How about: function foo($obj) { if (is_object($obj)) { return "object(" . get_class($obj) . ")#" . spl_object_hash($obj); } return NULL; } marcus Sunday, July 1, 2007, 9:18:19 PM, you wrote:
>> Again see mail archive for why. That said the name appears to be >> the best option already.
> Oh, yes, you're right spl_object_hash does its job and does it very > well, there's really no point rename it(or make an alias) into > object_get_id. I should have stated more clear what I think > object_get_id could actually be.
> How about object_get_id being a function returning the very first line > of var_dump's output being applied to the object? Let me be a bit more > specific, here's an example of var_dump usage:
> $ php -r "class Foo{};$foo = new Foo();var_dump($foo);" > object(Foo)#1 (0) { > }
> What I actually need, not the object hash but simply its unique id. > And in this case "object(Foo)#1" would be just fine. How can I get it? > The only way AFAIK is to surround var_dump with > ob_start/ob_get_contents/ob_end_clean functions and extract this > value.
> The problem with approach is if one has a complex object connected > with a graph of other complex objects(with recursive links) var_dump > may take a _very_ long time to complete. > And this is what object_get_id could do - simply return object id > prefixed with the class name.
Best regards, Marcus

Cristian Rodriguez

19 years ago
On 6/29/07, Lars Schultz <schultz@widescreen.ch> wrote:
> Hi there > > I just tried to switch from 5.1 to 5.2.3 and got thrown off right away by: > "Object of class MyObject could not be converted to string" > > I googled a bit and also read any Messages in the internals list but > couldn't find a decisive answer as to wether this will stay this way or not. > > > In the "PHP 5 Bug Summary Report" I found Bug # 40799 > "change string conversion behaviour for objects not implementing > __toString()" > > which is still open. I don't want to complain or anything but I'd like > to know wether it's feasible to wait for a change in this current, > modified, behaviour or if it's going to stay this way.
The old beahviuor was absolute non-sense..
> always helpful). Is there any other way than casting an object to a > string to get an objects #ID? >
use var_dump() or spl_object_hash for that.