2011-03-17 29 views
4

jQuery中,你可以寫類似php回調(如jQuery)?


$(selector).bind('click', function(e) { 
     // something was true - do these actions. 
}); 


我在想,如果在PHP,你可以沒有使用eval類似的東西。

這樣的事情?我知道這不會工作順便說一句。


class act{ 
    public function bind($pref, $callback) { 

     if($pref == 'something') { 
      // return and perform actions in $callback? 
      eval($callback); 
     } 
    } 
} 

你們有些人可能會問這是什麼需要?那麼我試圖簡化我的代碼,而不使用這麼多的if語句。


$act = new act; 

$act->bind('something', function(e) { 
     echo 'this was the php code to run in the callback'; 
}); 

上面的代碼可以避免使用一堆if語句。


$act = new act; 

if($act->bind('something')) { 
     // bind returned true so do this? 
} 

我知道你可以使用ob_get_contents來返回evaled代碼,但是ewww。


ob_start(); 
eval('?> ' . $callback . '<?php '); 
$evaled = ob_get_contents(); 
ob_end_clean(); 

return $evaled; 
+0

檢查我張貼在我的答案例如,它正是你想要什麼 – dynamic 2011-03-17 22:31:04

回答

4
if($pref == 'something') { 
     // return and perform actions in $callback? 
     call_user_func($callback); 
} 

call_user_func你想要做什麼,你甚至可以傳遞參數

http://it.php.net/call_user_func

function g($msg,$func){ 
    echo $msg; 

    call_user_func($func); 
} 

g('hello',function(){echo 'hello2';}); 

// prints: hellohello2 
+0

這是PHP 5.3 +正確的嗎? – kr1zmo 2011-03-17 22:32:55

+0

這不是一個有風險的安全解決方案嗎? – 2011-03-17 22:38:26

+0

那是你的代碼,沒有人可以注入一個功能 – dynamic 2011-03-17 22:40:10

1

如果要將多個參數傳遞給回調函數,請使用call_user_func_array,與前面提到的call_user_func類似,但作爲第二個參數,它需要一個參數數組。

$functionName = 'foo'; 
$functionArgs = array('bar', 'baz'); 
call_user_func_array($functionName, $functionArgs); 

或者,您可以傳遞一個匿名函數,而不是函數名稱。

$functionBody = function($arg1, $arg2){ 
     echo $arg1 . $arg2; 
    }; 
$functionArgs = array('bar', 'baz'); 
call_user_func_array($functionBody, $functionArgs); 

匿名函數可以像本例中那樣作爲變量傳遞,也可以直接作爲參數聲明。

1

PHP 5.3實際上添加了匿名函數,所以你基本上可以將一個函數作爲參數傳遞給另一個函數調用並從那裏執行它。

http://php.net/manual/en/functions.anonymous.php

$callback = function($name){ 
    printf("Hello %s\r\n", $name); 
}; 

$act->bind('test', $callback); 
1

其他的答案是偉大的,到目前爲止,但看到你的主要興趣是在活動,我會告訴你如何做到這一點,與串聯起來(獎金!)。

/** 
* jQuery events+chaining prototype. 
*/ 
class pQuery { 

    /// PROTECTED PROPERTIES /// 

    /** 
    * @var array Holds list of event=>callbacks items. 
    */ 
    protected $events=array(); 

    /// PROTECTED UTILITY METHODS /// 

    /** 
    * Creates an anonymous function compatible with PHP 4+. 
    * <b>IMPORTANT</b> It is likely functions made this way are not garbage collected. 
    * @param $funcCode string Function decleration, including the body. 
    * @return string The newly created function's name. 
    */ 
    protected static function mk_anonFunc($funcCode){ 
     static $counter=0; 
     $func='pQanon'.(++$counter); 
     @eval('function '.$func.'('.substr($funcCode,9)); 
     if(!function_exists($func)) 
      die('Fatal: Anonymous function creation failed!'); 
     return $func; 
    } 

    /** 
    * Detects whether a string contains an anonymous function or not. 
    * @param $funcCode string Function decleration, including the body. 
    * @return boolean True if it does contain an anonymous function, false otherwise. 
    */ 
    protected static function is_anonFunc($funcCode){ 
     return strpos($funcCode,'function(')!==false; 
    } 

    /// PUBLIC METHODS /// 

    /** 
    * Bind event callback to this jQuery instance. 
    * @param string $event The event name, eg: 'click'. 
    * @param string|array $callback A function or a class/instance method, eg: 
    *  'myFunc' OR array('myClass','myMtd') OR array($obj,'myMtd'). 
    * @return pQuery Chaining. 
    */ 
    public function bind($event,$callback){ 
     if(self::is_anonFunc($callback)) 
      $callback=self::mk_anonFunc($callback); 
     if(!isset($this->events[$event])) 
      $this->events[$event]=array(); 
     $this->events[$event][]=$callback; 
     return $this; 
    } 
    /** 
    * Unbind event callback from this jQuery instance. 
    * @param string $event The event name, eg: 'click'. 
    * @param string|array $callback A function or a class/instance method, eg: 
    *  'myFunc' OR array('myClass','myMtd') OR array($obj,'myMtd'). 
    * @return pQuery Chaining. 
    */ 
    public function unbind($event,$callback){ 
     if(!isset($this->events[$event])){ 
      if(($pos=array_search($callback,$this->events[$event]))!==false) 
       unset($this->events[$event][$pos]); 
     } 
     return $this; 
    } 
    /** 
    * Trigger event, calling all related callbacks. 
    * @param string $event The event name to trigger, eg: 'click'. 
    * @param array $params Optional array of arguments to pass to callback. 
    * @return pQuery Chaining. 
    */ 
    public function trigger($event,$params=array()){ 
     if(isset($this->events[$event])) 
      foreach($this->events[$event] as $callback) 
       call_user_func_array($callback,$params); 
     return $this; 
    } 
} 

/** 
* Allows us to use factory-singleton pattern. 
* @return pQuery The $pQuery instance. 
*/ 
function pQuery(){ 
    global $pQuery; 
    if(!isset($pQuery)) 
     $pQuery=new pQuery(); 
    return $pQuery; 
} 

這裏去一個例子:

// instantiate pQuery 
// Note: to use it like jQuery does, do it as follows 
// and then simply use "global $pQuery;" wherever you want it. 
$pQuery = new pQuery(); 

// declare some sample callbacks 
function start(){ echo 'start'; } 
function stop(){ echo 'stop'; } 

// bind some stuff and call start 
$pQuery->bind('start','start') 
     ->bind('stop','stop') 
     ->trigger('start'); 

// bind more stuff and call click 
$pQuery->bind('click','function(){ echo "clicked"; }') 
     ->bind('custom','function(){ echo "custom"; }') 
     ->bind('click','function(){ echo "clicked2"; }') 
     ->trigger('click',array($pQuery,'arg2','arg3')); 

// call end 
$pQuery->trigger('stop'); 
+0

非常令人印象深刻的先生Sciberras – kr1zmo 2011-03-17 22:41:35

+0

歡迎!希望你喜歡它,就像我在使用它時一樣。順便說一下,這是K2F PHP框架中的標準事件機制(包括其他類似架構的東西):https://github.com/uuf6429/K2F – Christian 2011-03-17 22:49:20

+0

有沒有辦法在$ pQuery-> bind ('click',$ act-> run('1')); – kr1zmo 2011-03-17 23:02:48