2010-11-25 23 views
2

我有一個PHP對象表單字段值,其屬性初始化以下方式排列:不穩定的行爲進行比較時,PHP內爆與使用JavaScript

$this->contact = implode(PHP_EOL,$description->getContact()) . PHP_EOL; 

唯一的例外是名爲兩個屬性和錯誤

然後將該對象編碼到JSON對象中,並傳遞到下面的JavaScript中,該JSON對象將JSON對象與表單中的值進行比較。

function compareEntry(data){ 
     var dataProperties = ["version", "bugs", "scenario", "exception", "instruction", "sources", "risks", "test", "contact"]; 
     var hasChanged = false; 

     for(var i = 0; i < dataProperties.length; i++){ 
      var dataProperty = dataProperties[i]; 
      alert("Original: '" + data[dataProperty] + "'\nModified: '" + document.myform[dataProperty].value + "'\nTest Value: " + (!data[dataProperty].localeCompare(document.myform[dataProperty].value))); 
      if(!data[dataProperty].localeCompare(document.myform[dataProperty].value)){ 
       hasChanged = true; 
      } 
     } 
[...] 

錯誤外,所有其他屬性都與在textarea的值進行比較。

表單字段使用PHP對象的值進行初始化。當我提交表單時,函數被調用。如果我在不更改任何值的情況下提交表單,那麼在將屬性與textarea的值進行比較時,它仍會給我一個false。爲什麼以及如何正確地比較它們?

說明: PHP對象是用相同的表單創建的MySQL條目的反映。在這之間,信息被加密和解密。但它不應該扮演一個角色,因爲PHP/JSon對象和表單的初始值來自同一個源。

編輯

弗羅德的解釋之後,我改變了我的測試語句:

data[dataProperty].localeCompare(document.myform[dataProperty].value)!=0 

但後來我注意到有兩個數據差異過大。

  • 屬性錯誤這之前,當現在false測試的返還true。但與其他屬性相反,當我從數據庫中檢索它們時,我不操縱這些值。屬性版本的值存儲在窗體中的select標記中。
  • 而且,當我改變textarea中的一個值而不是給我false時,它會給我true

它發生在我身上,它可能是由於我使用的瀏覽器的JavaScript的實施。但是我得到的結果並不像我預料的那樣。然而,我已經在Firefox和Chrome中描述過這種行爲,IE和Opera總是拋出false(除了比較版本之外,這在IE中給了我真實的例外,雖然他無法檢索到select標籤)。

我是否應該使用其他方法來比較我的字符串?

編輯2

服用WoLpH的建議之後,我改變了試驗條件:

數據[dataProperty] .trim()document.myform [dataProperty] .trim()

其中trim()是this other question中描述的函數。結果是我在第一次編輯中所反過來的結果。除了Chrome似乎隨機分配它的布爾值。在某種程度上,我的數據似乎有些問題。

下面是一個JSON對象的例子,我可以在Firefox中看到它(代碼片段中的變量數據)。

{"version":"REL-773","bugs":"20831","scenario":"THIS IS A TEST\r\n\r\nThis is the what happens: stuffs.\r\n","exception":"N\/A\r\n","instruction":"1. First Step.\r\n2. Second Step.\r\n2. Third Step\r\nIt is longer.\r\n4. Fourth Step.\r\n5. Fifth Step.\r\n6. Sixth Step.\r\n","sources":"me\r\n","risks":"High risks as it is just for testing of the web application.\r\n","test":"1. Select an entry\r\n2. Change some data such as <HOME>\/path\/\r\n3. See if the application run as expected!\r\n","contact":"[email protected]\r\n"} 

編輯3

使用功能escape()逃跑的兩個字符串的所有特殊字符,我注意到,在人物%OA被寫爲JSON對象%OD%OA。它讓我懷疑我的修剪功能不能正確替換\r\n\n。 (修剪,我的海報建議這裏後添加功能)

下面是函數使用:

if(typeof(String.prototype.trim) === "undefined") 
{ 
    String.prototype.trim = function() 
    { 
     return String(this).replace(/^\s+|\s+$/g, '').replace(/\r\n/g,"\n"); 
    }; 
} 
+0

您是否嘗試過在比較之前剝離所有尾部空白? – Wolph 2010-11-25 14:47:55

+0

@WoLpH,它似乎剝離尾隨空白沒有一點幫助。 – Eldros 2010-11-25 16:33:40

回答

1

JavaScript的string.localeCompare返回0,如果比較兩個字符串完全相同,和-1或1,否則。所以你的if語句如下:

if(!data[dataProperty].localeCompare(document.myform[dataProperty].value)){ 
    hasChanged = true; 
} 

..實際上當字符串相等時,將hasChanged設置爲true。嘗試刪除!並看看它是否按照你的預期行事。

2

首先,免責聲明:我有這樣的感覺,也許這不是確定的答案,而是更多的解決方法。因爲這是我能處理這個問題的唯一方法。

現在,由於我發佈了這個問題,我瞭解到client-side form validation is not enough。這不僅不夠,而且在我的情況下,它不是必需的,因爲它不會讓用戶體驗中的任何內容知道值已被更改。用戶知道某個值的格式不正確或者只是錯誤是非常有趣的。所以我將比較檢查遷移到了服務器端。

首先,我將我的PHP信息包裝在一個json字符串中,確保能夠轉義所有相關字符。我首先確保引號符號正確地轉義,然後在將結果字符串放入我的表單的隱藏輸入中之前,我用同等的Unicode代替characters which could be problematic

//escaping ",' and other throublesome characters properly for json 
$json_string = str_replace('\'', "\\'", json_encode($objEncasing)); 
$json_string = str_replace(array('\\"', '\\\'', '&','<','>'), array('\\u0022', '\\\u0027', '\\u0026', '\\u003C', '\\u003E'), $json_string); 
echo "<input name='json' type='hidden' value='".$json_string."' />"; 

應該注意的是JSON對象對應於形式的任何改動之前的信息,因此爲什麼JSON字符串在PHP格式化。表單信息然後通過POST發送到一個新的腳本,它將完成所有必要的工作。

現在我在接收腳本做的第一件事,就是檢索JSON變量,但人們不應該忘記check for magic quotes

if(get_magic_quotes_gpc()){ 
    $json_string = stripslashes($_POST['json']); 
}else{ 
    $json_string = $_POST['json']; 
} 

我們的JSON對象轉換成一個陣列和可進行比較時到$ _POST數組(使用JSON值除外):

if(!empty($json_string)){ 
    $json_encasing = json_decode($json_string, true); 
    $gotChange = false; 

    foreach($_POST as $key => $value){ 
     if($key != "json"){ 
      //Compare the value, if something change set $gotChange to true 
      $value = stripslashes($value); 
      if($value != $json_encasing[$key]){ 
        $json_encasing[$key] = $value; 
        $gotChange = true; 
      } 
     } 
    } 

    if($gotChange){ 
     //Do your stuff 
    } 
} 

,因爲我這樣做,我的服務器上,我並不需要預見到幾個不同的行爲。所以我的建議是,如果你能幫助它,那麼在服務器端做你的東西。

相關問題