PHP: create_function() ist gefährlich

Stefan - 24. August 2007

Heute durfte ich auf die harte Tour lernen, wie weit PHP manchmal noch von Perl und Python entfernt ist. So gehört in Python der Einsatz von lambda als Callback-Funktionen in Sprachkonstrukten wie filter oder reduce quasi zum guten Ton. Und hat man sich an einen derartige Programmierweise erst einmal gewöhnt, kommt einem alles andere vor wie QBasic für Einsteiger.

Natürlich hab ich auch in meinem neuesten Projekt, das zum ersten Mal auch im Backend auf PHP setzt, intensiv die PHP-Variante create_function() benutzt. In etlichen array_filter()- oder array_reduce()-Konstrukten hab ich also ein create_function() eingesetzt.

Das faszinierende dabei: Alles funktioniert wie erwartet. Naja fast. Das Escapen von Variablen oder gar der Zugriff auf Klassenkonstanten ist ein Graus, aber irgendwie klappt’s fast immer. Bis ich ein Script schrieb und auf die 180.000 Einträge einer Tabelle losließ. Nach wenigen tausend Datensätzen ging dem Script schon der Speicher aus, wobei ich memory_limit eh schon auf 768 MB gesetzt hatte.

Eine detaillierte Analyse (ich hab halt Stück für Stück die einzelnen Funktionsaufrufe auskommentiert) zeigte, dass der Übeltäter eine Funktion war, in der zwei create_function()-Aufrufe steckten. Sobald ich diese durch den Aufruf zweier normaler Funktionen ersetzte, war das Memory Leak, das create_function() aufriss, gestopft. Seither benötigt das Script, selbst bei 100.000 Durchläufen, keine 5 MB.

Ganz offensichtlich gibt der PHP Garbage Collector den Speicher, der durch create_function() beansprucht wird, nicht zurück. Hängt wohl damit zusammen, dass PHP eine einmal erzeugte Funktion nicht überschreiben oder löschen kann. Wieder etwas mühsam gelernt; warum nur steht im PHP Manual kein Hinweis dazu? (Keine Widerrede: Die Warnungen im Diskussionsbereich zählen nicht!)

Jetzt habe ich also ein Script, dessen Speicherbedarf sich in Grenzen hält, der Code aber ist durch den Verzicht auf create_function() deutlich hässlicher und weniger wartbar geworden. Elegante Programmierung und PHP passen wohl immer noch nicht zusammen.

Abgelegt in: PHP

4 Kommentare:

[…] hat auf seinem Blog in einem Artikel zu create_function über ein Memoryleak berichtet, das temporäre Funktionen aufreisen. Ursache ist der […]

Warum erzeugst du nicht wie im Beispiel einfach eine “Variable” mit der Funktion, prüfst ob diese existiert und wenn ja, benutzt du die bereits existente Funkiton? So ist sichergestellt, dass die Funktion nur einmal erzeugt wird, trotzdem ist sie da wo sie logisch hingehört :-)

Naja, das ist sicherlich auch ein Weg, aber auch das ist, wenn man die eleganten Lösungen von Perl und Co. gewohnt ist, nur ein Hilfskonstrukt. Und der Kern meiner “Beschwerde” war ja, dass create_function() genau so zu funktionieren scheint wie man das von der “Konkurrenz” kennt – es dann aber doch nicht tut, wenn’s drauf ankommt.

[…] wo andere einfach nur x in d schreiben und wer zwar create_function() zur Verfügung hat, diese gefährliche Funktion aber am besten nicht benutzt, dem nehme ich die Liebe zu JavaScript sogar ab. Besser als PHP ist es […]

Schreibe einen Kommentar
benötigt
benötigt (wird nicht angezeigt)
optional

Suchen