Impressum · Kontakt · Hilfe
Besucher online · Mitglieder



Portal > Foren > PHP > PHP-Programmierung > Closures in PHP emulieren
Antwort
 
Themen-Optionen
Alt 24.02.2008, 12:46   Nach oben    #1
pago
Projektleiter
 
Registriert seit: 30.11.2005
Ort: Bottrop
Beiträge: 1.091
Standard Closures in PHP emulieren

Hi,

ich überlege aktuell, wie man Closures in PHP realisieren könnte. (Kurzdefinition für Closure: Anonyme Funktion, die Zugriff auf den Scope (d.h. Variablen & Funktionen) hat, in dem sie definiert wurde)

Das darf von mir aus 100 Zeilen PHP-Code involvieren und extrem repetitiv sein, Hauptsache ich krieg's irgendwie hin.

Mein bisheriger Ansatz sieht so aus:
PHP-Code:
class Foo {
    private 
$stack = array();
    
    private function 
____closure($n) {
        
// get top of stack
        
$tos $this->stack[count($this->stack)-1];
        
// extract its variables to get hold of local variables
        
extract($tosEXTR_SKIP);
        
// push lexical scope and this scope onto stack (in case we're calling
        // an inner closure
        
$this->stack[] = array_merge($tos, array($n));
        
// invoke actual code
        
$result $y*$n;
        
// pop the stack
        
array_pop($this->stack);
        
// return the result
        
return $result;
    }
    
    public function 
doSomething($x$y) {
        
// push local variables on stack
        
$this->stack[] = array($x,$y);
        
// invoke actual code
        
$result array_map(array($this'____closure'), $x);
        
// pop the stack
        
array_pop($this->stack);
        
// return the result
        
return $result;
    }

Das müsste eigentlich funktionieren, selbst wenn in der Closure nochmal eine Closure wäre. Jedenfalls wenn ich bei meinen rein theoretischen Überlegungen keinen Fehler gemacht habe.

Problematisch wird es aber schon, wenn ich eine Closure zurückgeben will oder einer Funktion übergebe, die sie nicht direkt ausführt (dadurch wird der Stack geleert, ohne das die Closure Zugriff darauf hatte).

Hat jemand ne Idee, wie ich das Problem lösen kann? Oder gibt es keine Lösung (auch die Antwort würde mir helfen, weil ich dann nicht weiter überlegen müsste)?

Danke
- Patrick
pago ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 24.02.2008, 14:19   Nach oben    #2
MrNiceGuy
Erfahrener Benutzer
 
Benutzerbild von MrNiceGuy
 
Registriert seit: 14.08.2005
Ort: Nienburg / Weser
Beiträge: 662
Standard

Ähm, also ich habe mal eben versucht mir anhand des Textes bei Wikipedia anzueignen, was es mit dem closure aufsich haben soll, aber ehrlichgesagt habe ich denn Sinn und Zweck nicht wirklich hinterblicken können. Was wäre ein sinnvoller Anwendungsbereich für soetwas?! Und die Klasse da oben verstehe ich auch gerade nicht so richtig. Was sollen die Methoden bringen? Wie sollen sie aufgerufen werden? Und wenn ich das gerade richtig überflogen habe würde der Stack mit jedem Aufruf von ____closure($n) um ein weiteres Element erweitert, wobei vom vorherigen alle Inhalte plus den Übergabeparameter in den Stack geschrieben werden!? Das würde dann aber verdammt viel Speicherverbrauch bedeuten für immer die gleichen Daten?! *kratzamkopf*

Ich versuche nochmal diese kurze aber irgendwie doch wirre Klasse zu verstehen und den Sinn zu hinterblicken, wobei mir das momentan äußerst schwer fällt, nicht zuletzt, weil ich den Sinn hinter der Funktionalität von closures nicht verstanden habe, vielleicht kann mir da jemand auf die Sprünge helfen!? Die Beispiele bei Wikipedia helfen leider nicht wirklich weiter...
__________________
Paradox ist, wenn jemand für seinen Alkoholkonsum geradestehen soll
MrNiceGuy ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 24.02.2008, 15:09   Nach oben    #3
pago
Projektleiter
 
Registriert seit: 30.11.2005
Ort: Bottrop
Beiträge: 1.091
Standard

Hmm ja okay. In meinem Fall möchte ich eine Möglichkeit haben, um eine Callback-Funktion zu erzeugen, die Zugriff auf lokale Variablen und alle Methoden der Klasse, in der sie definiert wurde, hat.

Sinn macht das z.B. in Kooperation mit array_map und array_reduce.
Einfaches Beispiel in PHP:
PHP-Code:
function square($x) { return $x*$x; }
$data = array(1,2,3,4);
print_r(array_map('square'$data)); 
Nur das ich das ganze in "viel komplexer" brauche (bzw. es wäre schön, das komplexer zu haben, weil die primitive Lösung [anonyme Funktionen] nunmal primitiv und vorallem limitiert ist...).

Wenn dir das beim Verständnis hilft, kann ich dir gern eine genauere Erklärung meiner Motivation geben, aber ich weise mal vorsichtig darauf hin, dass das etwas umfangreicher werden könnte.

Davon ab habe ich einen Alternativen Ansatz gefunden, der in vielen Bereichen besser funktioniert, aber streikt, wenn ich private/protected Methoden aufrufen will (kurz: Ich erzeuge eine weitere Klasse, die den state speichert und zur Verfügung stellt, dann bin ich aber nicht mehr in der Original-Klasse, habe also keinen Zugriff auf private Methoden).
Java bietet via Reflection-API die Möglichkeit, auch private Methoden auszuführen. Kann PHP das auch?
pago ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 24.02.2008, 16:56   Nach oben    #4
robo47
BIN EIN KRASSA HELD!!!111
 
Benutzerbild von robo47
 
Registriert seit: 02.06.2005
Ort: weiher im tiefsten Odenwald
Beiträge: 1.184
Standard

Zitat:
Zitat von pago Beitrag anzeigen
Java bietet via Reflection-API die Möglichkeit, auch private Methoden auszuführen. Kann PHP das auch?
Suchst du die: http://de3.php.net/oop5.reflection ?
Ob sie das kann weis ich nicht.
robo47 ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 24.02.2008, 17:55   Nach oben    #5
pago
Projektleiter
 
Registriert seit: 30.11.2005
Ort: Bottrop
Beiträge: 1.091
Standard

Zitat:
Hinweis: Der Versuch, eine private, protected oder abstract Methode aufzurufen, wird darin enden, dass eine Exception aus der invoke() Methode geworfen wird.
Jo. Dann muss ich mir was anderes überlegen oder die Begrenzung auf öffentliche Methoden in kauf nehmen, falls niemandem sonst noch was einfällt.
pago ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 24.02.2008, 19:19   Nach oben    #6
bobby
Benutzer
 
Benutzerbild von bobby
 
Registriert seit: 09.03.2007
Ort: Nürnberg
Beiträge: 56
Standard

Nur der Vollständigkeit halber: http://schlitt.info/applications/blo...roperties.html

bobby.
bobby ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 24.02.2008, 19:52   Nach oben    #7
MrNiceGuy
Erfahrener Benutzer
 
Benutzerbild von MrNiceGuy
 
Registriert seit: 14.08.2005
Ort: Nienburg / Weser
Beiträge: 662
Standard

Zitat:
Zitat von pago Beitrag anzeigen
Hmm ja okay. In meinem Fall möchte ich eine Möglichkeit haben, um eine Callback-Funktion zu erzeugen, die Zugriff auf lokale Variablen und alle Methoden der Klasse, in der sie definiert wurde, hat.
OK, also ich verstehe das jetzt so, dass du innerhalb einer Klasse eien Callback-Methode schreiben willst, die Zugriff sowohl auf die globalen Variablen der Klasse, als auch auf die Variablen, die in einzelnen Methoden definiert wurden, hat. OK, allerdings kann ich dann nicht so ganz nachvollziehen, warum das Beispiel so kompliziert gestaltet wurde!? Wäre da folgender Weg nicht etwas einfacher?

PHP-Code:
<?php
class test
{
  protected 
$integerY NULL;

