ugrás a tartalomhoz

callback függvény - PHP bug?

H.Z. v2 · 2011. Júl. 22. (P), 06.02
preg_replace_callback-et próbáltam használni, akkor futottam bele egy érdekességbe: ha egy metódusból használom, adódnak vele gondok. Gondolom, ezek érvényesek valamennyi callback fv.-t használó eszközre.
Anonim callback függvényből nem tudok példányváltozóra hivatkozni, mert
"PHP Fatal error: Using $this when not in object context in..."
üzenetet kapok.
Az már csak a user notes-okból derült ki, hogy statikus metódusra sem lehet a self::metodus() formában hivatkozni, csak Osztálynév::metodus() működik.

Van erre a működésre valami ésszerű magyarázat?
 
1

callback pseudo-type

tiku I tikaszvince · 2011. Júl. 22. (P), 08.11
remélem jól értem a problémádat, ha igen akkor goto manual:
http://www.php.net/manual/en/language.pseudo-types.php#language.types.callback

Callback-ként nem csak függvény nevet adhatsz át, hanem tudsz hivatkozni egy osztály metódusára, egy példányosított objektum metódusára

Függvény call_user_func('my_callback_function')
Statikus metódus call_user_func(array('MyClass', 'myCallbackMethod'));
Objektum metódus call_user_func(array($obj, 'myCallbackMethod'));; itt ugye $obj helyére akár írhatsz $this-t is.

A preg_replace_callback esetén ezek persze így módosulnak
Függvény preg_replace_callback( $pattern, 'my_callback_function')
Statikus metódus preg_replace_callback( $pattern, array('MyClass', 'myCallbackMethod'));
Objektum metódus preg_replace_callback( $pattern, array($obj, 'myCallbackMethod'));
2

Szerintem nem jól érted.

H.Z. v2 · 2011. Júl. 22. (P), 08.26
Szerintem nem jól érted. :-)
Tudom használni (doksit is megnéztem), csak nem értem, hogy miért úgy van, ahogy...
Hogy miért gondolja a PHP egy objektum metódusában meghívott anonim callback függvény belsejében, hogy nem objektumban van?
3

kontextus

Poetro · 2011. Júl. 22. (P), 10.11
Ha általánosan nézed a callback függvényeket, akár melyik nyelvben, akkor látható, hogy azok általában más kontextusban futnak, mint ahol át lettek adva, ezért a $this ezekben nem, vagy máshogy érhető el. Főleg azok a nyelvek érintettek ahol a metódus és az objektum között csak gyenge a kapcsolat. Mondjuk jó lenne látni, hogyan is próbáltad meghívni a preg_replace_callback függvényt (lambda függvénnyel, stringet adsz át, tömböt adsz át, függvényt adsz át).
4

Nálam az OOP környezet

H.Z. v2 · 2011. Júl. 22. (P), 10.37
Nálam az OOP környezet egyelőre a Java-t, esetleg a ruby-t jelenti, ezekben meg ugye minden objektum.

$res=preg_replace_callback('valami minta',
    function($m){
            if(array_key_exists($m[0],$this->tombom)){ ... }
    },
    $atomb);
Valahogy így. Emlékezetből írom, mert még tegnap átírtam olyanra, ahogy működik is.
---
Próbálom reprodukálni a tegnapi verziót, de egészen más hibákat kapok... :(
5

Closure

Poetro · 2011. Júl. 22. (P), 10.42
A fenti anonymous függvény tud a környezetéről. Amennyiben használni akarod a closure valamelyik változóját, akkor a függvényt úgy is kell deklarálni:
<?php
class A {
  public $value = 'b';

  function replace() {
    $that = $this;

    return preg_replace_callback('/a/', function ($m) use (&$that) {
      return $that->value;
    }, 'acacac');
  }
}
$a = new A();
print $a->replace();
Bár úgy tűnik így se tud hozzáférni csak az osztály változóihoz, az objektuméhoz nem, maximum ha azokat explicit átadod. Például
<?php
class A {
  protected $value = 'b';

  function replace() {
    $value = $this->value;

    return preg_replace_callback('/a/', function ($m) use ($value) {
      return $value;
    }, 'acacac');
  }
}
$a = new A();
print $a->replace();
Note: It was not possible to use $this from anonymous function before PHP 5.4.0.

Anonymous functions
6

Köszi, de akkor visszatértünk

H.Z. v2 · 2011. Júl. 22. (P), 11.01
Köszi, de akkor visszatértünk az eredeti kérdéshez: ennek van valami konkrét oka vagy csak idő hiányában/lustaságból/etc. lett ilyen, oszt jónapot? ;-)


