Hallo!
Nachdem ich neulich auf die Version 4.4.0 upgedatet habe, beschwert sich PHP nun über das halbe PEAR. Wie ich finde, macht es das teilweise zu Recht, teilweise aber nicht. Es geht dabei immer um Rückgaben von Funktionen per Referenz:
function & foo() {...}
Die Fehlermeldung lautet immer
Notice: Only variable references should be returned by referenceDas tritt neuerdings (unter 4.3.11 kam die Notice noch nicht) auf beispielsweise in PEAR-File_Find::maptree
function &maptree(...) {
...
return array(wert1, wert2);
}
>
> Hier wird ja auch keine Variablenreferenz zurückgegeben. Ich glaubte bisher, dass für das Array Speicher allokiert würde und eine Referenz darauf von der Funktion zurückgegeben wird. Und ohne & würde Speicher reserviert werden, dann eine Kopie davon zurückgegeben werden; also doppelter Speicherverbrauch plus Kopiervorgang.
Das ganze wurde in PHP 4.4 und 5.1 geändert, um Entwickler anzuhalten sauberer zu programmieren ;-)
Man soll eben nur Variablen von Funktionen zurückgeben, keine Ergebnisse von Ausdrücken.
Aus den [Release-Notes von PHP 4.4.0](http://de3.php.net/release_4_4_0.php):
> As part of the solution for the reference bug, you are very likely to find
> that your own or third-party PHP scripts, considered 'clean' code under
> previous versions of PHP, will now throw an E\_NOTICE when references are
> incorrectly used in the script. This is intended to alert developers to
> minor errors in their approach, and does not affect the script's
> performance in any other way.
> Weiteres Beispiel, gleiche Klasse:
>
> ~~~php
function &search(...) {
> ...
> return ($matches);
> }
Kaum nimmt man die überflüssigen Klammern um $matches weg, verschwindet auch die Notice. Die Klammern scheinen mir hier eine (ungewollte) Kopie zu erzeugen, die (bzw. eine Referenz darauf) statt der Referenz auf $matches zurückgegeben wird.
Aus dem Manual Returning References:
Note: If you try to return a reference from a function with the syntax:
return ($found_var); this will not work as you now try to return the
result of an expression, and not a variable, by reference. You can only
return variables by reference from a function - nothing else.
Noch ein Beispiel, und damit komme ich zu meiner Verwunderung:
Klasse HTML_QuickForm (verlinkt ist die ältere Version 1.155. Ab 1.156 ist die Ursache für die Warnung beseitigt/umgangen(?) )
Es geht um die Funktion createElement() (Zeile 511)
Hier das Prinzip in Kurzform:
function &x() {
$x = 43; // in HTML_QuickForm wird allerdings eine Objektinstanz erzeugt
return $x;
}function &y() {
return x();
}echo y();
>
> Angenommen hätte ich, dass die Referenz auf $x durchgereicht wird.
> In den gefixten Versionen wird die Funktion y() wie folgt definiert:
>
> ~~~php
function &y() {
> $y =& x();
> return $y;
> }
Kann in der ersten y()-Definition nur der Compiler nicht erkennen, dass er hier von x() schon eine Referenz bekommt? Oder wodurch wird die Notice gerechtfertigt?
x() ist keine Variable, Punkt ;-)
siehe auch:
http://www.sitepoint.com/blog-post-view.php?id=285589
http://wyome.com/index.php?ptid=10&aid=429&module=articles&func=display
Grüße
Andreas
SELFHTML Linkverzeichnis: http://aktuell.de.selfhtml.org/links/