  protected function 
methodCallback ($integerX)
  {
    return 
$integerX $this->integerY;
  }
  
  public function 
methodDoSomething ($arrayX$integerY)
  {
    
$this->integerY $integerY;
    
$arrayResult array_map (array ($this'methodCallback'), $arrayX);
    
$this->integerY NULL;
    return 
$arrayResult;
  }
}
?>
__________________
Paradox ist, wenn jemand für seinen Alkoholkonsum geradestehen soll
MrNiceGuy ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 24.02.2008, 21:51   Nach oben    #8
pago
Projektleiter
 
Registriert seit: 30.11.2005
Ort: Bottrop
Beiträge: 1.091
Standard

Was passiert bei Rekursion? Was ist, wenn zwei Funktionen einen Parameter mit gleichem Namen haben (wobei das das geringere Problem ist, den Namen kann ich ja generieren, so dass der jeweils anders ist)?

Ich mach's kurz und schmerzlos: Ich habe eine funktionale Template-/Programmiersprache, die ich nach PHP kompiliere. Closures wäre ein extrem nützliches Feature, dass ich gern implementieren würde. Die Implementation muss aber generisch sein (d.h. ich muss sie generieren können, ohne irgendwas anpassen zu müssen) und sollte möglichst effizient sein. Von daher geh ich davon aus, dass ich den Kompromiss mit "nur öffentliche Methoden" wählen werde oder das Feature ganz draußen lasse.

Danke für die Hilfe.
pago ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Antwort

Lesezeichen


Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
 
Themen-Optionen

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist An.
Smileys sind An.
[IMG] Code ist An.
HTML-Code ist Aus.
Trackbacks are An
Pingbacks are An
Refbacks are Aus

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
PHP 5.2 Kompilierung schlägt fehl Byrel Tools, Server, Betriebssysteme 0 03.11.2006 21:09
[Rezension] PHP 5 Kochbuch Artemis Literatur 2 07.09.2006 19:15
PHP 5.1.5, PHP 4.4.4 und PHP 5.2.0 RC2 veröffentlicht Ben Nachrichten 2 01.09.2006 16:05
PHP 5.1 ist drausen robo47 Nachrichten 5 28.11.2005 20:30
Neue PHP "release candidates": PHP 4.4.2 RC 1 und PHP 5.1 RC 6 Ben Nachrichten 1 21.11.2005 20:48


Alle Zeitangaben in WEZ +2. Es ist jetzt 12:01 Uhr.

Nach oben
Wir nutzen das Zend Framework, vBulletin (vBulletin v3.7.3, Copyright ©2000-2008, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.0.0) und vBSEO.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44