Missing __toString() part

php.internals

Marcus Boerger

20 years ago
Hello guys, the attached patch closes one more __toString() part. It allows to use objects that define __toString as indexes to arrays. What do you guys think about this, should we add it or stay with the old behavior that didn't allow objects as indexes at all.
-- Best regards, Marcus mailto:mail@marcus-boerger.de

Pierre Joye

20 years ago
Hi, On 6/3/06, Marcus Boerger <mail@marcus-boerger.de> wrote:
> Hello guys, > > the attached patch closes one more __toString() part. It allows > to use objects that define __toString as indexes to arrays. What do > you guys think about this, should we add it or stay with the old > behavior that didn't allow objects as indexes at all.
$arr[new Test] = 'abc'; makes very little sense to me, as well as $a = new Test; $arr[$a] = 'abc'; Do we really want to support that? --Pierre

Marcus Börger

20 years ago
Hello Pierre, ever thought that we use tests to check special behavior and that those snippets have little to do with real applications? Obviously not. The idea behind is that for instance you might use an array as a translation and use an object to *calculate* the index. Saturday, June 3, 2006, 2:40:29 PM, you wrote:
> Hi,
> On 6/3/06, Marcus Boerger <mail@marcus-boerger.de> wrote: >> Hello guys, >> >> the attached patch closes one more __toString() part. It allows >> to use objects that define __toString as indexes to arrays. What do >> you guys think about this, should we add it or stay with the old >> behavior that didn't allow objects as indexes at all.
> $arr[new Test] = 'abc';
> makes very little sense to me, as well as
> $a = new Test; $arr[$a] = 'abc';
> Do we really want to support that?
> --Pierre
Best regards, Marcus

Pierre Joye

20 years ago
On 6/3/06, Marcus Boerger <helly@php.net> wrote:
> Hello Pierre, > > ever thought that we use tests to check special behavior and that > those snippets have little to do with real applications? Obviously > not. The idea behind is that for instance you might use an array as > a translation and use an object to *calculate* the index.
I understood that. The "magic" behind __toString was my point. However adding it could help to be consistent with the other magic operations... --Pierre

Robert Amos

20 years ago
Hi, Is it really worth enabling a whole new area where problems could occur just for this? Can you provide an example of where it might actually be considered useful and not just being lazy? -Rob On 6/3/06, Marcus Boerger <helly@php.net> wrote:
> Hello Pierre, > > ever thought that we use tests to check special behavior and that > those snippets have little to do with real applications? Obviously > not. The idea behind is that for instance you might use an array as > a translation and use an object to *calculate* the index. > > Saturday, June 3, 2006, 2:40:29 PM, you wrote: > > > Hi, > > > On 6/3/06, Marcus Boerger <mail@marcus-boerger.de> wrote: > >> Hello guys, > >> > >> the attached patch closes one more __toString() part. It allows > >> to use objects that define __toString as indexes to arrays. What do > >> you guys think about this, should we add it or stay with the old > >> behavior that didn't allow objects as indexes at all. > > > $arr[new Test] = 'abc'; > > > makes very little sense to me, as well as > > > $a = new Test; $arr[$a] = 'abc'; > > > Do we really want to support that? > > > --Pierre > > > > Best regards, > Marcus > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > >
-- Xnyo - http://xnyo.odynia.org/

Marcus Börger

20 years ago
Hello Robert, well lazy is a good point here but __toString is all about lazyness. Then again as said you might want to have objects naturally convert to strings whereever possible. Generally when providing a __toString implementation you say that you want this. And then you might as well expect that your objects can be used as index to arrays. The example is as said an object that can be used to calculate the index to an array. Assuming you deal with persons derived from a database as classes, your person objects might be implmeneted so that __toString simply returns the name of the persons. Now when your application also has an array that stores more information about the persons it would be nice if you could access that array direectly by your peson objects. best regards marcus Saturday, June 3, 2006, 2:55:00 PM, you wrote:
> Hi,
> Is it really worth enabling a whole new area where problems could > occur just for this? Can you provide an example of where it might > actually be considered useful and not just being lazy?
> -Rob
> On 6/3/06, Marcus Boerger <helly@php.net> wrote: >> Hello Pierre, >> >> ever thought that we use tests to check special behavior and that >> those snippets have little to do with real applications? Obviously >> not. The idea behind is that for instance you might use an array as >> a translation and use an object to *calculate* the index. >> >> Saturday, June 3, 2006, 2:40:29 PM, you wrote: >> >> > Hi, >> >> > On 6/3/06, Marcus Boerger <mail@marcus-boerger.de> wrote: >> >> Hello guys, >> >> >> >> the attached patch closes one more __toString() part. It allows >> >> to use objects that define __toString as indexes to arrays. What do >> >> you guys think about this, should we add it or stay with the old >> >> behavior that didn't allow objects as indexes at all. >> >> > $arr[new Test] = 'abc'; >> >> > makes very little sense to me, as well as >> >> > $a = new Test; $arr[$a] = 'abc'; >> >> > Do we really want to support that? >> >> > --Pierre >> >> >> >> Best regards, >> Marcus >> >> -- >> PHP Internals - PHP Runtime Development Mailing List >> To unsubscribe, visit: http://www.php.net/unsub.php >> >>
> -- > Xnyo - http://xnyo.odynia.org/
Best regards, Marcus

Robert Amos

