Jump to content
php.lv forumi

Kā PHP izveidot funkciju ķēdēšanu (chaining).


codez

Recommended Posts

Kā PHP izveidot funkciju ķēdēšanu kā tas ir jQuery?

Pavisam vienkārši.

Tam par palīgu mēs ņemam OOP maģiskās metodes __call un __toString;

Parādīšu piemēru, kurš pielāgots string apstrādei, bet idejiski, nedaudz pielāgojot, var strādāt arī ar array-iem vai pat objektiem.

 

<?php
class Chain{
 public $s;
 function __construct($s){
   $this->s=$s;
 }
 function __call($n,$p){   
   $this->s=call_user_func_array($n,array_merge(array($this->s),$p));
   return $this;
 }  
 function __toString(){
   return (string)$this->s;
 }
 function out(){
   echo $this->s;
   return $this;
 }
 function br(){
   $this->s.='<br />';
   return $this;
 }
}
function C($s){
 $ch = new Chain($s);
 return $ch;
}

 

Sākam ar to, ka mums ir klase Chain un funkcija C.

Viss sākas ar funkcijas C izsaukšanu, kura izveido Chain objekta instanci un to inicializē ar stringu un atgriež.

Šo varētu realizēt arī ar OOP maģisko funkciju __invoke, kas mums tad ļautu izsauk klasi šādi Chain(), bet šī funkcija ir tikai no PHP 5.3, kas vēl daudzās vietās (hostingos, utt) nav pieejams.

 

Tālāk klasē Chain ir maģiskā metode __call, kura tiek izsaukta tad, ja tiek mēģināts izsukt metodi, kura neeksistē. Pirmais parametrs ir metodes nosaukums, otrais ir parametru masīvs.

Tad mēs ņemam un izsaucam tādu funkciju, kāda metode ir mēģināta izsaukt un pie pramatriem priekšā vēl pieleikam mūsu stringu, jo string funkcijām pirmais parametrs ir apstrādājamais strings.

Un galā atrgiežam pašu klases instanci $this, lai varētu tālāk izsaukt nākamo metodi.

 

Vēl izveidojam __toString funkciju, kas tiks izsaukta gadījumā, ja objektu mēģinās izmantot kā stringu, piem. pie echo. Šī funkcija atgriež mūsu objekta glabāto stringu.

 

Tālāk varam izveidot kaudzi metožu, kuras apstrādā stringu, šijā piemērā:

out() - izvada stringu.

br() - pievieno br tagu, lai izvadod strings būtu jaunā rindā.

 

 

Rezultātā mēs ar stringu varam strādāt sekojošā veidā:

 

C(' <b>hello</b> ')->trim()->htmlentities()->br()->out(); //<b>hello</b><br />
echo C('Hello World')->strtolower()->br(); //hello world<br />
echo C('Hello World')->substr(0,5)->strtoupper()->br(); //HELLO<br />

 

 

Šādu cahining mehānismu mēs varam izmantot dažādās vietās:

- gan būvējot db abstrakcija slāni, lai kveriju varētu būvēt query()->select('*')->from('users')->where('id=5');

- gan veidojot html helperus html()->div()->ol(li('menu1'),li('menu2'));

Link to comment
Share on other sites

Jāpieliek masīvu supports parametros kombinācijā ar php5.3 būs smuki:

C(array('a', 'b', 'c')).br();
C(array('a', 'b', 'c')).each(function(a,b,c,d,...){
...do_some_work...
/* vajadzētu izdomāt, kā piedabūt $this->* te darbosies? */
});

 

Btw, ir kāds iemesls, kāpēc

 $ch = new Chain($s);
 return $ch;

 

nevis

 

 return new Chain($s);

?

Edited by marrtins
Link to comment
Share on other sites

Jāpieliek masīvu supports parametros kombinācijā ar php5.3 būs smuki:

C(array('a', 'b', 'c')).br();
C(array('a', 'b', 'c')).each(function(a,b,c,d,...){
...do_some_work...
/* vajadzētu izdomāt, kā piedabūt $this->* te darbosies? */
});

 

Šijā gadījumā man šķiet, ka varētu pat strādāt šāds:

C(array(1,2,3)).array_map(function($el){
});

bet anonīmās callback funkcijas tikai no PHP 5.3

 

Btw, ir kāds iemesls, kāpēc

 $ch = new Chain($s);
 return $ch;

 

nevis

 

 return new Chain($s);

?

Testējot domāju, ka nāksies vēl to $ch kaut kā inicializēt un apstrādāt, bet beigās sanāca, ka vienkāršā variantā nevajag, tāpēc palika tāds.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...