Nálam csak 5.3 van, itt egyszerűen elhajt, ha a $this-re próbálok közvetlenül hivatkozni.
Példány metódust is úgy kellett meghívni, hogy a callback helyére egy array($this,"metódusnév") paramétert írok.
Szóval működik, csak gusztustalan. :-)
7

anonymous függvények

Poetro · 2011. Júl. 22. (P), 11.08
Az anonymous függvény még igen csak friss nyelvi elem (5.3-ban vezették be), ezért még nem mondanám kiforrottnak. majd 1-2 év múlva térjünk vissza a kérdésre :-). Valószínűleg ez is egyelőre inkább megerőszakolása a nyelvnek, akárcsak az objektumok, amik ugyan már egyre jobban működnek, de még mindig nem tökéletesek.
8

:-)

H.Z. v2 · 2011. Júl. 22. (P), 11.36
OK, erre voltam kíváncsi.
(1-2 év... hol leszek én már akkor... ;-) )
9

Ne használj anonim

inf · 2011. Júl. 22. (P), 20.29
Ne használj anonim függvényeket, akkor nem lesz ilyen gondod. Egyszerűbb, ha adsz neki szép nevet, hogy mit csinál...
10

Hát ezek után legalábbis

H.Z. v2 · 2011. Júl. 22. (P), 20.43
Hát ezek után legalábbis csökkenteni fogom a használatukat. :-)
11

A másik, hogy performanciában

deejayy · 2011. Júl. 24. (V), 21.06
A másik, hogy performanciában csökkenést fog okozni, ha anonim függvényeket használsz nevesítettek helyett (ahányszor belefut a kódban, annyiszor kell függvény definiálni, nem csak egyszer, mint az utóbbinál).
12

Ez tény vagy vélemény? Elég

tgr · 2011. Júl. 24. (V), 23.27
Ez tény vagy vélemény? Elég nagy bénaság lenne a compiler részéről...
13

Én arra szavazok, hogy tény.

kuka · 2011. Júl. 25. (H), 09.21
Én arra szavazok, hogy tény. Személyesen abba futottam bele, hogy ciklusban használt anonim függvény fölzabálta a memóriát, ha viszont volt neve akkor normálisan működött. Valahol azt a magyarázatot találtam rá, hogy az értelmezőnek nincs támpontja arra nézve, hogy mikor szabadítsa fel az anonim függvények lokális változóit, ezért csak a futás végén teszi. Ennek elméletileg csak akkor volna értelme, ha nem hozná őket létre újra és újra. Viszont a lefejelt (és fél napig szívott) furcsaság csak akkor jöhetett elő, ha valóban minden alkalommal újra létrehozta az anonim függvényt.
14

Egyszerű, tedd ciklusba a két

deejayy · 2011. Júl. 25. (H), 09.49
Egyszerű, tedd ciklusba a két verziót és meglátod. Egyébként ha jól emlékszem nem jelentős a különbség, de van és mérhető.
15

Az anon függvényekből (ha jól

prom3theus · 2011. Júl. 25. (H), 13.20
Az anon függvényekből (ha jól tudom) objektumot csinál a PHP és az objektumot hívja meg függvényként (aminek hatására az objektum egy mágikus metódusa kapja meg a vezérlést, abban pedig az anon fgv. kódja van). Gyaníthatóan minden iterációkor létrehoz egy új példányt.