2011-05-29 91 views
6

如何在PHP中對javascript函數進行編碼?我想編碼的回調函數與陣列PHP json_encode對函數進行編碼

$options = array(
'title' => 'Title', 
'fnCallback' => someCallback); 

相當於INI的JavaScript

var options = { 
'title': 'Title', 
'fnCallback': someCallback }; 

我知道我的PHP代碼是錯誤的,我怎麼能定嗎?感謝先進。

+0

JSON只允許資本收益。你無法找到它的功能對象。您只能提供函數名作爲字符串,然後處理JavaScript中的分辨率(使用地圖或東西)。什麼是 – mario 2011-05-29 18:43:11

+0

someCallback''應該是什麼?一個常數?因爲只有常數纔可以是這樣的引用。 – Gumbo 2011-05-29 18:43:41

+1

我猜That's someCallback'是一個回調函數。 – mc10 2011-05-29 18:44:57

回答

7

中提琴我解決我的問題Zend_Json編碼

$options = array(
    'title' => 'Title', 
    'fnCallback' => new Zend_Json_Expr('someCallback') 
);  

Zend_Json::encode(
    $options, 
    false, 
    array('enableJsonExprFinder' => true)); 
+0

很高興地看到一些實際的使用ZF的;-)。我去難看和優雅通過添加在php數組 '數據'=> '@ aCallBack()@' 和後json_encode輸出之前,DID str_replace函數( '' @ '' ')和(' @ '', '') 。 PHP4ever。 – Teson 2013-12-07 23:47:50

0

您忘記了'title'和'fnCallback'之間的逗號。

+0

哎呀對不起,這不是目標問題。 someCallback在PHP中是非法的,但不在js中。 – brian 2011-05-29 18:47:13

+0

我知道,但你沒有問爲什麼PHP代碼不工作。應該json_encode – 2011-05-29 18:48:28

+0

是啊,我可以引用功能,但我錯了,我看到@mario – brian 2011-05-29 18:51:57

5

JSON用於傳遞值,它們不適合傳遞代碼段。

但是,您可以傳遞函數名稱或其他有意義的值,並檢索正確的函數以在JavaScript端調用它。

+0

通過返回一個字符串或者解決這個問題,這個目標是使代碼不「乾淨」 $的returnValue =「{‘標題’,‘標題’ 'fnCallback':someCallback}「; – brian 2011-05-29 18:54:51

0

不要爲實際的本地Javascript對象表示法語法(不管名稱)混淆JSON。 Javascript對象可以包含函數引用; JSON不能。

1

爲了使通知消失在PHP中,只寫你的回調函數中引號:

$options = array(
    'title' => 'Title', 
    'fnCallback' => "someCallback"); 

然後當你在Javascript收到JSON,你可以重新映射回調函數的名稱實際JS功能與例如:

json = $.getJSON(..); 
json.fnCallback = window[json.fnCallback]; // for global callbacks 
+0

現在我知道基本的,非常感謝你馬里奧 – brian 2011-05-29 19:03:06

1

這是不可能的,沒有想到一個慣例和自己實現它。

說,你有這樣的JSON

'{"title": "Title", "fnCallback": "someCallback" }' 

那麼你可以做,在客戶端

function wireupCallbacks(jsonObject) { 
    if (typeof jsonObject === "object") { 
    for (var prop in jsonObject) { 
     var callbackName = jsonObject[prop]; 
     if (/Callback$/.test(prop) && typeof callbackName === "string") { 
     if (typeof this[callbackName] === "function") { 
      jsonObject[prop] = this[callbackName]; 
     } 
     } 
    } 
    } 
    return jsonObject; 
} 

,並呼籲在一個對象,它提供了你的回調的上下文中

var someObject = { 
    someCallback: function() { alert("It works!"); } 
} 

var jsonObject = {"title": "Title", "fnCallback": "someCallback" }; 

wireupCallbacks.call(someObject, jsonObject); 

jsonObject.fnCallback(); // alerts "It works!" 

遺失的東西:

  • 當前該功能僅查找名爲"*Callback"的屬性。
  • 沒有後備全局函數(這些的window對象將是屬性)
  • 沒有遞歸(未被訪問到嵌套對象)
  • 沒有JSON陣列處理

添加這些功能是你自己的,這些都不應該很難實現。

+0

漂亮啊,感謝 – brian 2011-05-29 19:04:23

0

這裏是我用來做這個代碼:

//~ [FUNCTION] 
function __json_encode($mVar,$fnCallback="stripcslashes") { 
    return preg_replace_callback('#"[ ]{0,}function[ ]{0,}\([^)$]{0,}\)[ ]{0,}\{[ ]{0,}(?(?![ ]{0,}}[ ]{0,}").){0,}[ ]{0,}\}[ ]{0,}"([(?,")|(?\}{0,}$)]{0,})#si', 
     function ($aRes) use ($fnCallback) { 
      for($aRes[0]=substr($aRes[0],1),$sOut="",$i=0,$iOpen=0,$iClose=0;$i<= strlen($aRes[0]) && $sOut.= substr($aRes[0],$i,1);$i++) 
       if (substr($aRes[0],$i,1) == "{") $iOpen++; 
       else if (substr($aRes[0],$i,1) == "}" AND $iOpen == ++$iClose) break; 
      return is_callable($fnCallback) ? $fnCallback($sOut).$aRes[1] : $sOut.$aRes[1]; 
     },json_encode($mVar) 
    ); 
} 



//~ [TEST] 
print "<script>\n"; 
print sprintf(
    "\tvar oTest = %s;", 
    __json_encode(
     array( 
      "Numeric"=>1, 
      "string"=>"hello world !", 
      "myFunction"=>"function(test) { if (test==1) { alert('myFunction(1)'); return true; } else return false; }", 
      "myObject"=>array(
       "Numeric"=>1, 
       "string"=>"hello world !", 
       "myFunction"=>"function(test) { alert('myFunction(1)'); return true; }") 
     ) 
    ) 
); 
print "\n\tif (oTest.myFunction(1) == false) alert('myFunction(0)');"; 
print "\n\tif (oTest.myObject.myFunction(0) == false) alert('myFunction(0)');"; 
print "\n</script>"; 

結果:

<script> 
     var oTest = { 
      "Numeric":1, 
      "string":"hello world !", 
      "myFunction":function(test) { if (test==1) { alert('myFunction(1)'); return true; } else return false; }, 
      "myObject":{ 
       "Numeric":1, 
       "string":"hello world !", 
       "myFunction":function(test) { alert('myFunction(1)'); return true; } 
      } 
     }; 
     if (oTest.myFunction(0) == false) alert('myFunction(0)'); 
     if (oTest.myObject.myFunction(1) == false) alert('myFunction(0)'); 
    </script> 

數量。