20 years ago
Thats fair, as long as it doesn't result in any unwanted behaviour then I'm +1. -Rob On 6/3/06, Marcus Boerger <helly@php.net> wrote:
> Hello Robert, > > well lazy is a good point here but __toString is all about lazyness. > Then again as said you might want to have objects naturally convert > to strings whereever possible. Generally when providing a __toString > implementation you say that you want this. And then you might as well > expect that your objects can be used as index to arrays. > > The example is as said an object that can be used to calculate the > index to an array. Assuming you deal with persons derived from > a database as classes, your person objects might be implmeneted so > that __toString simply returns the name of the persons. Now when your > application also has an array that stores more information about the > persons it would be nice if you could access that array direectly by > your peson objects. > > best regards > marcus > > Saturday, June 3, 2006, 2:55:00 PM, you wrote: > > > Hi, > > > Is it really worth enabling a whole new area where problems could > > occur just for this? Can you provide an example of where it might > > actually be considered useful and not just being lazy? > > > -Rob > > > On 6/3/06, Marcus Boerger <helly@php.net> wrote: > >> Hello Pierre, > >> > >> ever thought that we use tests to check special behavior and that > >> those snippets have little to do with real applications? Obviously > >> not. The idea behind is that for instance you might use an array as > >> a translation and use an object to *calculate* the index. > >> > >> Saturday, June 3, 2006, 2:40:29 PM, you wrote: > >> > >> > Hi, > >> > >> > On 6/3/06, Marcus Boerger <mail@marcus-boerger.de> wrote: > >> >> Hello guys, > >> >> > >> >> the attached patch closes one more __toString() part. It allows > >> >> to use objects that define __toString as indexes to arrays. What do > >> >> you guys think about this, should we add it or stay with the old > >> >> behavior that didn't allow objects as indexes at all. > >> > >> > $arr[new Test] = 'abc'; > >> > >> > makes very little sense to me, as well as > >> > >> > $a = new Test; $arr[$a] = 'abc'; > >> > >> > Do we really want to support that? > >> > >> > --Pierre > >> > >> > >> > >> Best regards, > >> Marcus > >> > >> -- > >> PHP Internals - PHP Runtime Development Mailing List > >> To unsubscribe, visit: http://www.php.net/unsub.php > >> > >> > > > > -- > > Xnyo - http://xnyo.odynia.org/ > > > > > Best regards, > Marcus > >
-- Xnyo - http://xnyo.odynia.org/

Pierre Joye

20 years ago
On 6/3/06, Robert Amos <shiznatz@gmail.com> wrote:
> Thats fair, as long as it doesn't result in any unwanted behaviour then I'm +1.
Good luck ;-) --Pierre

Derick Rethans

20 years ago
On Sat, 3 Jun 2006, Marcus Boerger wrote:
> Hello Robert, > > well lazy is a good point here but __toString is all about lazyness. > Then again as said you might want to have objects naturally convert > to strings whereever possible. Generally when providing a __toString > implementation you say that you want this. And then you might as well > expect that your objects can be used as index to arrays. > > The example is as said an object that can be used to calculate the > index to an array. Assuming you deal with persons derived from > a database as classes, your person objects might be implmeneted so > that __toString simply returns the name of the persons. Now when your > application also has an array that stores more information about the > persons it would be nice if you could access that array direectly by > your peson objects.
Makes sense to me, so +1. Derick
-- Derick Rethans http://derickrethans.nl | http://ez.no | http://xdebug.org

Michael Walter

20 years ago
Yes definitely, that functionality would be useful. Regards, Michael On 6/3/06, Pierre <pierre.php@gmail.com> wrote:

Andrew Yochum

20 years ago
On Sat, Jun 03, 2006 at 01:42:12PM +0200, Marcus Boerger wrote:
> Hello guys, > > the attached patch closes one more __toString() part. It allows > to use objects that define __toString as indexes to arrays. What do > you guys think about this, should we add it or stay with the old > behavior that didn't allow objects as indexes at all.
Like others who have contributed to the thread I agree that it would be useful, but I think using __toString() wrong for this. There is a confusion two ideas here: 1. The string representation of an object, probably human readable, lucent string. 2. A unique hash of an object use to identify it programmatically, and likely unique. Probably a non-human friendly, opaque value. These are not the same thing. The latter is what, IMO, would be used for an objects value as an index into an array, not the former. The latter is available ... currently I do this like so: class a{ public function __toString() { return 'an object';}} $foo = new a; $bar = new a; $arr = new array() $arr[(string)$foo] = $foo; // The index is "Object id #1" $arr[(string)$bar] = $bar; // The index is "Object id #2" Note that the __tostring method is not used in the cast - a spearate issue, but needs to be pointed out for this issue. Therefore my suggested alternative to Marcus' patch is: When Objects are used in array index context, use the object ID or some variation. And, possibly, provide a magic method, or interface to generate an hash value of an object. Regards, Andrew
-- Andrew Yochum Plexpod andrew@plexpod.com 718-360-0879

Marcus Börger

20 years ago
Hello Andrew, Saturday, June 3, 2006, 4:36:39 PM, you wrote:
> On Sat, Jun 03, 2006 at 01:42:12PM +0200, Marcus Boerger wrote: >> Hello guys, >> >> the attached patch closes one more __toString() part. It allows >> to use objects that define __toString as indexes to arrays. What do >> you guys think about this, should we add it or stay with the old >> behavior that didn't allow objects as indexes at all.
> Like others who have contributed to the thread I agree that it would be > useful, but I think using __toString() wrong for this. There is a > confusion two ideas here: > 1. The string representation of an object, probably human > readable, lucent string. > 2. A unique hash of an object use to identify it programmatically, > and likely unique. Probably a non-human friendly, opaque value. > These are not the same thing. The latter is what, IMO, would be used > for an objects value as an index into an array, not the former.
> The latter is available ... currently I do this like so: > class a{ public function __toString() { return 'an object';}} > $foo = new a; > $bar = new a; > $arr = new array() > $arr[(string)$foo] = $foo; // The index is "Object id #1" > $arr[(string)$bar] = $bar; // The index is "Object id #2" > Note that the __tostring method is not used in the cast - a spearate > issue, but needs to be pointed out for this issue.
> Therefore my suggested alternative to Marcus' patch is: > When Objects are used in array index context, use the object ID or some > variation. And, possibly, provide a magic method, or interface to > generate an hash value of an object.
We cannot use the object id since that is not necessarily unique. For the same reason SplObjectStorage cannot be done in userland. However what you mention here is right. Other languages offer to magic functions. A stringify one and a hashing one. But then again i don't think we should add yet another magic feature. best regards marcus

