Closures und Rekursion
Tom
- php
0 1UnitedPower0 tami0 Tom0 tami0 1UnitedPower
0 tami0 molily0 Closures und Rekursion. into the depth
Tom
Hello Nüsseknacker,
es ist zwar noch nicht wieder Weihnachten, aber ich habe hier eine Nuss, die ich einfach, doppelt, dreifach, nicht geknackt bekomme. An etlichen "kleinen Problemchen" hatte ich vorbei geschaut und habe sie inzwischen durch Nachdenken oder Probieren (...) gelöst. Hinterher ist ja auch Alles ganz leicht.
Kaum macht man es richtig, schon funktioniert es
Bevor ich das Forum jetzt vollmülle mit Code und Erläuterungen dazu, erstmale meine Frage, ob denn überhaupt jemand sich der Frage annehmen mag?
"Programmers Summary"
---------------------
Es existiert eine Datei im PHP-Ini-Format
Diese Datei wird mittels parse_ini_string() einwandfrei eingelesen
Die Daten werden verändert.
Die Datei soll nun zurückgeschrieben werden
Besondere Schwierigkeiten:
Mittels einer Hauptfunktion und einer rekursiven (beide global) funktioniert die Lösung inzwischen
Überträgt man die Lösung auf Stammfunktion und Closure (für den rekursiven Teil), treten Fehler auf.
Wer mag mir beim "Programmers Improvement" helfen?
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Meine Herren!
Ich habe mal ein minimalistisches Beispiel für einen Closure gebastelt, dessen innere Funktion rekursiv arbeitet:
<?php
$outer = function ( $n ) {
echo "Outer\n";
$times = 0;
$inner = function () use ( &$times, &$inner, $n ) {
echo "Inner : ${times}\n";
$times++;
if ( $times < $n ){
$inner();
}
};
return $inner;
};
$inner = $outer(4);
$inner();
?>
Die äußere Funktion liefert eine rekursive Funktion, die $n mal rekursiv absteigt.
hi,
auch schön Douglas Crockforst memoizer:
var memoizer = function (memo, formula) {
var recur = function (n) {
var result = memo[n];
if (typeof result !== 'number') {
result = formula(recur, n); memo[n] = result;
}
return result;
};
return recur;
};
var fibonacci = memoizer([0, 1], function (recur, n) {
return recur(n - 1) + recur(n - 2);
});
mfg
tami
Meine Herren!
auch schön Douglas Crockforst memoizer.
Das ist aber Javascript ;) Wie der Autor "Douglas Crockford" schon vermuten lässt.
hi,
Meine Herren!
auch schön Douglas Crockforst memoizer.
Das ist aber Javascript ;) Wie der Autor "Douglas Crockford" schon vermuten lässt.
Jo. Aber Closures sind Closures, oder? ;-) Danke aber für den Themenwechsel, das stimmt schon.
mfg
tami
Hello UP,
Ich habe mal ein minimalistisches Beispiel für einen Closure gebastelt, dessen innere Funktion rekursiv arbeitet:
<?php
$outer = function ( $n ) {
echo "Outer\n";
$times = 0;$inner = function () use ( &$times, &$inner, $n ) {
echo "Inner : ${times}\n";
$times++;
if ( $times < $n ){
$inner();
}};
return $inner;
};$inner = $outer(4);
$inner();
?>
>
> Die äußere Funktion liefert eine rekursive Funktion, die $n mal rekursiv absteigt.
Soll ich alter Knacker das noch ohne jegliche Funktionsbeschreibung verstehen?
Ich sehe ja noch nicht einmal (mit Ausnahme der Referenzen), was das mit meinem Problem zu tun haben könnte...
Es wäre also außerordentlich nett von Dir, wenn Du
- Aufgabenstellung
- Skizzierung des Lösungsweges
- Erläuterungen: warum wurde was wie erledigt?
beifügen könntest.
Es wäre mMn dann auch außerordentlich hilfreich, daraus einen Wiki-Artikel zu erzeugen. Meinst Du, dass wir das hier zusammen gebacken bekommen?
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
![](http://selfhtml.bitworks.de/Virencheck.gif)
--
☻\_
/▌
/ \ Nur selber lernen macht schlau
<http://bikers-lodge.com>
hi,
Hello UP,
Ich habe mal ein minimalistisches Beispiel für einen Closure gebastelt, dessen innere Funktion rekursiv arbeitet:
<?php
$outer = function ( $n ) {
echo "Outer\n";
$times = 0;$inner = function () use ( &$times, &$inner, $n ) {
echo "Inner : ${times}\n";
$times++;
if ( $times < $n ){
$inner();
}};
return $inner;
};$inner = $outer(4);
$inner();
?>
> >
> > Die äußere Funktion liefert eine rekursive Funktion, die $n mal rekursiv absteigt.
>
> Soll ich alter Knacker das noch ohne jegliche Funktionsbeschreibung verstehen?
Jo.
<https://forum.selfhtml.org/?t=217315&m=1492340> zum Thema "use".
Der Rest ist doch im Code drin. Einfach ausführen und fertig ...;
Outer
Inner : 0
Inner : 1
Inner : 2
Inner : 3
mfg
tami
Meine Herren!
Soll ich alter Knacker das noch ohne jegliche Funktionsbeschreibung verstehen?
Ich dachte das Beispiel wäre trivial für jemanden, der Erfahrung mit Closures und Rekursion hat. Manchmal überschlägt man sich eben selber, wenn man eingefleischtes Gelerntes versucht zu erklären.
Ich sehe ja noch nicht einmal (mit Ausnahme der Referenzen), was das mit meinem Problem zu tun haben könnte...
Und das könnte daran liegen, dass deine Problembeschreibung nicht auf dein Problem passt :P Ein Closure ist eine Funktion, die als Rückgabewert eine weitere Funktion liefert. Das Grundgerüst eines Closures, wie es auch in meinem Beispiel vorkommt ist:
$outer = function(){
$inner = function(){
}
return $inner;
}
Ich bin nun davon ausgegangen, dass das Problem darin liegt, dass die innere Funktion rekursiv arbeiten soll. Das Problem dabei ist, dass die innere Funktion anonym ist, weshalb es notwendig ist, ihr die Referenz auf sich selbst ausdrücklich bekannt zu machen.
$outer = function(){
$inner = function() use (&$inner) {
$inner(); // ACHTUNG: Endlosrekursion
}
return $inner;
}
Um Endlosrekursion zu vermeiden, habe die Variable $times eingeführt, die Zählen soll, wie häufig die innere Funktion aufgerufen wird:
$outer = function(){
$times = 0;
$inner = function() use( &$inner, &$times ){
$times++;
if ( $times < 5 ){
$inner();
}
}
return $inner;
}
Um dem Beispiel mehr Würze zu geben, habe ich die Häufigkeit, wie oft abgestiegen werden darf über den Parameter $n steuerbar gemacht:
$outer = function( $n ){
$times = 0;
$inner = function() use( &$inner, &$times, $n ){
$times++;
if ( $times < $n ){
$inner();
}
}
return $inner;
}
Die Funktionen sollten dann auch ausgeführt werden:
$inner = outer( 5 );
$inner();
Die Variablennamen an dieser Stelle waren ungünstig gewählt. $innerIntance
wäre passender gewesen.
Um zu illustrieren welche Funktion, wann aufgerufen wird, habe ich die Ausgabe reingepackt:
$outer = function ( $n ) {
echo "Outer\n";
$times = 0;
$inner = function () use ( &$times, &$inner, $n ) {
echo "Inner : ${times}\n";
$times++;
if ( $times < $n ){
$inner();
}
};
return $inner;
};
PS: Eine Eigenart dieses Beispiels, die nicht besonders intuitiv ist, dass die innere Funktion nur beim ersten Aufruf $n mal rekursiv absteigt und alle weiteren Aufrufe zwar die Variable $timer erhöhen, aber tatsächlich keine rekursiven Aufrufe mehr stattfinden.
Es wäre mMn dann auch außerordentlich hilfreich, daraus einen Wiki-Artikel zu erzeugen. Meinst Du, dass wir das hier zusammen gebacken bekommen?
Dafür habe ich nicht die nötige Zeit. Meines Erachtens nach ist das hier ein gute Artikel über funktionale Programmierweise in PHP: http://code.tutsplus.com/tutorials/functional-programming-in-php--net-35043
Hello,
Und das könnte daran liegen, dass deine Problembeschreibung nicht auf dein Problem passt :P Ein Closure ist eine Funktion, die als Rückgabewert eine weitere Funktion liefert. Das Grundgerüst eines Closures, wie es auch in meinem Beispiel vorkommt ist:
$outer = function(){
$inner = function(){
}
return $inner;
}
Da wird wohl mein Problem liegen.
Kann mir jemand mal ein \_Bild\_ malen vom Gesamtzusammenhang?
Als alter Assembler-Hase bekomme ich immer gleich Panik, wenn ich nicht nachvollziehen kann, was geschehen soll \*ohohoh\*
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
![](http://selfhtml.bitworks.de/Virencheck.gif)
--
☻\_
/▌
/ \ Nur selber lernen macht schlau
<http://bikers-lodge.com>
hi,
Hello,
Und das könnte daran liegen, dass deine Problembeschreibung nicht auf dein Problem passt :P Ein Closure ist eine Funktion, die als Rückgabewert eine weitere Funktion liefert. Das Grundgerüst eines Closures, wie es auch in meinem Beispiel vorkommt ist:
$outer = function(){
$inner = function(){
}
return $inner;
}
>
>
> Da wird wohl mein Problem liegen.
> Kann mir jemand mal ein \_Bild\_ malen vom Gesamtzusammenhang?
~~~php
function funktionsGenerator ($name) {
$sagHallo = function () use ($name) {
echo "hallo: " . $name;
};
return $sagHallo;
};
$meinHalloSager = funktionsGenerator("Noname");
$meinHalloSager();
hallo: Noname
???
mfg
tami
hi,
- Es soll daher Rekursion benutzt werden
http://www.php.net/manual/en/class.recursiveiterator.php
bzw.
http://www.php.net/manual/en/class.recursiveiteratoriterator.php
hilft nix?
mfg
tami
Hello,
- Es soll daher Rekursion benutzt werden
http://www.php.net/manual/en/class.recursiveiterator.php
bzw.
http://www.php.net/manual/en/class.recursiveiteratoriterator.php
hilft nix?
Nee, das schießt übers Ziel hinaus. Beides zieht sich das Mäntelchen der OOP an.
Ich suche nach den Erklärungen im prozeduralen Bereich, warum es nicht fubktioniert, wie man es erwarten könnte (nicht: "würde").
Ich muss schließlich erst einmal mein Drittel- bis Zweidrittelwissen auf Limes 100% pimpem.
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
hi,
Hello,
- Es soll daher Rekursion benutzt werden
http://www.php.net/manual/en/class.recursiveiterator.php
bzw.
http://www.php.net/manual/en/class.recursiveiteratoriterator.php
hilft nix?Nee, das schießt übers Ziel hinaus. Beides zieht sich das Mäntelchen der OOP an.
Es sind schlicht Klassen, damit man damit arbeiten kann, nu ja ...;
Ich suche nach den Erklärungen im prozeduralen Bereich, warum es nicht fubktioniert, wie man es erwarten könnte (nicht: "würde").
Das geht nicht ohne eine schlichten Beispielcode, der alles außen vor lässt, was nicht zum Problem gehört.
mfg
tami
Hi,
Zeigst du uns den Code?
Mathias
Hello,
Zeigst du uns den Code?
Klar, mach ich.
Aber das ist ja eine ganze Entwicklung von Code und "Warums". Und trotzdem ist nix dabei herausgekommen dabei bisher.
Ich bastel jetzt mal, was mMn wirklich relevant war bisher.
Erfahrungsgemäß liegt der Fehler ja genau im ausgeblendeten Teil *tztz*
Melde mich demnächst zurück
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
hi,
Hello,
Zeigst du uns den Code?
Klar, mach ich.
Aber das ist ja eine ganze Entwicklung von Code und "Warums". Und trotzdem ist nix dabei herausgekommen dabei bisher.
Ich bastel jetzt mal, was mMn wirklich relevant war bisher.
Erfahrungsgemäß liegt der Fehler ja genau im ausgeblendeten Teil *tztz*
Das kann ja garnicht sein, wenn Du alles außen vorlässt, was _nicht_ zu Problem gehört. Wenn du dort Fehler machst, ist es wurscht. Du willst doch erstmal Dein Problem lösen ...;
https://forum.selfhtml.org/?t=217478&m=1493987
tami
Hello,
Zeigst du uns den Code?
Hier schon mal das Testscript:
<?php ### parse_ini_file.php ### Ini-File auslesen ### utf-8 ### ÄÖÜäöü
### only for testing
header('Content-Type: text/html; Charset=utf-8');
$source = 'ini_file.dat'; ## Dateiname für die Datendatei
$target = 'ini_file.write.dat'; ## Dateiname für die Ausgabe
$fs = @fopen($source, 'rb+');
$ft = @fopen($target, 'wb+');
#===================================================================================================
function ini_read($fp)
{
if (!$fp) return false;
if (!@flock($fp, LOCK_EX)) return false;
if (false === ($_fstat = @fstat($fp))) return false;
if (false === ($cont = fread($fp, $_fstat['size']))) return false;
if (false === ($_data = @parse_ini_string($cont, true))) return false;
return $_data;
}
#===================================================================================================
function writeparams($_values, $arraykey, $depth, $fp, $maxdepth)
{
foreach ($_values as $key => $param)
{
if ($depth >= 1)
{
$arraykeytxt = $arraykey . "[$key]";
}
else
{
$arraykeytxt = $key;
}
if (is_array($param))
{
$depth++;
if ($depth <= $maxdepth)
{
writeparams ($param, $arraykeytxt, $depth, $fp, $maxdepth);
}
}
else
{
fwrite ($fp, "$arraykeytxt = '$param'" . PHP_EOL);
}
}
return true;
}
#===================================================================================================
function ini_write($fp, $_data, $filename, $maxdepth=3)
{
#---------------------------------------------------------------------------
$writeparams = function ($_values, $arraykey, $depth) use ($fp, $maxdepth, &$writeparams)
{
foreach ($_values as $key => $param)
{
if ($depth >= 1)
{
$arraykeytxt = $arraykey . "[$key]";
}
else
{
$arraykeytxt = $key;
}
if (is_array($param))
{
$depth++;
if ($depth <= $maxdepth)
{
$writeparams ($param, $arraykeytxt, $depth);
}
}
else
{
fwrite ($fp, "$arraykeytxt = '$param'" . PHP_EOL);
}
}
return true;
};
#---------------------------------------------------------------------------
$depth = 0;
$arraykey = '';
foreach ($_data as $section => $_value)
{
if (is_array($_value))
{
fwrite ($fp, PHP_EOL . "[$section]" . PHP_EOL);
if ($depth < $maxdepth)
{
$writeparams ($_value, $_value, $depth);
# writeparams ($_value, $section, $depth, $fp, $maxdepth);
}
}
else
{
fwrite ($fp, "$section = '$_value'" . PHP_EOL);
}
}
}
#==================================================================================================
echo "<pre>\r\n";
if (false === ($_data = ini_read($fs))) echo htmlspecialchars(print_r(error_get_last(),1)) . "\r\n";
else
{
echo htmlspecialchars(print_r($_data,1)) . "\r\n";
ini_write($ft, $_data, $target, 3);
}
echo "</pre>\r\n";
?>
und die Source-Datei:
;### ini_file.dat ### 2014-05-18 13:46:34 ### utf-8 ### ÄÖÜäöü
param1 = eins
param2 = zwei
param3 = drei
[meta]
calls = 9
[active]
0 = braun
1 = rot
2 = grau
3 = blau
4 = violett
5 = grün
6 = orange
7 = gold
[reserve]
0 = weiß
1 = silber
2 = schwarz
3 = gelb
[tom]
alter = 56
wohnung[plz] = 34444
wohnung[ort] = 'Sankt Andreasberg'
wohnung[strasse] = 'Mühlenstraße'
wohnung[hausnummer] = 19
;comm[tel][] = '05582/999378' ; geht nicht, nur eine Array-Tiefe erlaubt
;comm[tel][] = '05582/999362' ; geht nicht, nur eine Array-Tiefe erlaubt
tel[] = '05582/999378'
tel[] = '05582/999362'
Man muss umschalten zwichen der Funktion writeparams() und der Closure $writeparams und sich die Zieldateien ansehen.
Ich würde mich freuen, wenn es nur ein Trivialfehler wäre.
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
hi,
was bringt die eingeschlossene Funtion, was ein Objekt mit privaten und öffentlichen Methoden nicht bringen würde (dort kann man ja dann auf alle Variablen, ob privat oder öffentlich zugreifen)?
Ich vermute, du machst beim Hochzählen was falsch, aber ich sehe den Sinn nicht. Vielleicht molily ja ...;
Das Memoizer-Beispiel macht ja Sinn. Denn da "merkt" sich die Funktion ja intern die bereits erfolgten Berechnungen ...;
mfg
tami
Hello,
was bringt die eingeschlossene Funtion, was ein Objekt mit privaten und öffentlichen Methoden nicht bringen würde (dort kann man ja dann auf alle Variablen, ob privat oder öffentlich zugreifen)?
Bitte halte Dich an die Aufgabenstellung oder heraus :-)
Meine Präambel war ja nicht ohne Sinn in den Raum gestellt.
Du könntest dazu aber einen eigenen Thread eröffnen, der (fast) die Aufgabenstellung erledigt.
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
hi,
Hello,
was bringt die eingeschlossene Funtion, was ein Objekt mit privaten und öffentlichen Methoden nicht bringen würde (dort kann man ja dann auf alle Variablen, ob privat oder öffentlich zugreifen)?
Bitte halte Dich an die Aufgabenstellung oder heraus :-)
Meine Präambel war ja nicht ohne Sinn in den Raum gestellt.Du könntest dazu aber einen eigenen Thread eröffnen, der (fast) die Aufgabenstellung erledigt.
Ich mach doch keine Doppelpostings hier.
"Praktische Closures
Theorie beiseite und ein mal nachgefragt: Sind denn Closures tatsächlich auch nützlich? Finden wir es heraus, indem wir Überlegungen zum praktischen Nutzen von Closures anstellen. Eine Closure erlaubt die Verknüpfung von Daten (aus der Umgebung) mit einer Funktion, die mit diesen Daten arbeitet. Dies hat Ähnlichkeit mit objektorientierter Programmierung, wo Daten über Objekte (die Eigenschaften des Objekts) mit Methoden verknüpft werden."
https://developer.mozilla.org/de/docs/JavaScript/Guide/Closures
Threaddrift, wie Du als einer der dienstältesten Stammposter ja weißt, sind hier übrigens durchaus nicht ungern gesehen, falls überhaupt. Die Frage ist, da PHP ja über Objekte/Klassen mit privaten und öffentlichen Variablen verfügt (anders als Javascript), ob Du mit diesem Beispiel eine sinnvolle Verwendung für eine Closure erstellst. Meine Hypothese: Nein. Es ist zudem, wie Du ja weißt, Sitte im Forum, darauf hinzuweisen, wenn ein "falscher" Ansatz verfolgt wird. Schon gar, wenn das nachher im Wiki landen soll(te).
mfg
tami
hi,
"Praktische Closures
Theorie beiseite und ein mal nachgefragt: Sind denn Closures tatsächlich auch nützlich? Finden wir es heraus, indem wir Überlegungen zum praktischen Nutzen von Closures anstellen. Eine Closure erlaubt die Verknüpfung von Daten (aus der Umgebung) mit einer Funktion, die mit diesen Daten arbeitet. Dies hat Ähnlichkeit mit objektorientierter Programmierung, wo Daten über Objekte (die Eigenschaften des Objekts) mit Methoden verknüpft werden."
https://developer.mozilla.org/de/docs/JavaScript/Guide/Closures
Threaddrift, wie Du als einer der dienstältesten Stammposter ja weißt, sind hier übrigens durchaus nicht ungern gesehen, falls überhaupt. Die Frage ist, da PHP ja über Objekte/Klassen mit privaten und öffentlichen Variablen verfügt (anders als Javascript), ob Du mit diesem Beispiel eine sinnvolle Verwendung für eine Closure erstellst. Meine Hypothese: Nein. Es ist zudem, wie Du ja weißt, Sitte im Forum, darauf hinzuweisen, wenn ein "falscher" Ansatz verfolgt wird. Schon gar, wenn das nachher im Wiki landen soll(te).
Der wesentliche Unterscherschied bei der Memoizer-Funktion https://forum.selfhtml.org/?t=217478&m=1493981 ist ja, dass das Ding eine Funktion zurück gibt und dass eine private Variable in Javascript anders nicht möglich(!) ist.
mfg
tami
hi,
hi,
"Praktische Closures
Theorie beiseite und ein mal nachgefragt: Sind denn Closures tatsächlich auch nützlich? Finden wir es heraus, indem wir Überlegungen zum praktischen Nutzen von Closures anstellen. Eine Closure erlaubt die Verknüpfung von Daten (aus der Umgebung) mit einer Funktion, die mit diesen Daten arbeitet. Dies hat Ähnlichkeit mit objektorientierter Programmierung, wo Daten über Objekte (die Eigenschaften des Objekts) mit Methoden verknüpft werden."
https://developer.mozilla.org/de/docs/JavaScript/Guide/Closures
Threaddrift, wie Du als einer der dienstältesten Stammposter ja weißt, sind hier übrigens durchaus nicht ungern gesehen, falls überhaupt. Die Frage ist, da PHP ja über Objekte/Klassen mit privaten und öffentlichen Variablen verfügt (anders als Javascript), ob Du mit diesem Beispiel eine sinnvolle Verwendung für eine Closure erstellst. Meine Hypothese: Nein. Es ist zudem, wie Du ja weißt, Sitte im Forum, darauf hinzuweisen, wenn ein "falscher" Ansatz verfolgt wird. Schon gar, wenn das nachher im Wiki landen soll(te).
Der wesentliche Unterscherschied bei der Memoizer-Funktion http://forum.de.selfhtml.org/my/?t=217478&m=1493981 ist ja, dass das Ding eine Funktion zurück gibt und dass eine private Variable in Javascript anders nicht möglich(!) ist.
s.a. "Private
Private members are made by the constructor. Ordinary vars and parameters of the constructor becomes the private members.
function Container(param) {
this.member = param;
var secret = 3;
var that = this;
}
This constructor makes three private instance variables: param, secret, and that. They are attached to the object, but they are not accessible to the outside, nor are they accessible to the object's own public methods. They are accessible to private methods. Private methods are inner functions of the constructor.
function Container(param) {
function dec() {
if (secret > 0) {
secret -= 1;
return true;
} else {
return false;
}
}
this.member = param;
var secret = 3;
var that = this;
}
The private method dec examines the secret instance variable. If it is greater than zero, it decrements secret and returns true. Otherwise it returns false. It can be used to make this object limited to three uses.
By convention, we make a private that variable. This is used to make the object available to the private methods. This is a workaround for an error in the ECMAScript Language Specification which causes this to be set incorrectly for inner functions.
Private methods cannot be called by public methods. To make private methods useful, we need to introduce a privileged method."
http://javascript.crockford.com/private.html
Mich würde mal interessieren, wie Closures in PHP überhaupt Sinn machen. Sie nur zu benutzen, damit es kein OOP-"Mäntelchen" gibt, mag vielleicht eine persönliche Entscheidung für "OOP"-"Hasser" sein, das aber hätte im Wiki hier nix verloren. Es gibt keinen Grund, Dinge zu erklären, die man nur machen kann, weil man sie machen kann. Es muss ja einen Vorteil geben. Bei Javscript mag das zB. die Zuweisung einer Funktion zu einem Eventhandler sein, oder die Erzeugung von privaten, memorisierbaren Variablen. All diese Fälle finde ich bei PHP nicht ...;
mfg
tami
Hello tami,
Du hältst Duch nicht an meine Fragestellung.
Sollte ich also noch eine Lösung finden (ich muss dafür ja "nur" in die Sourcecodes einsteigen), werde ich die als "Geheimwissen" für mich behalten.
Kannst Du also erst einmal zum Hauptanliegen zurückfinden und helfen, das Anliegen entweder zu unternmauern oder durch substantiierte Hinweise ad Absurdum zu führen?
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
hi,
Hello tami,
Du hältst Duch nicht an meine Fragestellung.
Sollte ich also noch eine Lösung finden (ich muss dafür ja "nur" in die Sourcecodes einsteigen), werde ich die als "Geheimwissen" für mich behalten.
Kannst Du also erst einmal zum Hauptanliegen zurückfinden und helfen, das Anliegen entweder zu unternmauern oder durch substantiierte Hinweise ad Absurdum zu führen?
Wenn molily das nicht anders sieht: Dein Problem ist nicht sinnvoll mit Closures zu lösen würde ich meinen. S.a. https://forum.selfhtml.org/?t=217478&m=1494003
mfg
tami
Hello,
Wenn molily das nicht anders sieht: Dein Problem ist nicht sinnvoll mit Closures zu lösen würde ich meinen. S.a. https://forum.selfhtml.org/?t=217478&m=1494003
Es geht nicht um die Sinnhaftigkeit, sondern um die Möglichkeit.
Mein Dogma ist immer "halt den Ball flach".
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
hi,
Hello,
Wenn molily das nicht anders sieht: Dein Problem ist nicht sinnvoll mit Closures zu lösen würde ich meinen. S.a. http://forum.de.selfhtml.org/my/?t=217478&m=1494003
Es geht nicht um die Sinnhaftigkeit, sondern um die Möglichkeit.
aha - http://www.99-bottles-of-beer.net/language-perl-737.html
Sowas höre ich nur von Anfängern hier: "ich wills aber so...".
Mein Dogma ist immer "halt den Ball flach".
Der ist mit einer Klasse flacher als alles andere. Sieht man ja: die Klasse funzt, dein Beispiel nicht.
mfg
tami
Hallo,
Mich würde mal interessieren, wie Closures in PHP überhaupt Sinn machen. Sie nur zu benutzen, damit es kein OOP-"Mäntelchen" gibt, mag vielleicht eine persönliche Entscheidung für "OOP"-"Hasser" sein, das aber hätte im Wiki hier nix verloren. Es gibt keinen Grund, Dinge zu erklären, die man nur machen kann, weil man sie machen kann. Es muss ja einen Vorteil geben. Bei Javscript mag das zB. die Zuweisung einer Funktion zu einem Eventhandler sein, oder die Erzeugung von privaten, memorisierbaren Variablen. All diese Fälle finde ich bei PHP nicht ...;
Ich kann mir da schon Fälle vorstellen, wo das ganz nützlich sein kann, und zwar immer dann, wenn mit callbacks gearbeitet wird, die aber gleichzeitig Daten aus dem umgebenden Scope benötigen.
Vergleiche z.b. das Beispiel von dieser Seite zum Sortieren eines Arrays nach einem beliebigen Attribut:
<?php
function sortBy(&$items, $key){
if (is_array($items)){
return usort($items, function($a, $b) use ($key){
return strCmp($a[$key], $b[$key]);
});
}
return false;
}
Die Vergleichsfunktion (function($a, $b)) benötigt Daten aus dem umgebenden Scope ($key).
Natürlich kann man das theoretisch auch anders bauen (man könnte z.b. eine eigene Klasse "Sortable" implementieren, der man dann die benötigten Daten bei der Erzeugung mitgibt o.ä.), aber man spart sich Schreibarbeit, weil man dank Lambda/Closure-Ausdrücken den Callback direkt in den Funktionsaufruf von usort schreiben kann. Macht IMO den Code auch lesbarer, denn man sieht jetzt sofort, dass der Callback zum usort-Aufruf gehört.
Viele Grüße,
Jörg
hi,
Ich kann mir da schon Fälle vorstellen, wo das ganz nützlich sein kann, und zwar immer dann, wenn mit callbacks gearbeitet wird, die aber gleichzeitig Daten aus dem umgebenden Scope benötigen.
Vergleiche z.b. das Beispiel von dieser Seite zum Sortieren eines Arrays nach einem beliebigen Attribut:
<?php
function sortBy(&$items, $key){
if (is_array($items)){
return usort($items, function($a, $b) use ($key){
return strCmp($a[$key], $b[$key]);
});
}
return false;
}
>
> Die Vergleichsfunktion (function($a, $b)) benötigt Daten aus dem umgebenden Scope ($key).
>
> Natürlich kann man das theoretisch auch anders bauen (man könnte z.b. eine eigene Klasse "Sortable" implementieren, der man dann die benötigten Daten bei der Erzeugung mitgibt o.ä.), aber man spart sich Schreibarbeit, weil man dank Lambda/Closure-Ausdrücken den Callback direkt in den Funktionsaufruf von usort schreiben kann. Macht IMO den Code auch lesbarer, denn man sieht jetzt sofort, dass der Callback zum usort-Aufruf gehört.
Jo ;-). Klingt plausibel.
mfg
tami
hi,
hi,
Ich kann mir da schon Fälle vorstellen, wo das ganz nützlich sein kann, und zwar immer dann, wenn mit callbacks gearbeitet wird, die aber gleichzeitig Daten aus dem umgebenden Scope benötigen.
Vergleiche z.b. das Beispiel von dieser Seite zum Sortieren eines Arrays nach einem beliebigen Attribut:
<?php
function sortBy(&$items, $key){
if (is_array($items)){
return usort($items, function($a, $b) use ($key){
return strCmp($a[$key], $b[$key]);
});
}
return false;
}
> >
> > Die Vergleichsfunktion (function($a, $b)) benötigt Daten aus dem umgebenden Scope ($key).
> >
> > Natürlich kann man das theoretisch auch anders bauen (man könnte z.b. eine eigene Klasse "Sortable" implementieren, der man dann die benötigten Daten bei der Erzeugung mitgibt o.ä.), aber man spart sich Schreibarbeit, weil man dank Lambda/Closure-Ausdrücken den Callback direkt in den Funktionsaufruf von usort schreiben kann. Macht IMO den Code auch lesbarer, denn man sieht jetzt sofort, dass der Callback zum usort-Aufruf gehört.
>
> Jo ;-). Klingt plausibel.
Ich finde noch: "Reduce your closure usage for factories
It’s common usage in ZF 2 to handle dependencies through the use of closures as factories in the getServiceConfig of your Module.php class. Instead, you’d better use explicit class factories, and set define the factories in the module.config.php file (in the service\_manager key). This is slightly more efficient (because closures are instantiated, it’s faster to create a string than a closure), allow you to cache config file (closure are not cacheable), and remove the unreadeable Module.php with tons of closures."
<http://www.michaelgallego.fr/blog/2013/01/21/some-tips-to-write-better-zend-framework-2-modules/>
mfg
tami
Hello,
<?php
function sortBy(&$items, $key){
if (is_array($items)){
return usort($items, function($a, $b) use ($key){
return strCmp($a[$key], $b[$key]);
});
}
return false;
}
Ich will nix sortieren!
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
![](http://selfhtml.bitworks.de/Virencheck.gif)
--
☻\_
/▌
/ \ Nur selber lernen macht schlau
<http://bikers-lodge.com>
hi,
Hello,
<?php
function sortBy(&$items, $key){
if (is_array($items)){
return usort($items, function($a, $b) use ($key){
return strCmp($a[$key], $b[$key]);
});
}
return false;
}
>
> Ich will nix sortieren!
1\. Sag das mjerk.
2\. Deshalb macht Dein Beispiel (vermutlich) auch wenig Sinn ...;
Oder vielleicht auch nicht?
<http://jeremycook.ca/2010/08/01/recursive-closures-in-php-5-3/>
Googlen kannst Du ja alleine ...;
mfg
tami
hi,
Ich finde noch: "Reduce your closure usage for factories
It’s common usage in ZF 2 to handle dependencies through the use of closures as factories in the getServiceConfig of your Module.php class. Instead, you’d better use explicit class factories, and set define the factories in the module.config.php file (in the service_manager key). This is slightly more efficient (because closures are instantiated, it’s faster to create a string than a closure), allow you to cache config file (closure are not cacheable), and remove the unreadeable Module.php with tons of closures."
http://www.michaelgallego.fr/blog/2013/01/21/some-tips-to-write-better-zend-framework-2-modules/
und
"However, I prefer factories for mainly readability and maintainability. With factories you don't end up with some massive configuration file with tons of closures all over the place.
Sure, closures are great for rapid development but if you want your code to be readable and maintainable then I'd say stick with factories."
http://stackoverflow.com/questions/19479175/factory-classes-vs-closures-in-zend-framework-2
mfg
tami
hi,
hi,
Ich finde noch: "Reduce your closure usage for factories
It’s common usage in ZF 2 to handle dependencies through the use of closures as factories in the getServiceConfig of your Module.php class. Instead, you’d better use explicit class factories, and set define the factories in the module.config.php file (in the service_manager key). This is slightly more efficient (because closures are instantiated, it’s faster to create a string than a closure), allow you to cache config file (closure are not cacheable), and remove the unreadeable Module.php with tons of closures."
http://www.michaelgallego.fr/blog/2013/01/21/some-tips-to-write-better-zend-framework-2-modules/
und
"However, I prefer factories for mainly readability and maintainability. With factories you don't end up with some massive configuration file with tons of closures all over the place.
Sure, closures are great for rapid development but if you want your code to be readable and maintainable then I'd say stick with factories."
http://stackoverflow.com/questions/19479175/factory-classes-vs-closures-in-zend-framework-2
Und bei einer Suche in den Klassen des Zend-Framework finde ich:
>Internal search for "Closure" in "*.php"
.\Zend\Cache\Pattern\CallbackCache.php:140: if (is_object($callback)) { // Closures & __invoke
.\Zend\Code\Reflection\FunctionReflection.php:95: if ($this->isClosure()) {
.\Zend\Code\Reflection\FunctionReflection.php:236: if ($this->isClosure()) {
.\Zend\Console\Getopt.php:708: public function setOptionCallback($option, \Closure $callback)
.\Zend\Db\Adapter\Driver\Pdo\Pdo.php:270: $rowCount = $sqliteRowCounter->getRowCountClosure($context);
.\Zend\Db\Adapter\Driver\Pdo\Pdo.php:277: $rowCount = $oracleRowCounter->getRowCountClosure($context);
.\Zend\Db\Adapter\Driver\Pdo\Result.php:184: if ($this->rowCount instanceof \Closure) {
.\Zend\Db\Adapter\Driver\Pdo\Feature\OracleRowCounter.php:67: * @return \Closure
.\Zend\Db\Adapter\Driver\Pdo\Feature\OracleRowCounter.php:69: public function getRowCountClosure($context)
.\Zend\Db\Adapter\Driver\Pdo\Feature\SqliteRowCounter.php:67: * @return \Closure
.\Zend\Db\Adapter\Driver\Pdo\Feature\SqliteRowCounter.php:69: public function getRowCountClosure($context)
.\Zend\Db\Sql\Delete.php:98: * @param Where|\Closure|string|array $predicate
.\Zend\Db\Sql\Select.php:276: * @param Where|\Closure|string|array|Predicate\PredicateInterface $predicate
.\Zend\Db\Sql\Select.php:306: * @param Where|\Closure|string|array $predicate
.\Zend\Db\Sql\Update.php:115: * @param Where|\Closure|string|array $predicate
.\Zend\Db\Sql\Predicate\PredicateSet.php:73: if ($predicates instanceof \Closure) {
.\Zend\Db\TableGateway\AbstractTableGateway.php:178: * @param Where|\Closure|string|array $where
.\Zend\Db\TableGateway\AbstractTableGateway.php:189: if ($where instanceof \Closure) {
.\Zend\Db\TableGateway\AbstractTableGateway.php:304: * @param string|array|\Closure $where
.\Zend\Db\TableGateway\AbstractTableGateway.php:362: * @param Where|\Closure|string|array $where
.\Zend\Db\TableGateway\AbstractTableGateway.php:371: if ($where instanceof \Closure) {
.\Zend\Di\Di.php:12:use Closure;
.\Zend\Di\Di.php:705: && $iConfigCurValue instanceof Closure
.\Zend\Di\Di.php:706: && $type !== 'Closure') {
.\Zend\Di\Di.php:707: /* @var $iConfigCurValue Closure */
.\Zend\Di\ServiceLocator.php:12:use Closure;
.\Zend\Di\ServiceLocator.php:85: if ($service instanceof Closure
.\Zend\I18n\Translator\Plural\Symbol.php:12:use Closure;
.\Zend\I18n\Translator\Plural\Symbol.php:105: * @param Closure $getter
.\Zend\I18n\Translator\Plural\Symbol.php:108: public function setNullDenotationGetter(Closure $getter)
.\Zend\I18n\Translator\Plural\Symbol.php:117: * @param Closure $getter
.\Zend\I18n\Translator\Plural\Symbol.php:120: public function setLeftDenotationGetter(Closure $getter)
.\Zend\Paginator\Adapter\DbTableGateway.php:22: * @param null|Where|\Closure|string|array $where
.\Zend\Paginator\Adapter\DbTableGateway.php:25: * @param null|Having|\Closure|string|array $having
.\Zend\ServiceManager\ServiceManager.php:42: * @var string|callable|\Closure|FactoryInterface[]
.\Zend\Stdlib\Hydrator\Strategy\ClosureStrategy.php:12:class ClosureStrategy implements StrategyInterface
.\Zend\Stdlib\Hydrator\Strategy\ClosureStrategy.php:34: * $hydrator->addStrategy('category', new ClosureStrategy(
mfg
tami
Moin tami!
Und bei einer Suche in den Klassen des Zend-Framework finde ich:
Internal search for "Closure" in "*.php" .\Zend\Cache\Pattern\CallbackCache.php:140: if (is_object($callback)) { // Closures & __invoke .\Zend\Code\Reflection\FunctionReflection.php:95: if ($this->isClosure()) { .\Zend\Code\Reflection\FunctionReflection.php:236: if ($this->isClosure()) { .\Zend\Console\Getopt.php:708: public function setOptionCallback($option, \Closure $callback) .\Zend\Db\Adapter\Driver\Pdo\Pdo.php:270: $rowCount = $sqliteRowCounter->getRowCountClosure($context); .\Zend\Db\Adapter\Driver\Pdo\Pdo.php:277: $rowCount = $oracleRowCounter->getRowCountClosure($context); .\Zend\Db\Adapter\Driver\Pdo\Result.php:184: if ($this->rowCount instanceof \Closure) { .\Zend\Db\Adapter\Driver\Pdo\Feature\OracleRowCounter.php:67: * @return \Closure .\Zend\Db\Adapter\Driver\Pdo\Feature\OracleRowCounter.php:69: public function getRowCountClosure($context) .\Zend\Db\Adapter\Driver\Pdo\Feature\SqliteRowCounter.php:67: * @return \Closure .\Zend\Db\Adapter\Driver\Pdo\Feature\SqliteRowCounter.php:69: public function getRowCountClosure($context) .\Zend\Db\Sql\Delete.php:98: * @param Where|\Closure|string|array $predicate .\Zend\Db\Sql\Select.php:276: * @param Where|\Closure|string|array|Predicate\PredicateInterface $predicate .\Zend\Db\Sql\Select.php:306: * @param Where|\Closure|string|array $predicate .\Zend\Db\Sql\Update.php:115: * @param Where|\Closure|string|array $predicate .\Zend\Db\Sql\Predicate\PredicateSet.php:73: if ($predicates instanceof \Closure) { .\Zend\Db\TableGateway\AbstractTableGateway.php:178: * @param Where|\Closure|string|array $where .\Zend\Db\TableGateway\AbstractTableGateway.php:189: if ($where instanceof \Closure) { .\Zend\Db\TableGateway\AbstractTableGateway.php:304: * @param string|array|\Closure $where .\Zend\Db\TableGateway\AbstractTableGateway.php:362: * @param Where|\Closure|string|array $where .\Zend\Db\TableGateway\AbstractTableGateway.php:371: if ($where instanceof \Closure) { .\Zend\Di\Di.php:12:use Closure; .\Zend\Di\Di.php:705: && $iConfigCurValue instanceof Closure .\Zend\Di\Di.php:706: && $type !== 'Closure') { .\Zend\Di\Di.php:707: /* @var $iConfigCurValue Closure */ .\Zend\Di\ServiceLocator.php:12:use Closure; .\Zend\Di\ServiceLocator.php:85: if ($service instanceof Closure .\Zend\I18n\Translator\Plural\Symbol.php:12:use Closure; .\Zend\I18n\Translator\Plural\Symbol.php:105: * @param Closure $getter .\Zend\I18n\Translator\Plural\Symbol.php:108: public function setNullDenotationGetter(Closure $getter) .\Zend\I18n\Translator\Plural\Symbol.php:117: * @param Closure $getter .\Zend\I18n\Translator\Plural\Symbol.php:120: public function setLeftDenotationGetter(Closure $getter) .\Zend\Paginator\Adapter\DbTableGateway.php:22: * @param null|Where|\Closure|string|array $where .\Zend\Paginator\Adapter\DbTableGateway.php:25: * @param null|Having|\Closure|string|array $having .\Zend\ServiceManager\ServiceManager.php:42: * @var string|callable|\Closure|FactoryInterface[] .\Zend\Stdlib\Hydrator\Strategy\ClosureStrategy.php:12:class ClosureStrategy implements StrategyInterface .\Zend\Stdlib\Hydrator\Strategy\ClosureStrategy.php:34: * $hydrator->addStrategy('category', new ClosureStrategy(
Beim besten Willen, weiß ich nicht was ich daraus nun schließen soll. Ist das schlecht oder gut? Schnell oder langsam? Ausdrucksstark oder schleierhaft? Jedenfalls nicht informativ. Ich weiß, dass du sehr gerne auf externe Quellen verweist, aber dieser Thread ist ein Exempel dafür, dass es auch wirklich anstrengend werden kann. Ich bin eigentlich ein geduldiger Mensch, aber irgendwann bin ich hier ausgestiegen. Ich weiß deinen Diskussion-Eifer wirklich zu schätzen, und ich gebe mir Mühe den Verweisen meiner Diskussions-Partner zu folgen, aber du überspannst den Bogen. Es wäre überaus wünschenswert, wenn du deine gewonnen Kenntnisse aggregieren und uns eine antizipierte Fassung davon zukommen lassen würdest. Gerne kannst du deine zusammengetragenen Infos dann an zweitausend Quellen festmachen, aber mute uns bitte nicht zu zweitausend Quellen selber bis ins Detail zu studieren.
--
“All right, then, I'll go to hell.” – Huck Finn
hi,
Beim besten Willen, weiß ich nicht was ich daraus nun schließen soll. Ist das schlecht oder gut?
Du weißt doch das diese Forum zum freien Meinungsaustausch da ist. Niemand ist gezwungen, irgendwelche Beiträge zu lesen. Ich kann auch nie davon ausgehen, dass meine Beiträge von allen verstanden werden.
Die Aussage hier sinngemäß: Es werden Closures offenbar im ZF bentutzt. Wer will, kann sich die passenden Stellen gerne mal anschauen. So wie ich es aus anderen bereits verwiesenen Beiträgen erstehe, handelt es sich u.U. um eine Alternative zu Factory-Methoden. In erwähnten und verlinkten Seiten, bzw. einer, wird die Ansicht vertreten, dass Factory-Methoden versändlicher und leichter wartbar sind.
Der Punkt: es gibt wenn überhaupt dann sinnvolle Anwendungen im ZF. Wen also der sinnhafte Einsatz interessiert, mag da gucken. Das ich das hier erst zur Ansicht geben, wenn ich in der Lage bin, das komplett zusammen zu fassen, magst Du Dir zwar wünschen, aber hör bitte einfach auf zu lesen wenns Dir nicht passt. Ist ein freies Forum!
mfg
tami
hi if(!1UnitedPower) {
read (if ($you->want()):
Die Aussage hier sinngemäß: Es werden Closures offenbar im ZF bentutzt. Wer will, kann sich die passenden Stellen gerne mal anschauen. So wie ich es aus anderen bereits verwiesenen Beiträgen erstehe, handelt es sich u.U. um eine Alternative zu Factory-Methoden. In erwähnten und verlinkten Seiten, bzw. einer, wird die Ansicht vertreten, dass Factory-Methoden versändlicher und leichter wartbar sind.
Der Punkt: es gibt wenn überhaupt dann sinnvolle Anwendungen im ZF. Wen also der sinnhafte Einsatz interessiert, mag da gucken. Das ich das hier erst zur Ansicht geben, wenn ich in der Lage bin, das komplett zusammen zu fassen, magst Du Dir zwar wünschen, aber hör bitte einfach auf zu lesen wenns Dir nicht passt. Ist ein freies Forum!
Als Ergänzung - und nicht als sinnvolle und umfassende Erklärung für 1UnitedPower - falls nicht schon verwiesen hier der Verweis auf php.net: http://www.php.net/manual/de/functions.anonymous.php:
"Anonymous functions, also known as closures, allow the creation of functions which have no specified name. They are most useful as the value of callback parameters, but they have many other uses."
"Closures can also be used as the values of variables; PHP automatically converts such expressions into instances of the Closure internal class."
mfg
tami
hi,
"Anonymous functions, also known as closures, allow the creation of functions which have no specified name. They are most useful as the value of callback parameters, but they have many other uses."
"Closures can also be used as the values of variables; PHP automatically converts such expressions into instances of the Closure internal class."
Heisst also für PHP, dass jede namenlose Funktion zur Klasse closure gehört.
<?php
namespace My;
use Closure;
$test = function() {};
var_dump(get_class($test));
namespace und use sind hier eigentlich sinnlos, denn das Ergebnis bleibt:
string(7) "Closure"
So wie ich das sehe, nutzt das Zend-Framework die anonymen Funktionen wenn überhaupt als Callbackfunktionen oder als Funktionen, die als Paramater an andere übergeben werden (können). Die Kapselung von Variableninhalten spielt dabei u.U. garkeine Rolle.
mfg
tami
hi,
http://de.slideshare.net/melechi/php-53-part-2-lambda-functions-closures-presentation fässt als Slideshow leider nur die Unterschiede von "anonymer Funktion" und "Closure" zusammen und verweist am Ende noch auf die magic-method __invoke, die aus einer Klasse quasi eine Closure macht.
mfg
tami
Hello tami,
function sortBy(&$items, $key){
Ich habe nix sortieren lassen...
Bleib bitte beim Thema!
Ich wette drei (deiner) Lieblingsdrinks gegen 1000 Euro darauf, dass Du meine Aufgabenstellung bisher gar nicht nachgestellt hast.
Ich wollte hier kein "Bla-Bla" sondern gezielte Antworten. Daher auch die Präambel!
Jedes Posting von Dir ohne direkten Bezug darauf ist vorerst sinnfrei. Lass uns doch erst einmal _beweisen_ , dass/warum meine Vorgehensart nicht fruchtet.
Anaschließend werden Deine Ideen sicherlich hilfreich sein, um einen Wikei-Artiklel daraus zu machen.
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
hi,
Hello tami,
function sortBy(&$items, $key){
Ich habe nix sortieren lassen...
Bleib bitte beim Thema!
Ich wette drei (deiner) Lieblingsdrinks gegen 1000 Euro darauf, dass Du meine Aufgabenstellung bisher gar nicht nachgestellt hast.
https://forum.selfhtml.org/?t=217478&m=1494003 ???
mfg
tami
Hello,
Ich mach doch keine Doppelpostings hier.
Und ich möchte keine "anderer Weg Quick Fuck"-Lösung, sondern die Beantwortung der Frage.
OOP bleibt also für die direkte Beantwortung _meiner_ Frage außen vor!
Es steht Dir aber hoffentlich niemand im Wege, wenn Du hier eine komplette Lösung für die Aufgabenstellung in OOP liefern Würdest. Die würde das Forum dann bestimmt auch lobend in das Wiki übernehmen. Aber eben bitte vollständig!
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
hi,
Hello,
Ich mach doch keine Doppelpostings hier.
Und ich möchte keine "anderer Weg Quick Fuck"-Lösung, sondern die Beantwortung der Frage.
- geht, aber so...
- geht, geht nicht, weil ...
OOP bleibt also für die direkte Beantwortung _meiner_ Frage außen vor!
Es steht Dir aber hoffentlich niemand im Wege, wenn Du hier eine komplette Lösung für die Aufgabenstellung in OOP liefern Würdest. Die würde das Forum dann bestimmt auch lobend in das Wiki übernehmen. Aber eben bitte vollständig!
Es muss schon Sinn machen: https://forum.selfhtml.org/?t=217478&m=1494000
mfg
tami
hi,
Hello,
Ich mach doch keine Doppelpostings hier.
Und ich möchte keine "anderer Weg Quick Fuck"-Lösung, sondern die Beantwortung der Frage.
- geht, aber so...
- geht, geht nicht, weil ...
OOP bleibt also für die direkte Beantwortung _meiner_ Frage außen vor!
Es steht Dir aber hoffentlich niemand im Wege, wenn Du hier eine komplette Lösung für die Aufgabenstellung in OOP liefern Würdest.
Die hast Du schon selbst geliefert. Muss man doch nur kurz umstellen:
<?php
// ich würde aber file_get_contents und file_put_contents nehmen meine ich ...
class IniHandler {
private $fp;
private $maxdepth;
public function ini_read($fp)
{
if (!$fp) return false;
if (!@flock($fp, LOCK_EX)) return false;
if (false === ($_fstat = @fstat($fp))) return false;
if (false === ($cont = fread($fp, $_fstat['size']))) return false;
if (false === ($_data = @parse_ini_string($cont, true))) return false;
return $_data;
}
private function writeparams($_values, $arraykey, $depth)
{
foreach ($_values as $key => $param)
{
if ($depth >= 1)
{
$arraykeytxt = $arraykey . "[$key]";
}
else
{
$arraykeytxt = $key;
}
if (is_array($param))
{
$depth++;
if ($depth <= $this->maxdepth)
{
writeparams ($param, $arraykeytxt, $depth, $this->fp, $this->maxdepth);
}
}
else
{
fwrite ($this->fp, "$arraykeytxt = '$param'" . PHP_EOL);
}
}
return true;
}
public function ini_write($fp, $_data, $filename, $maxdepth=3)
{
$this->fp = $fp;
$this->maydepth = $this->maxdepth;
$depth = 0;
$arraykey = '';
foreach ($_data as $section => $_value)
{
if (is_array($_value))
{
fwrite ($fp, PHP_EOL . "[$section]" . PHP_EOL);
if ($depth < $this->maxdepth)
{
$this->writeparams ($_value, $_value, $depth);
# writeparams ($_value, $section, $depth, $fp, $this->maxdepth);
}
}
else
{
fwrite ($fp, "$section = '$_value'" . PHP_EOL);
}
}
}
}
macht auch ggfs. Sinn, die nötigen Daten erstmal dem Konstruktor zu übergeben. Vielleicht aber auch nicht ...;
S.a. http://framework.zend.com/apidoc/2.0/classes/Zend.Config.Reader.Ini.html
mfg
tami
Hello tami,
wenn ich "OOP" benutzen will, benötige cih keine "Closures" mehr.
[...]
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
hi,
Hello tami,
wenn ich "OOP" benutzen will, benötige cih keine "Closures" mehr.
OK, wenn das klar ist, warte ich jetzt nur noch darauf, ob molily oder Sven oder ähnlich kundige Personen hier noch was zum grundsätzlichen Einsatz von Closures zu sagen haben. Memoizer geht übrigens nicht ohne Closures. Liegt aber auch daran, dass PHP eben nur einmal durchläuft und sich in dem Sinne ja nichts merken kann ...; den Memoizer aber kann man öfter bedienen ...; und da lohnt sich die interne Speicherung.
mfg
tami
Hello Nüsseknacker,
dieser Thread wird für mich erst dann zuende sein, wenn mir jemand nachweist, warum ich die anonyme Funktion nebst "use" hier nicht einsetzen durfte!
Ich möchte keine "Alternativlösungen", sondern den Nachweis, dass meine Idee hier Schrott war!
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
hi,
Hello Nüsseknacker,
dieser Thread wird für mich erst dann zuende sein, wenn mir jemand nachweist, warum ich die anonyme Funktion nebst "use" hier nicht einsetzen durfte!
Ich möchte keine "Alternativlösungen", sondern den Nachweis, dass meine Idee hier Schrott war!
"Which One to Use?
There is no correct answer to this question. I would argue that if the process of determining the permissions is quite dependent on the application module, then the object oriented approach is more appropriate. However, if you think that each application module should be able to provide an authentication function, and your AuthPlugin is just a skeleton providing the authentication functionality but without knowing anything about users and procedures, then you can go with the functional approach.
The functional approach makes your AuthPlugin very abstract and you can depend on it. However, if you plan to allow your AuthPlugin to do more and know more about users and your system, then it will became too concrete, and you don't want to depend on it. In that case choose the object oriented way and let the concrete AuthPlugin depend on the more abstract application modules"
Wie von United verlinkt: http://code.tutsplus.com/tutorials/functional-programming-in-php--net-35043
mfg
tami
Meine Herren!
Hello Nüsseknacker,
dieser Thread wird für mich erst dann zuende sein, wenn mir jemand nachweist, warum ich die anonyme Funktion nebst "use" hier nicht einsetzen durfte!
Ich möchte keine "Alternativlösungen", sondern den Nachweis, dass meine Idee hier Schrott war!
Dann lass uns doch mal zusammen Programmieren, Fehlermeldungen auswerten und debuggen.
$foo = "bar";
function outer () {
$inner = function () use ( $foo ) {
};
}
Ergibt:
Notice: Undefined variable: foo in /in/U8sUa on line 8
#0 outer(), called at [/in/U8sUa:13]
#0 at [/in/U8sUa:8]\n #1 outer(), called at [/in/U8sUa:13]
NULL
Aha $foo ist nicht bekannt.
Okay vielleicht müssen wir $foo ja auch der äußeren Funktion bekannt machen:
<?php
$foo = "bar";
function outer () use ( $foo ) {
$inner = function () use ( $foo ) {
var_dump( $foo );
};
$inner();
}
outer();
?>
Ergibt:
Fatal error: syntax error, unexpected T_USE, expecting ';' or '{' in /in/9HWQj on line 4
#0 at [/in/9HWQj:4]
Ah moment. Das use-Keyword gibt es nicht für Funktionsausdrücke, aber für anonyme Funktionen schon.
<?php
$foo = "bar";
$outer = function () use ( $foo ) {
$inner = function () use ( $foo ) {
var_dump( $foo );
};
$inner();
};
$outer();
?>
string(3) "bar"
Tadaa!
Wieso muss man dir eigentlich noch erklären, wir sukzessives Debuggen funktioniert? Du hast doch genug Erfahrung ;)
Hello,
Wieso muss man dir eigentlich noch erklären, wir sukzessives Debuggen funktioniert? Du hast doch genug Erfahrung ;)
Ich weiß zwar nicht, was Du mir mit deinem Beispiel zeigen wolltest, aber der Fehler ist gefunden.
Eigentlich hätte der mich anspringen müssen :-O
[code lang=php]
$writeparams ($_value, $_value, $depth);
# writeparams ($_value, $section, $depth, $fp, $maxdepth);
[code]
[code lang=php]
$writeparams ($_value, $section, $depth);
[code]
Konnte ja nur ein dämlicher Fehler sein *ohoh*
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Meine Herren!
Ich weiß zwar nicht, was Du mir mit deinem Beispiel zeigen wolltest
Ich dachte, dass die anonyme Funktion $writeparams keinen Zugriff auf die Variable $fp hätte. Das hätte sich mit der Fehlermeldung bemerkbar gemacht, die ich im Beispiel provoziert habe. Ich habe nicht gesehen, dass es außer der globalen Variable $fp auch noch den Funktionsparameter $fp gibt. Mein Irrtum.
aber der Fehler ist gefunden.
Fein.
Hello Nüsseknacker und speziell "tami",
Ich möchte keine "Alternativlösungen", sondern den Nachweis, dass meine Idee hier Schrott war!
Wenn ich Dir im Folgenden speziell widersprochen habe, dann nur, weil ich erst einmal die Hauptfrage klären möchte: Habe ich nur einen prophanen Fehler in meinem Lösungsweg, oder steckt dahinter ggf. ein "deep error in contruction"?
Alternativvorschläge sind dann eventuell anschließend sinnvoll.
Lov You
New messages from "dem schönen Oberharz"
(Forumsidee!)
Tom vom Berg
Om nah hoo pez nyeetz, Tom!
New messages from "dem schönen Oberharz"
(Forumsidee!)
??
PS: Die „vielen“ ‚schönen‘ “Anführungszeichen” ‘hast’ «du» »entdeckt«, oder bist du etwa auch mit deaktiviertem JavaScript unterwegs?
Matthias