Matthias Pigulla schrieb:
> [...] The "return new" issue has the interesting side
> effect that notices disappear depending on the constructor's
> implementation details.
Yes. If the language insists on getting on my nerves, well, then it
should at least be consistent in doing do ;-)
> Many people will agree that your above code should work - when seen from
> the "conceptual" point of view. It's a nasty side effect that because of
> the way the PHP4 internals worked, you *had* to use the reference here.
>
> Note that the following is yet another way of stating the same:
>
> function &getstuff($in) {
> return ($in == 'ok' ? new MyObject() : null);
> }
Nice shorter version of the example. All hail quick'n dirty C-style
inline-ifs. PHP was never very good at hiding its origin ;-)
> The problem is that even if internally temp assignments are used to make
> it "still work", how to separate the cases where notices are appropriate
> ("bad code") from those where they are not (because everything was
> "legal")?
By being able to switch this particular notice? So one can check all the
places where they occur and then decide which are true errors.
> [Weak point - others will throw in that it has never been "legal" but
> "only worked" :)]
No, if that hasn't been in the manual in the past then it has been legal
since behaviour was "undefined". Now PHP is filling the gaps in the docs
and taking a direction where it differs from most other languages so I
would call this "willingly breaking working code".
>>I don't understand the "only on PHP4": Why should PHP4 be
>>more "advanced" than PHP5 regarding this issue? And more
>>important: Why should the two versions differ in behaviour in
>>such a basic point?
>
> With PHP5 object handles, passing around references is really rare. If
> you ported your code to make use of the new PHP5 features, you probably
> won't see the whole reference passing-related problems at all (at least
> not in places where you're only doing correct OO stuff).
>
> [Example works in PHP5]
> Just as one would expect.
Oops. I managed to make the example that simple that it actually worked
since it never _needed_ to return a reference. There are more complex
cases where sometimes a reference is needed (because the object is
already bound into a larger data structure) and sometimes a new object
is needed. Then I am stuck with the same annoying problem of being
forced to supply dummy containers that you know from PHP4:
#!/usr/bin/php5.1
<?php
class Factory {
private static $predefined=null;
function init() { self::$predefined=new Foo(); }
function &build($what) {
if ($what == 'a')
return new Foo();
elseif ($what=='b')
return self::$predefined;
else
return null;
}
}
class Foo {}
Factory::init();
var_dump($x = Factory::build('a'));
var_dump($y = Factory::build('b'));
var_dump($y = Factory::build('c'));
throws (since PHP5.1) two of those notices and has to be replaced by
#!/usr/bin/php5.1
<?php
class Factory {
private static $predefined=null;
function init() { self::$predefined=new Foo(); }
function &build($what) {
if ($what == 'a')
{
$res=new Foo();
return $res;
}
elseif ($what=='b')
return self::$predefined;
else
{
$res=null;
return $res;
}
}
}
class Foo {}
Factory::init();
var_dump($x = Factory::build('a'));
var_dump($y = Factory::build('b'));
var_dump($y = Factory::build('c'));
And a simple "return $res=new Foo();" isn't enough to keep PHP quiet!
OLLi
____________
Reverend: "You’re pregnant?"
Gabrielle: "Yes. And it's impossible, I’m on the pill... which you
probably think is a sin, but it works. It’s a 99.9% effective sin."
Reverend: "Maybe it's in that one tenth of a percent that god resides."
Gabrielle: "You couldn’t wait to throw that in could you?"
[DH 120]