Hi!

IMHO defining the value used for the array key should be provided by the
user, like Lester Caine said. Using a state or location based hash behaves
very unexpectedly and I doubt it would be used very much because of that.

Regarding __toString vs. __hash. It depends on what __toString really is
for. Now that there is a dedicated __debugInfo method, should __toString
enable an object to be used as a string without exception? In this case
there is no need for a separate method. Having a separate method might
actually be confusing. "When a string is expected __toString is called,
except when ..."

If that is not the purpose of __toString() than a separate method makes
more sense. I agree with johannes that __toString is often used for
debugging. I do that quite a bit. However since this would be new
functionality there is no BC break and users can be informed before using
it.


I tried to summarize the four approaches, just to make sure I understood
them correctly.

Using __toString()
------------------------

toString not set will lead all instances to use the same (empty) array key
thus overwriting each other.

toString is often used to generate a string represantation of the class.
Imagine an emailClass, where toString return the email body. This would
lead to huge unwieldy array keys, though technically fine.

toString then has three jobs:
    1. Output for debug (even though there is a new function for that, it
is still often used for that)
    2. Textual representation, like an email-body or the content of a
stream.
    3. array key

Currently the following error is thrown, when no __toString function is
defined
"Fatal error: Object of class O could not be converted to string". If it
read
"Fatal error: Object of class O could not be converted to string. Expected
method __toString()." It would point users in the right direction.

new magic method __hash
--------------------------------------

This relieves the ambiguity of __toString. It also enables the user to
define a key that is sensible for his use case, for example a user id or
database id.

Currently it issues a warning "Warning: Illegal offset type". If a new
magicc method is implemented than it should read "Warning: Illegal offset
type object. Object has no method __hash()"

state based Hash
-----------------------

A state based hash can be made somewhat readable, but changing state
changes the hash.

    $a = new MyClass();
    $a->foo = 'bar';

    $d = array( $a => 'It Works');

    $a->foo = 'buzz';

    echo $d[$a]; // Notice: Undefined index

On the other hand this would work (Imagine storing something in the session
or database and trying to access it from a different instance or from a
later request)

    $a = new MyClass();
    $a->foo = 'bar';

    $d = array( $a => 'It Works');

    $b = serialize($a);
    $a = unserialie($b);

    echo $d[$a]; // It Works!

internal pointer based Hash
------------------------------------

Changing the state of the object would not change its hash so this works:

    $a = new MyClass();
    $a->foo = 'bar';

    $d = array( $a => 'It Works');

    $a->foo = 'buzz';

    echo $d[$a]; // It works

But this would not work

    $a = new MyClass();
    $a->foo = 'bar';

    $d = array( $a => 'It Works);

    $b = serialize($a);
    $a = unserialie($b);

    echo $d[$a]; // Notice: Undefined index

-- john

Reply via email to