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
Hi Lars,
In the meanwhile .. check out spl_object_hash
Evert
Lars Schultz 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.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
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
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
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."
Hello Gwynne,
no more unnecessary aliases please.
marcus
Sunday, July 1, 2007, 9:27:25 AM, you 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
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
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
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
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
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".
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
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
(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
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.
Sure, object identity is not related to properties in any way. Same
object can have different properties during the lifetime, and different
objects can have identical properties. spl_object_hash is unique in the
terms of object identity.
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
Guys thank you all very much for this detailed explanation!
spl_object_hash is unique in the
terms of object identity.
I really don't want to be annoying but from the end user's POV
spl_object_hash sounds like a function which returns a hash but not an
identity. Any tiny chance it will be available as object_get_id in
PHP6? ;)
--
Best regards, Pavel
I really don't want to be annoying but from the end user's POV
spl_object_hash sounds like a function which returns a hash but not an
identity. Any tiny chance it will be available as object_get_id in
PHP6? ;)
It does give the hash, which is unique for each object. In which form
would you expect object_get_id to return object's identity? PHP doesn't
have a type of "tuple of C pointer and long integer" ;)
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
Stanislav Malyshev schrieb:
It does give the hash, which is unique for each object. In which form
would you expect object_get_id to return object's identity? PHP doesn't
have a type of "tuple of C pointer and long integer" ;)
We could add a counter that gets incremented for each object that is
created and associate that number with the object. Wouldn't that solve
the problem (if there is one)?
--
Sebastian Bergmann http://sebastian-bergmann.de/
GnuPG Key: 0xB85B5D69 / 27A7 2B14 09E4 98CD 6277 0E5B 6867 C514 B85B 5D69
We could add a counter that gets incremented for each object that is
created and associate that number with the object. Wouldn't that solve
the problem (if there is one)?
It would solve it, but it would require modifying each extension dealing
with objects in order to register all objects in this global registry
and of course it would require adding another value into object
structure. I'm not sure having running numeric ID is that important.
If you just need to know if two variables are the same object, you have
===. If you need to index by it, you have the hash.
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
Hello all,
and thanks Stas for the explanations.
Monday, July 2, 2007, 7:52:03 PM, you wrote:
We could add a counter that gets incremented for each object that is
created and associate that number with the object. Wouldn't that solve
the problem (if there is one)?
It would solve it, but it would require modifying each extension dealing
with objects in order to register all objects in this global registry
and of course it would require adding another value into object
structure. I'm not sure having running numeric ID is that important.
If you just need to know if two variables are the same object, you have
===. If you need to index by it, you have the hash.
Exactly. And the index should not be dependant on the contents of the
properties. Also you should always use the shortest unique ID. In our case
as very well explained it is handler plus id. What we could do to prevent
two different objects getting the same hash is to ask for the memory
location....but the we cannot use the zval container as multiple zval
containers might point to the same object. Nor can we really use the object
location in its object storage as we do not know if that is safe. Thus we
could only add an independent counter which imo is pretty bad and as
epxplained it would created overly complex overhead.
Now what you actually want with the hash is indexing. That probably means
storing the object in whatever holds the index - maybe an array. Maybe
something else. Either way no other object can get the same hash as the
object is stored and thus no other objetc can get the same handler,id combo
at the same time. So i do not see any issue here. If you guys want it more
complex i suggest you extend the hash in userland and add a special
property/interface solution.
Best regards,
Marcus
(Many apologies for the double e-mail. Ugh, I'm not used to hitting Reply To
All yet)
I really don't want to be annoying but from the end user's POV
spl_object_hash sounds like a function which returns a hash but not
an
identity. Any tiny chance it will be available as object_get_id in
PHP6? ;)It does give the hash, which is unique for each object. In which form
would you expect object_get_id to return object's identity? PHP
doesn't have a type of "tuple of C pointer and long integer" ;)
Hmm. I think what Pavel is asking is just to make it clearer in the
documentation what spl_object_hash's purpose and workings are, and perhaps
make an alias to it named object_get_id so other people don't run into this
confusion in the future.
The name of spl_object_hash and the fact it is in the SPL and not in the
engine does lead one to believe that it might do more than simply hashing
the handler table and handle tuple. People might think it hashes the
properties as well.
David
Hmm. I think what Pavel is asking is just to make it clearer in the
documentation what spl_object_hash's purpose and workings are, and perhaps
make an alias to it named object_get_id so other people don't run into this
confusion in the future.The name of spl_object_hash and the fact it is in the SPL and not in the
engine does lead one to believe that it might do more than simply hashing
the handler table and handle tuple. People might think it hashes the
properties as well.
Exactly, this is what I wanted to say, thanks ;)
David
--
Best regards, Pavel
(Many apologies for the double e-mail. Ugh, I'm not used to hitting Reply To
All yet)I really don't want to be annoying but from the end user's POV
spl_object_hash sounds like a function which returns a hash but not
an
identity. Any tiny chance it will be available as object_get_id in
PHP6? ;)It does give the hash, which is unique for each object. In which form
would you expect object_get_id to return object's identity? PHP
doesn't have a type of "tuple of C pointer and long integer" ;)Hmm. I think what Pavel is asking is just to make it clearer in the
documentation what spl_object_hash's purpose and workings are
That's fine, the docu team would gladly accept any help and patches.
and perhaps
make an alias to it named object_get_id so other people don't run into this
confusion in the future.
I'd like to avoid creating misleading aliases, which would not be usable on a shared
hosting in the next 10 years anyway.
The name of spl_object_hash and the fact it is in the SPL and not in the
engine does lead one to believe that it might do more than simply hashing
the handler table and handle tuple. People might think it hashes the
properties as well.
People won't think anything like that if we fix the documentation, so let's do it.
--
Wbr,
Antony Dovgal
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
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 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?
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
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.
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
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)...
I don't like it either;) But it does exactly what Stanislav Malyshev
described: it hashes the "tuple of C pointer". Misleading in this case
is that this is only unique as long as the compared objects exist at the
same time...then they can't inhabit the same memory-space. But because
php clears and reuses memory as soon as no pointers to the object exist
(reference counting). In this case php uses the exact same "tuple of
C pointer" for the next object as the for the previous one. At
least...that's my interpretation of this behaviour;)
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)...
That's a valid point, reusing IDs might be not a good idea. Not reusing
them though might not help either - you have only so much IDs in long,
so eventually it might happen that IDs from two objects that existed at
different time coincide. spl_object_hash guarantees that no two hashes
of two simultaneously existing objects are the same, but it would be
very hard to guarantee that no objects that ever existed have the same
hash.
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
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
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
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
$ 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?
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
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.