Andi Gutmans

20 years ago
Generally I think it's a good thing to allow to use objects as array indexes. There are really two ways of doing it: a) Try and find a way to create unique ideas. b) Support __toString() and leave it up to the author. I have a bit of a hard time finding a solution to (a) unless the unique id is a string. Not that I think having it as a string is necessarily a bad thing but I'd be interested in hearing what others think. Supporting __toString() is the easiest way to go, especially as it wouldn't lead to BC breaks. It would be up to the author to make that a unique key like "Db#Person#1" but then they couldn't use that with "print" because the value the class author would want there would probably not be the one he'd want in array access. Anyone got any thoughts, how bad of a break it would be if we did create a unique id of objects, whether string or int? That's something we probably could do for PHP 6 esp. if string is acceptable. Andi At 09:38 AM 6/3/2006, Marcus Boerger wrote:

Pierre Joye

20 years ago
Hi, On 6/4/06, Andi Gutmans <andi@zend.com> wrote:
> Generally I think it's a good thing to allow to use objects as array > indexes. There are really two ways of doing it: > a) Try and find a way to create unique ideas. > b) Support __toString() and leave it up to the author.
I see a third choice, which I prefer: c) leave the choice to the user, he knows better what to do with his object (like implementing his own get(Hash|Key) method. --Pierre

Andi Gutmans

20 years ago
Yep that is also a choice, although it can be advantageous to have an automatic (a) which people just now works, always... I don't think it's a critical problem because as you pointed out people can deal with it, but I think it'd be nice to provide some tools to make life easier. At 06:01 PM 6/3/2006, Pierre wrote:

Alan Knowles

20 years ago
$x = new Obj; $y[$x]= 123; That behaviour is going to be fun to document, and for people unfamilar with it to find in the manual -> php.net/array -> go to array syntax page -> read down to find about objects as keys -> go to __toHash() page... ..whereas... $x = new Obj; $y[$x->toHash()]= 123; they might have a chance to see instantly how that is supposed to work, on the rare occasion that somebody needs this, is it really worth building it into the langauge???? Regards Alan Andi Gutmans wrote:

Rasmus Lerdorf

20 years ago
Alan Knowles wrote:
> > $x = new Obj; > $y[$x]= 123; > > That behaviour is going to be fun to document, and for people unfamilar > with it to find in the manual > -> php.net/array -> go to array syntax page -> read down to find about > objects as keys -> go to __toHash() page... > > ..whereas... > $x = new Obj; > $y[$x->toHash()]= 123; > > they might have a chance to see instantly how that is supposed to work, > on the rare occasion that somebody needs this, is it really worth > building it into the langauge????
In that case, why not just use the existing __toString explicitly with: $x = new Obj; $y[(string)$x] = 123; This works today and basically gives you the same thing. The only thing it doesn't do is separate an array index context from an output context allowing you do different things in the two cases. I think if we are going to add a toHash thing, it should trigger when the object is used in a hash context, just like toString triggers when it is used in a string context. -Rasmus

Pierre Joye

20 years ago
On Sat, 03 Jun 2006 18:50:09 -0700 rasmus@lerdorf.com (Rasmus Lerdorf) wrote:
> This works today and basically gives you the same thing. The only > thing it doesn't do is separate an array index context from an output > context allowing you do different things in the two cases. > > I think if we are going to add a toHash thing, it should trigger when > the object is used in a hash context, just like toString triggers > when it is used in a string context.
Agreed. this is the only solution to limit undesired behaviors, if we add such magic method. As well as raising warnings when an object is used as hash without having this method defined. -- Pierre

Marcus Börger

20 years ago
Hello Rasmus, Andi, first to Andi, there is no BC involved beside the fact that this would allow objects being used in arrays which wasn't possible before. Now a hashing value can easily be generated: char * hash; int len = spprintf(&hash,0,"%p:%d",Z_OBJ_HT_P(zobj),Z_OBJ_HANDLE_P(zobj)); That said maybe it is enough to add a generic hash function either the engine or SPL: /* {{{ proto string spl_object_hash(object obj) Return hash id for given object */ PHP_FUNCTION(spl_object_hash) { zval *obj; int len; char *hash; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &obj) == FAILURE) { return; } len = spprintf(&hash, 0, "%p:%d", Z_OBJ_HT_P(obj), Z_OBJ_HANDLE_P(obj)); RETURN_STRINGL(hash, len, 0); } marcus@zaphod /usr/src/PHP_5_2 $ php -r 'var_dump(spl_object_hash(new stdClass));' string(11) "0x87b6a40:1" Maybe we want to scramble this with md5 or something alike: /* {{{ proto string spl_object_hash(object obj) Return hash id for given object */ PHP_FUNCTION(spl_object_hash) { zval *obj; int len; char *hash; char md5str[33]; PHP_MD5_CTX context; unsigned char digest[16]; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &obj) == FAILURE) { return; } 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); efree(hash); } marcus@zaphod /usr/src/PHP_5_2 $ php -r 'var_dump(spl_object_hash(new stdClass));' string(32) "0bab1548e3b42acbcf1170617b5432ae" For PHP 5.2 we could think about adding a hash handler to the object handler table and provide the above as default implementation. That hash handler would then be called when an object is being used as an offset. Maybe later in PHP 6 we can also add an interface that allows to overload that hash implementation. (If someone really wants that). Yet anything the user can overload be it an interface or magic function (e.g. __hashOf) seems to be too much for now. Besides that i am meanwhile convinced that __toString shouldn't have to do anything with objects as array offsets other then it can be requested by the user thorugh a string cast (e.g.: $ar[(string)$obj]). best regards marcus Sunday, June 4, 2006, 3:50:09 AM, you wrote:
> Alan Knowles wrote: >> >> $x = new Obj; >> $y[$x]= 123; >> >> That behaviour is going to be fun to document, and for people unfamilar >> with it to find in the manual >> -> php.net/array -> go to array syntax page -> read down to find about >> objects as keys -> go to __toHash() page... >> >> ..whereas... >> $x = new Obj; >> $y[$x->toHash()]= 123; >> >> they might have a chance to see instantly how that is supposed to work, >> on the rare occasion that somebody needs this, is it really worth >> building it into the langauge????
> In that case, why not just use the existing __toString explicitly with:
> $x = new Obj; > $y[(string)$x] = 123;
> This works today and basically gives you the same thing. The only thing > it doesn't do is separate an array index context from an output context > allowing you do different things in the two cases.
> I think if we are going to add a toHash thing, it should trigger when > the object is used in a hash context, just like toString triggers when > it is used in a string context.
> -Rasmus
Best regards, Marcus

Pierre Joye

20 years ago
Hello,
> Hello Rasmus, Andi,
> marcus@zaphod /usr/src/PHP_5_2 $ php -r 'var_dump(spl_object_hash(new > stdClass));' string(32) "0bab1548e3b42acbcf1170617b5432ae" > > For PHP 5.2 we could think about adding a hash handler to the object > handler table and provide the above as default implementation. That > hash handler would then be called when an object is being used as an > offset. Maybe later in PHP 6 we can also add an interface that allows > to overload that hash implementation. (If someone really wants that). > Yet anything the user can overload be it an interface or magic > function (e.g. __hashOf) seems to be too much for now.
Do you mean to allow object as indices with this default implementation? But this implementataion cannot be overloaded? I fail to see the needs of such things in 5.x (or 6.x even with overload). Adding another magic method __toHash is also not what I would like. Adding a function hash_from_object() or spl_hash_from object() to ease the generations of hashes is indeed a good idea. There is no impact in the objects managements and people are free to use it or not (no magic default behaviors). --Pierre

Sebastian Bergmann

20 years ago
Rasmus Lerdorf wrote:
> I think if we are going to add a toHash thing, it should trigger when > the object is used in a hash context, just like toString triggers when > it is used in a string context.
This makes sense to me, too.
-- Sebastian Bergmann http://www.sebastian-bergmann.de/ GnuPG Key: 0xB85B5D69 / 27A7 2B14 09E4 98CD 6277 0E5B 6867 C514 B85B 5D69

Zeev Suraski

20 years ago
Whichever way we go, the key would have to be either an integer or a string (since that's what array indices can be), and going with an integer here sounds like a really bad idea (chances of it colliding with numeric indices are reasonably high on a 32-bit system). So if we go with (a), it would definitely have to be a string as you suggested. Not sure what's the best way to create a unique, one-to-one mapped string representation of an object. If we can't find a solution to that one, then it pretty much brings us to (b). Zeev At 03:57 04/06/2006, Andi Gutmans wrote:

Ilia A.

20 years ago
I think this is a potentially missing bit of functionality we definitely need to consider including. There is really no technical reason why $foo[new ToStringObject] = "bar"; cannot work or a reason why it shouldn't as far as functionality goes. Ilia Alshanetsky On 3-Jun-06, at 7:42 AM, Marcus Boerger wrote:

Rasmus Lerdorf

20 years ago
I don't understand why using the object as an index would trigger a __toString() call. PHP's array indices are not defined to be strings, so I don't see this as being a string context use and thus __toString() shouldn't be called. I also don't see why we need to make a distinction between the key and the value here if there is any way we can avoid it. For example, this obviously works: class foo { function a() { echo "a"; } } $a = new foo(); $b[1] = $a; $b[1]->a(); Why shouldn't this? $b[$a] = 1; key($b)->a(); I have always looked a PHP array as having 2 places to store things. You can store stuff in the key with the caveat/feature that it must be unique and you can store whatever you want in the value part. Only allowing strings and integers in the key seems like an arbitrary restriction to me. As long as the key is something we can somehow uniquely identify I think we should aim to support it. -Rasmus Ilia Alshanetsky wrote:

Marcus Börger

20 years ago
Hello Rasmus, though you are probably right here your idea brought to it's full extend will bring a major BC break. Just consider we had both key and value as a zval then the current behavior would change for quite a lot of situations including not only objects and resources but also booleans, floats and NULL. Right now everybody is used to the restiction that an array key can only be a string or an integer and if not it is either not acceptable as a key at all or is being converted to either one. best regards marcus Saturday, June 3, 2006, 6:30:38 PM, you wrote:
> I don't understand why using the object as an index would trigger a > __toString() call. PHP's array indices are not defined to be strings, > so I don't see this as being a string context use and thus __toString() > shouldn't be called.
> I also don't see why we need to make a distinction between the key and > the value here if there is any way we can avoid it.
> For example, this obviously works:
> class foo { > function a() { echo "a"; } > } > $a = new foo(); > $b[1] = $a; > $b[1]->a();
> Why shouldn't this?
> $b[$a] = 1; > key($b)->a();
> I have always looked a PHP array as having 2 places to store things. > You can store stuff in the key with the caveat/feature that it must be > unique and you can store whatever you want in the value part. Only > allowing strings and integers in the key seems like an arbitrary > restriction to me. As long as the key is something we can somehow > uniquely identify I think we should aim to support it.
> -Rasmus
> Ilia Alshanetsky wrote: >> I think this is a potentially missing bit of functionality we definitely >> need to consider including. There is really no technical reason why >> $foo[new ToStringObject] = "bar"; cannot work or a reason why it >> shouldn't as far as functionality goes. >> >> >> Ilia Alshanetsky >> >> >> >> >> On 3-Jun-06, at 7:42 AM, Marcus Boerger wrote: >> >>> Hello guys, >>> >>> the attached patch closes one more __toString() part. It allows >>> to use objects that define __toString as indexes to arrays. What do >>> you guys think about this, should we add it or stay with the old >>> behavior that didn't allow objects as indexes at all. >>> >>> --Best regards, >>> Marcus mailto:mail@marcus-boerger.de >>> <ze2-offset-obj-tostring-20060603.diff.txt> >>> --PHP Internals - PHP Runtime Development Mailing List >>> To unsubscribe, visit: http://www.php.net/unsub.php >> >> --PHP Internals - PHP Runtime Development Mailing List >> To unsubscribe, visit: http://www.php.net/unsub.php
Best regards, Marcus

Rasmus Lerdorf

20 years ago
Right, just let me clarify. My point here was that if we are going to make a change here, we should do it correctly and come up with a way to create a unique hash of the object so it really can be used as an array index. Magically calling __toString() in a case where we don't have an explicit string context sounds half-assed and non-obvious to me. If you want that ability, simply do: $a[(string)$obj] and it is obvious what you are doing. -Rasmus Marcus Boerger wrote:

Stanislav Malyshev

20 years ago
RL>>I don't understand why using the object as an index would trigger a RL>>__toString() call. PHP's array indices are not defined to be strings, RL>>so I don't see this as being a string context use and thus RL>>__toString() shouldn't be called. If so, what should be the actual key in the hash?
-- Stanislav Malyshev, Zend Products Engineer stas@zend.com http://www.zend.com/ +972-3-6139665 ext.115

Rasmus Lerdorf

20 years ago
Stanislav Malyshev wrote:
> RL>>I don't understand why using the object as an index would trigger a > RL>>__toString() call. PHP's array indices are not defined to be strings, > RL>>so I don't see this as being a string context use and thus > RL>>__toString() shouldn't be called. > > If so, what should be the actual key in the hash?
I am sure we could come up with some sort of hashing mechanism that would uniquely identify an object. And perhaps even expose it to the user with a __hashOf(). But again, I am not sure we want to open up that can of worms. Like I said, I think this is the more correct approach and that we shouldn't try to use a magic __toString() call here to attempt to emulate this. -Rasmus

Gwynne

20 years ago
On Jun 3, 2006, at 1:13 PM, Rasmus Lerdorf wrote:
>> RL>>I don't understand why using the object as an index would >> trigger a RL>>__toString() call. PHP's array indices are not >> defined to be strings, RL>>so I don't see this as being a string >> context use and thus >> RL>>__toString() shouldn't be called. >> If so, what should be the actual key in the hash? > I am sure we could come up with some sort of hashing mechanism that > would uniquely identify an object. And perhaps even expose it to > the user with a __hashOf(). But again, I am not sure we want to > open up that can of worms. Like I said, I think this is the more > correct approach and that we shouldn't try to use a magic __toString > () call here to attempt to emulate this.
I'm new to this list, so I apologize if I'm out of line in commenting here, but it's my opinion that the advantages offered by a __hash() magic function would outweigh the inevitable complexity and issues involved. I imagine that it would be a strict semantic: If the class of the object being indexed into the array doesn't define a magic __hash() function, it would be a warning or even fatal error; no attempt would/should be made to calculate a hash based on anything other than what the object is willing to call itself. Gwynne SkyTag Software

Jasper Bryant-Greene

20 years ago
-----BEGIN PGP SIGNED MESSAGE----- Hash: RIPEMD160 Gwynne wrote:
> I'm new to this list, so I apologize if I'm out of line in commenting > here, but it's my opinion that the advantages offered by a __hash() > magic function would outweigh the inevitable complexity and issues > involved. I imagine that it would be a strict semantic: If the class of > the object being indexed into the array doesn't define a magic __hash() > function, it would be a warning or even fatal error; no attempt > would/should be made to calculate a hash based on anything other than > what the object is willing to call itself.
I would imagine that __hash() or whatever it is called would be defined on all objects and implemented internally in PHP, and would simply generate some internal hash that is unique for all objects. - -- Jasper Bryant-Greene General Manager Album Limited http://www.album.co.nz/ 0800 4 ALBUM jasper@album.co.nz 021 708 334 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.3 (MingW32) iD8DBQFEgglOFfAeHhDzT4gRA2JtAKC3rkHI6QGo5yYQyHBbuZzG068D6wCgqej3 QqtgAcCeC5qo8ja2oCB4aUw= =2C/T -----END PGP SIGNATURE-----

Gwynne

20 years ago
On Jun 3, 2006, at 6:12 PM, Jasper Bryant-Greene wrote:
> I would imagine that __hash() or whatever it is called would be > defined > on all objects and implemented internally in PHP, and would simply > generate some internal hash that is unique for all objects.
That might work for initial testing, but applying that sort of hash function to objects identified purely by strings, to take one example, doesn't work. (in_array(new Str("A"), array(new Str("A"))) is one failure mode that comes instantly to mind. It's inevitable that two non-identical objects would contain identical data. Think of the reasons behind C++'s operator==, or for those of you familiar with Carbon programming under MacOS, the hash callbacks provided by CoreFoundation's various container types. Gwynne SkyTag Software

bertrand Gugger

20 years ago
Gwynne wrote:
> no attempt > would/should be made to calculate a hash based on anything other than > what the object is willing to call itself.
+1 here oo people have a name for that. and implement what's needed. I'm surely out of talk , but please keep indexes scalar. The toString way is anyway rotten. The id way for an object is headaches.
-- toggg

Greg Beaver

20 years ago
Marcus Boerger wrote:
> Hello guys, > > the attached patch closes one more __toString() part. It allows > to use objects that define __toString as indexes to arrays. What do > you guys think about this, should we add it or stay with the old > behavior that didn't allow objects as indexes at all.
I prefer to require an explicit (string) cast to use an object as an array index. The "can't use objects as array index" has actually helped me catch many subtle bugs that were slipping through in earlier PHP versions, I very much like this fatal error. I don't see this: $a = $b[$c]; being much clearer to understand than: $a = $b[$c]; or better yet $a = $b[$c->person()]; which is by far the clearest and easiest to debug (and results in a fatal error if $c is the wrong kind of object or the wrong string - even better for debugging) Thanks, Greg

Zeev Suraski

20 years ago
In case we can't find a solution Andi's (a) approach, I think I like the explicit cast approach better than just implicitly converting to string. Rasmus pointed out that it's not clear why of all types PHP would implicitly convert the object to a string, and chances are that he's not the only person that will be surprised by that behavior. Zeev At 06:20 04/06/2006, Greg Beaver wrote:

Michael Wallner

20 years ago
Marcus Boerger wrote:
> Hello guys, > > the attached patch closes one more __toString() part. It allows > to use objects that define __toString as indexes to arrays. What do > you guys think about this, should we add it or stay with the old > behavior that didn't allow objects as indexes at all.
-1 on automatic __toString() +1 on explicit (string) cast (as it is now) +0 on __toHash()/__toKey() (which must be implemented explicitly) Rasmus' idea of changing the HashKey is... duh... at least something to think some more time about. Regards,
-- Michael

Derick Rethans

20 years ago
On Sun, 4 Jun 2006, Michael Wallner wrote:
> Marcus Boerger wrote: > > Hello guys, > > > > the attached patch closes one more __toString() part. It allows > > to use objects that define __toString as indexes to arrays. What do > > you guys think about this, should we add it or stay with the old > > behavior that didn't allow objects as indexes at all. > > -1 on automatic __toString() > +1 on explicit (string) cast (as it is now) > +0 on __toHash()/__toKey() (which must be implemented explicitly)
I changed my mind :) -1 on automatic __toString() +1 on explicit (string) cast -1 on __toHash/__toKey +1 on unique object identifiers regards, Derick

Marian Kostadinov

20 years ago
There will be a BC problem with classes implementing ArrayAccess where the array key is passed to offsetXXX methods as it is. And there we have objects also allowed as parameters. 2006/6/3, Marcus Boerger <mail@marcus-boerger.de>:

Andrei Zmievski

20 years ago
I am sorry if I missed the whole thread. I think that using the result of __toString() for indexing objects is a bad idea. If we want to allow this behavior (which is actually useful in some situations), I'd rather we had a __hash() method or something similar to what Python does. The string representation of the object and its hashed representation may be very different. -Andrei On Jun 3, 2006, at 4:42 AM, Marcus Boerger wrote:

Adam Maccabee Trachtenberg

20 years ago
On Sun, 4 Jun 2006, Andrei Zmievski wrote:
> I am sorry if I missed the whole thread. I think that using the > result of __toString() for indexing objects is a bad idea. If we want > to allow this behavior (which is actually useful in some situations), > I'd rather we had a __hash() method or something similar to what > Python does. The string representation of the object and its hashed > representation may be very different.
After sitting on the fence on this one for a few days, I agree with Andrei. For example, for an eBay Item object, my __toString() returns the Title, but that's not unique, so my __toHash() returns the numeric ID, which is. Furthermore, if my __toString() was unique, and I was relying on that for keys in an array, I would have to mark that method as final; otherwise, someone might unknowingly destroy the uniqueness in a child class and break my code. That's not ideal because there could otherwise be many good reasons that someone would want to override __toString(). In contrast, it's unlikely that you would override __toHash(), and it's pretty obvious that you shouldn't do something that could cause collisions. The other proposal, where PHP generates a unique object id, would also be fine. Even better, perhaps. I'm not sure what I think yet. -adam
-- adam@trachtenberg.com | http://www.trachtenberg.com author of o'reilly's "upgrading to php 5" and "php cookbook" avoid the holiday rush, buy your copies today!

Michael Gall

20 years ago
On 6/5/06, Adam Maccabee Trachtenberg <adam@trachtenberg.com> wrote:
> > For example, for an eBay Item object, my __toString() returns the > Title, but that's not unique, so my __toHash() returns the numeric ID, > which is.
While I wouldn't be surprised if you completely ignore my opinion, however I think the __toHash implementation should happen in an interface, rather than happening automagically. That will make it just a little bit more predicatable. Michael

Gwynne

20 years ago
On Jun 4, 2006, at 8:33 PM, Michael Gall wrote:
>> For example, for an eBay Item object, my __toString() returns the >> Title, but that's not unique, so my __toHash() returns the numeric >> ID, >> which is. > While I wouldn't be surprised if you completely ignore my opinion, > however I > think the __toHash implementation should happen in an interface, > rather than > happening automagically. That will make it just a little bit more > predicatable.
+1 on that from me. There is definitely a use for a __toHash() magic function WITHOUT it being automagical. An automagical one would probably lead to a lot of confusion and odd behaviors. Let people use the feature if they need it and ignore it otherwise. However, if it was automagical, I'd agree with previous comments: Make it a string based on the hash table pointer. Gwynne SkyTag Software

Robert Cummings

20 years ago
On Sun, 2006-06-04 at 20:49, Gwynne wrote:
> On Jun 4, 2006, at 8:33 PM, Michael Gall wrote: > >> For example, for an eBay Item object, my __toString() returns the > >> Title, but that's not unique, so my __toHash() returns the numeric > >> ID, > >> which is. > > While I wouldn't be surprised if you completely ignore my opinion, > > however I > > think the __toHash implementation should happen in an interface, > > rather than > > happening automagically. That will make it just a little bit more > > predicatable. > > +1 on that from me. There is definitely a use for a __toHash() magic > function WITHOUT it being automagical. An automagical one would > probably lead to a lot of confusion and odd behaviors. Let people use > the feature if they need it and ignore it otherwise.
But enforcing it's use via an interface means class users that don't want to use interfaces now need to use interfaces. Also the other magical functions aren't linked to interfaces, why change tradition? Cheers, Rob.
-- .------------------------------------------------------------. | InterJinn Application Framework - http://www.interjinn.com | :------------------------------------------------------------: | An application and templating framework for PHP. Boasting | | a powerful, scalable system for accessing system services | | such as forms, properties, sessions, and caches. InterJinn | | also provides an extremely flexible architecture for | | creating re-usable components quickly and easily. | `------------------------------------------------------------'

Richard Lynch

20 years ago
On Sat, June 3, 2006 6:42 am, Marcus Boerger wrote:
> the attached patch closes one more __toString() part. It allows > to use objects that define __toString as indexes to arrays. What do > you guys think about this, should we add it or stay with the old > behavior that didn't allow objects as indexes at all.
I use objects rarely, and am not sure I care all that much, but... Seems to me that there is a REALLY good chance that there ARE scripts "out there" that rely on current behaviour of: $a = new Foo(); $arr[$a] = 42; Never mind that that's a really dumb thing to have -- Somebody is relying on it doing whatever it does... Whether that is erroring out or just turning all objects into "" doesn't matter. Somebody relies on it doing the same thing it always did. Don't break that, please, in 5.2 -- Do whatever you want in 6.0 on that. This all seems like much ado about nothing to me. Anybody brainy enough to NEED their objects as array indices can probably manage to write a function to uniquely identify their/all objects. Sorry if my votes aren't fitting into the schema of voting... I kinda got glassy-eyed with this whole thread, to tell the truth.
-- Like Music? http://l-i-e.com/artists.htm

Robert Amos

20 years ago
As far as I can see, and I'm sure someone will be kind enough to correct me if I'm wrong, but there is no current behaviour for it, it returns a warning. $a = new stdClass; $b[$a] = 0; Warning: Illegal offset type in t3.php on line 2 And results in an empty array (in this case) so it does nothing. -bok On 6/5/06, Richard Lynch <ceo@l-i-e.com> wrote:
> > On Sat, June 3, 2006 6:42 am, Marcus Boerger wrote: > > the attached patch closes one more __toString() part. It allows > > to use objects that define __toString as indexes to arrays. What do > > you guys think about this, should we add it or stay with the old > > behavior that didn't allow objects as indexes at all. > > I use objects rarely, and am not sure I care all that much, but... > > Seems to me that there is a REALLY good chance that there ARE scripts > "out there" that rely on current behaviour of: > > $a = new Foo(); > $arr[$a] = 42; > > Never mind that that's a really dumb thing to have -- Somebody is > relying on it doing whatever it does... > > Whether that is erroring out or just turning all objects into "" > doesn't matter. Somebody relies on it doing the same thing it always > did. > > Don't break that, please, in 5.2 -- Do whatever you want in 6.0 on that. > > This all seems like much ado about nothing to me. Anybody brainy > enough to NEED their objects as array indices can probably manage to > write a function to uniquely identify their/all objects. > > Sorry if my votes aren't fitting into the schema of voting... I kinda > got glassy-eyed with this whole thread, to tell the truth. > > -- > Like Music? > http://l-i-e.com/artists.htm > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > >
-- Xnyo - http://xnyo.odynia.org/

Richard Lynch

20 years ago
That *IS* a current behaviour. Returns a warning and leaves the array un-modified. On Sun, June 4, 2006 10:59 pm, Robert Amos wrote:
> As far as I can see, and I'm sure someone will be kind enough to > correct me > if I'm wrong, but there is no current behaviour for it, it returns a > warning. > > $a = new stdClass; > $b[$a] = 0; > > Warning: Illegal offset type in t3.php on line 2 > > And results in an empty array (in this case) so it does nothing. > > -bok > > On 6/5/06, Richard Lynch <ceo@l-i-e.com> wrote: >> >> On Sat, June 3, 2006 6:42 am, Marcus Boerger wrote: >> > the attached patch closes one more __toString() part. It allows >> > to use objects that define __toString as indexes to arrays. What >> do >> > you guys think about this, should we add it or stay with the old >> > behavior that didn't allow objects as indexes at all. >> >> I use objects rarely, and am not sure I care all that much, but... >> >> Seems to me that there is a REALLY good chance that there ARE >> scripts >> "out there" that rely on current behaviour of: >> >> $a = new Foo(); >> $arr[$a] = 42; >> >> Never mind that that's a really dumb thing to have -- Somebody is >> relying on it doing whatever it does... >> >> Whether that is erroring out or just turning all objects into "" >> doesn't matter. Somebody relies on it doing the same thing it >> always >> did. >> >> Don't break that, please, in 5.2 -- Do whatever you want in 6.0 on >> that. >> >> This all seems like much ado about nothing to me. Anybody brainy >> enough to NEED their objects as array indices can probably manage to >> write a function to uniquely identify their/all objects. >> >> Sorry if my votes aren't fitting into the schema of voting... I >> kinda >> got glassy-eyed with this whole thread, to tell the truth. >> >> -- >> Like Music? >> http://l-i-e.com/artists.htm >> >> -- >> PHP Internals - PHP Runtime Development Mailing List >> To unsubscribe, visit: http://www.php.net/unsub.php >> >> > > > -- > Xnyo - http://xnyo.odynia.org/ >
-- Like Music? http://l-i-e.com/artists.htm

Jasper Bryant-Greene

20 years ago
-----BEGIN PGP SIGNED MESSAGE----- Hash: RIPEMD160 All I've got to say on the matter is that if anyone is relying on that kind of behaviour for something serious, then their code deserves to break. Jasper Richard Lynch wrote:
> That *IS* a current behaviour. > > Returns a warning and leaves the array un-modified. > > > On Sun, June 4, 2006 10:59 pm, Robert Amos wrote: >> As far as I can see, and I'm sure someone will be kind enough to >> correct me >> if I'm wrong, but there is no current behaviour for it, it returns a >> warning. >> >> $a = new stdClass; >> $b[$a] = 0; >> >> Warning: Illegal offset type in t3.php on line 2 >> >> And results in an empty array (in this case) so it does nothing. >> >> -bok >> >> On 6/5/06, Richard Lynch <ceo@l-i-e.com> wrote: >>> On Sat, June 3, 2006 6:42 am, Marcus Boerger wrote: >>>> the attached patch closes one more __toString() part. It allows >>>> to use objects that define __toString as indexes to arrays. What >>> do >>>> you guys think about this, should we add it or stay with the old >>>> behavior that didn't allow objects as indexes at all. >>> I use objects rarely, and am not sure I care all that much, but... >>> >>> Seems to me that there is a REALLY good chance that there ARE >>> scripts >>> "out there" that rely on current behaviour of: >>> >>> $a = new Foo(); >>> $arr[$a] = 42; >>> >>> Never mind that that's a really dumb thing to have -- Somebody is >>> relying on it doing whatever it does... >>> >>> Whether that is erroring out or just turning all objects into "" >>> doesn't matter. Somebody relies on it doing the same thing it >>> always >>> did. >>> >>> Don't break that, please, in 5.2 -- Do whatever you want in 6.0 on >>> that. >>> >>> This all seems like much ado about nothing to me. Anybody brainy >>> enough to NEED their objects as array indices can probably manage to >>> write a function to uniquely identify their/all objects. >>> >>> Sorry if my votes aren't fitting into the schema of voting... I >>> kinda >>> got glassy-eyed with this whole thread, to tell the truth. >>> >>> -- >>> Like Music? >>> http://l-i-e.com/artists.htm >>> >>> -- >>> PHP Internals - PHP Runtime Development Mailing List >>> To unsubscribe, visit: http://www.php.net/unsub.php >>> >>> >> >> -- >> Xnyo - http://xnyo.odynia.org/ >> > >
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.2.2 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFEhJWZFfAeHhDzT4gRA82mAJ4xoaVLaWdN98sgiKBLoI2BNVlqNQCgw6tb 8sayHh6bHy+540r+gYMwxwk= =10rp -----END PGP SIGNATURE-----

Greg Beaver

20 years ago
You miss the point. The warning that is helpful in debugging, it has nothing to do with designing things to break, it has to do with unintentional bugs. If in 1 case of 1000 in a loop, there is an object instead of a string used as a key due to a bug (one example: this can easily happen if you forget to check for a PEAR_Error on return from a legacy PEAR class), a warning is printed. With some kind of magic conversion, this warning will instead translate into a magic conversion to string, causing unpredictable and very difficult-to-track-down behavior. Greg Jasper Bryant-Greene wrote:

Sebastian Bergmann

20 years ago
Marcus Boerger wrote:
> the attached patch closes one more __toString() part. It allows > to use objects that define __toString as indexes to arrays. What do > you guys think about this, should we add it or stay with the old > behavior that didn't allow objects as indexes at all.
+1
-- Sebastian Bergmann http://www.sebastian-bergmann.de/ GnuPG Key: 0xB85B5D69 / 27A7 2B14 09E4 98CD 6277 0E5B 6867 C514 B85B 5D69

Dmitry Stogov

20 years ago
We probably should support this, but not only for __toString(). Objects may also have internal get() (not __get()) and cast() handlers that should be supported too. Also usage of cast() in context of array offset don't say what do we like "int" or "string". Thanks. Dmitry.

Evert Pot

20 years ago
Any chance this could be done in the form of an interface, instead of a magic function? Evert Dmitry Stogov wrote: