ugrás a tartalomhoz

Php- függvény hívása a megadott kontextusban

inf · 2009. Nov. 19. (Cs), 01.20
Sziasztok!

Egy függvényt szeretnék meghívni egy objektum kontextusában, vagy átadni neki másik kontextusból adatot.
(kontextus=scope, jobb fordítást nem találtam)

Egyelőre az egyedüli működő megoldás a $GLOBALS használata, ill. php4 alatt létezik olyan, hogy aggregate, viszont nekem php5-ös megoldásra van szükségem.

Tud valaki ilyet?
 
1

Ideiglenes

inf · 2009. Nov. 19. (Cs), 02.57
Egyelőre csinálok egy összekötő osztályt a függvénynek, aminek a konstruktorában megadom a kontextust, mint paramétert, a függvényben pedig erre a paraméterre hivatkozom. Ennek elég nagy hátránya, hogy csak a public dolgokat lehet elérni az adott kontextusban.
2

Példa

gphilip · 2009. Nov. 19. (Cs), 17.08
Hali!

tudnál példát Írni, nem egészen értem. Biztosan van megoldás vagy design pattern erre, pl observer, ha jól gondolom, mit szeretnél.
3

Huhh

inf · 2009. Nov. 28. (Szo), 07.03
Hát nem tudom javascripthez mennyire értesz.

Javascriptben leírva kb ennyit szeretnék megcsinálni phpben:
  1. <script>  
  2. Function.prototype.bind=function (scope)  
  3. {  
  4.     var method=this;  
  5.     return function ()  
  6.     {  
  7.         return method.apply(scope,arguments);  
  8.     };  
  9. };  
  10.   
  11.   
  12. var Class=Function;  
  13. Class.prototype.Create=function (params)  
  14. {  
  15.     var Class=function ()  
  16.     {  
  17.         if (typeof this.initialize=="function")  
  18.         {  
  19.             this.initialize.apply(this,arguments);  
  20.         }  
  21.     };  
  22.       
  23.     for (var param in params)  
  24.     {  
  25.         Class.prototype[param]=params[param];  
  26.     }  
  27.       
  28.     return Class;  
  29. };  
  30.   
  31. var Template=Class.Create(  
  32. {  
  33.     initialize: function (data)  
  34.     {  
  35.         this.data=data;  
  36.     },  
  37.     evaluate: function (code)  
  38.     {  
  39.         eval(code);  
  40.     }  
  41. });  
  42.   
  43.   
  44.   
  45. var Tree=Class.Create(  
  46. {  
  47.     initialize: function (tree)  
  48.     {  
  49.         this.tree=tree;  
  50.     },  
  51.     showRecursive: function (branches,showBranch,showLetter)  
  52.     {  
  53.         var resultString="";  
  54.         for (var i=0,l=branches.length; i<l; ++i)  
  55.         {  
  56.             var branch=branches[i];  
  57.             var isLetter=!("branches" in branch) ||   
  58.                 !(branch.branches instanceof Array) ||   
  59.                 !branch.branches.length;   
  60.             resultString+=isLetter  
  61.                 ?showLetter(branch)  
  62.                 :showBranch(branch,  
  63.                     this.showRecursive(branch.branches,showBranch,showLetter)  
  64.                 );  
  65.         }  
  66.         return resultString;  
  67.     },  
  68.     show: function (showTree,showBranch,showLetter)  
  69.     {  
  70.         return showTree(this.showRecursive(this.tree.branches,showBranch,showLetter));  
  71.     }  
  72. });  
  73.   
  74. window.onload=function ()  
  75. {  
  76.     new Template(  
  77.     {  
  78.         tree:   
  79.         {  
  80.             branches:  
  81.             [  
  82.                 {label: "branch-a",  
  83.                     branches:  
  84.                     [  
  85.                         {label: "letter-a1"},  
  86.                         {label: "letter-a2"},  
  87.                         {label: "branch-a3",  
  88.                             branches:  
  89.                             [  
  90.                                 {label: "letter-a3x"},  
  91.                                 {label: "letter-a3y"}  
  92.                             ]  
  93.                         }  
  94.                     ]  
  95.                 },  
  96.                 {label: "letter-b"},  
  97.                 {label: "branch-c",  
  98.                     branches:  
  99.                     [  
  100.                         {label: "letter-c1"},  
  101.                         {label: "letter-c2"}  
  102.                     ]  
  103.                 }  
  104.             ]  
  105.         },  
  106.         config:  
  107.         {  
  108.             branch:{color: "brown"},  
  109.             letter:{color: "green"}  
  110.         }  
  111.     }).evaluate(  
  112.         "var container=document.createElement('div');"+  
  113.         "document.body.appendChild(container);"+  
  114.           
  115.         "var showTree=function (tree)"+  
  116.         "{"+  
  117.             "return '<ol>'+tree+'</ol>';"+  
  118.         "};"+  
  119.           
  120.         "var showBranch=function (branch,sub)"+  
  121.         "{"+  
  122.             "return "+  
  123.                 "'<li>'+"+  
  124.                     "'<span style=\"color: '+this.data.config.branch.color+'\">'+"+  
  125.                         "branch.label+"+  
  126.                     "'</span>'+"+  
  127.                     "'<ul>'+"+  
  128.                         "sub+"+  
  129.                     "'</ul>'+"+  
  130.                 "'</li>';"+  
  131.         "};"+  
  132.           
  133.         "var showLetter=function (letter)"+  
  134.         "{"+  
  135.             "return "+  
  136.                 "'<li>'+"+  
  137.                     "'<span style=\"color: '+this.data.config.letter.color+'\">'+"+  
  138.                         "letter.label+"+  
  139.                     "'</span>'+"+  
  140.                 "'</li>';"+  
  141.         "};"+  
  142.           
  143.         "var html=new Tree(this.data.tree).show("+  
  144.             "showTree.bind(this),"+  
  145.             "showBranch.bind(this),"+  
  146.             "showLetter.bind(this)"+  
  147.         ");"+  
  148.           
  149.         "container.innerHTML=html;"  
  150.           
  151.     );  
  152. };  
  153. </script>  
A lényege, hogy kapok egy stringet a Template::evaluate-be, amit egy Compiler fordít be sablonkódról php-be. Na most nekem van egy Tree osztályom, amivel meg tudom jeleníteni egy fa tartalmát tetszőleges kinézetben úgy, hogy függvényeket adok át neki. A függvényeknek a Template aktuális példányára kell vonatkozniuk, mert onnan jönnek a konfigurációs, meg egyéb adatok. (Ez csak egy példa külső osztályok használatára sablonon belül...) A Tree::show összedobja a megadott függvények és a fa alapján a kimenetet. Gyakorlatilag ennyi.

Elnézést a stringes, összeadogatós gányolásért, igazából az a rész külön fájlban van php-ben, az az, amit a Compiler kidob, mint php kódot.

Ha nem érthető a dolog, akkor csak szólj, aztán megpróbálom elmagyarázni. :-D


Vázlatosan a lényeg, hogy van egy kódom, amit eval-al meghívok úgy, hogy a Template egy példányának a scope-jában van. Tehát a "this" az a Template egy példánya lesz, aminek már a this.adat változója tárol a adatokat. A kód egy része egy külső osztály: Tree példányosításával foglalkozik. A Tree-nek át kell adni a példányosításnál adatokat, majd a megjelenítéshez a kódban megadott függvényeket. A megjelenítéshez megadott függvényeknek a Template példányának a scope-jában kell futniuk, hogy azok is tudjanak elérni adatokat a this.adat-ból.
Azért van szükség erre a szerkezetre, mert a Compiler minden változó elérést this.adat['változó']-ra fordít le. Szóval ezzel sajnos nem lehet variálni. Nem akarom elmagyarázni, hogy miért nem, mert nagyon bonyolult, a lényeg, hogy a this.adat-ot nem lehet átírni a fordítóban, a fordítón kívül pedig nem szeretném átírni, mert az szintén bonyolult (bár kevésbbé, mint az előző), és gányolás.



Php-ban úgy oldottam meg, hogy létrehozok egy összekötő osztályt, aminek a függvényei lettek a showTree, showBranch, showLetter, a nevét meg a sablonban kell megadni. Az összekötő osztálynál a __get,__set és __call át lett írva, hogy a Template példányra hivatkozzon. Eztán csináltam egy példányt ebből az osztályból, amit szépen átadtam a Tree-nek, és ő nagy kegyesen meghívta a megjelenítő függvényeket rajta. Ami ebben a megoldásban zavaró, hogy minden ilyen külső feldolgozónál egy-egy új osztályt kell létrehoznom. Szal ahányszor meg akarom hívni a Tree megjelenítés részét, annyiszor kell új osztályt létrehoznom. Hálistennek nincs olyan sok külső dolog, viszont ez az egy hívás - egy osztály dolog nagyon zavar. Ezért próbáltam keresni valami megoldást a témára, de sajnos eddig még nem találtam. Php4-ben van olyan, hogy aggregate, az talán segítene, de php5-ben nem lehet használni.
4

Scope

Joó Ádám · 2009. Nov. 28. (Szo), 09.13
kontextus=scope, jobb fordítást nem találtam


Hatókör.
5

Kösz.

inf · 2009. Nov. 28. (Szo), 20.03
Köszi. :-)