2011-07-29 24 views
1

我有一個簡單的基於web的數據庫,使用php/mysql來跟蹤離開我的庫房的產品。基於MySQL表中的條目進行輸入驗證? (php/ajax/html/mysql)

MySQL數據庫有一堆表,但我關心的兩個是'請求'和'銷售人員',你可以在下面看到(我忽略了不相關的信息)。

Requests 
R_ID ...  R_Salesperson 
1  ...  James 
2  ...  Bob 
3  ...  Craig 

Salesperson 
S_ID   S_Name 
1  ...  James 
2  ...  Bob 
3  ...  Craig 

在我的頭節,我有以下腳本鍵入時動態填充我們的銷售人員的名單:

// Autocomplete Salesperson Field 
$("#form_specialist").autocomplete("../includes/get_salesperson_list.php", { 
    width: 260, 
    matchContains: true, 
    //mustMatch: true, 
    //minChars: 0, 
    //multiple: true, 
    //highlight: false, 
    //multipleSeparator: ",", 
    selectFirst: false 
}); 

AAAND get_salesperson_list.php:

<?php 
require_once "get_config.php"; 
$q = strtolower($_GET["q"]); 
if (!$q) return; 

$sql = "select DISTINCT S_Name as S_Name from Salesperson where S_Name LIKE '%$q%'"; 
$rsd = mysql_query($sql); 
while($rs = mysql_fetch_array($rsd)) { 
$cname = $rs['S_Name']; 
echo "$cname\n"; 
} 
?> 

我還有一些基本的javascript輸入驗證,需要在銷售人員字段中輸入值(腳本在頭部):

<!-- Input Validation --> 
<script language="JavaScript" type="text/javascript"> 
<!-- 
function checkform (form) 
{ 


// ** Validate Salesperson Entry ** 
if (form.form_specialist.value == "") { 
alert("Please enter Salesperson Name"); 
form.form_salesperson.focus(); 
return false ; 
} 
// ** END Salesperson Validation ** 

return true ; 
} 
//--> 
</script> 

Aaaaanyway - 問題是我無法弄清楚如何拒絕任何不在'銷售員'表中的名字。例如,如果我要輸入'Jaaames',儘管它最初會提示'James',如果我忽略它並提交'Jaaames',則會將其輸入到'Requests'表中。鑑於我的未確診的強迫症,這是相當煩人的,我寧願不必每隔幾次經常編輯它們。

回答

1

我會說你在這裏採取了錯誤的做法。

請求表不應該存儲銷售人員的姓名,它應該保存其ID。銷售人員表的主鍵。

然後,而不是使用自動完成來填充TEXT輸入,我建議使用相同的方法來填充使用銷售人員ID作爲值的SELECT菜單。

這完成以下操作:

  1. 數據庫變得更加標準化
  2. 它會從請求表
  3. 冗餘信息去除需要驗證客戶端上的銷售人員的名字
  4. 通過將S_ID定義爲Requests表的外鍵,可確保Sales Person表中的唯一條目可存在於Requests表中。
+0

是的..雖然我很懶,但是垃圾編碼器;) – Barry

0

嘗試添加某種驗證之前,你把它放到你的數據庫?我的意思是,在將請求放入表格的腳本中?

1

您可以嘗試將AJAX請求綁定到提交表單或更改文本字段,或者當字段失去焦點時。 在這個例子中,我使用jQuery:

$('input[name=salesperson').blur(function(){ 
    //when the text field looses focus 
    var n = $(this).val(); 
    $.post('a_php_file_that_checks_db_for_names.php', {salesperson:n}, function(data){ 
     //post the name to a php file which in turn looks that name up in the database 
     //and returns 1 or 0 
     if (data) 
     { 
      if (data==='1') 
      { 
       alert('name is in database'); 
      } 
      else 
      { 
       alert('name is not in database'); 
      } 
     } 
     else 
     { 
      alert('no answer from php file'); 
     } 
    }); 
}); 

您還需要爲這個跟一個PHP文件,一個例子是:

if (isset($_POST['salesperson'])) 
{ 
    //query here to check for $_POST['salesperson'] in the db, 
    //fill in the blanks :) 
    $yourquery='select name from db where name=?'; 

    if ($yourquery) 
    { 
     //looks like there were results, so your name is in the db 
     echo '1'; 
    } 
    else 
    { 
     echo '2'; 
    } 

} 

填補空白的一點必需的,但你明白了。 希望這可以幫助你

編輯:

第二,更優雅的解決方案只是來考慮 - 如果你能得到銷售人​​員的名單,並隱藏表單字段的每個,你可以閱讀所有進入一個JS對象,並在表單域被更改時對它進行測試。不幸的是,我沒有時間給你寫一個例子,但這聽起來像是對我做的一個更好的方式。

-1

mustMatch選項不適合你嗎?我看到它被註釋掉了。

此外,您的腳本容易受到SQL注入攻擊。我意識到這是一個內部應用程序,但你永遠不知道什麼時候瘋狂將要出現並毀了你的一天。在你get_salesperson_list.php的頂部,您檢索$_GET查詢之後,您可以添加這樣的事情:

if (!preg_match("/^\w+$/", $q)) { 
    // some kind of error handling here, or at least a refusal to fulfill the request: 
    exit; 
} 

UPDATE:對不起,我的意思是說「退出」,而不是「迴歸」。我確實看到你的腳本不在函數中。我已經編輯了上述內容來解釋這一點。感謝您指出了這一點。

+0

-1,Geez,SQL注入與內部應用程序有什麼關係?始終使用預準備語句或相應的函數(如'mysql_real_escape_string')來避免SQL注入。另外,'get_salesperson_list.php'似乎不是一個函數,所以使用'return'將不會終止它的執行流程。 –

+0

謝謝! - 我覺得這樣一個白癡沒有注意到我已經註釋掉了這個功能。 Ahhh well - works now:D – Barry

1

看來你只是使用Javascript來驗證你的輸入 - 這是不好的,因爲如果你的用戶不支持或禁用Javascript,它將永遠不會運行。如上所示,服務器端驗證將更容易檢查數據庫。然而,客戶端驗證對於不良輸入的第一道防線也是有幫助的,因爲它通常更快。我想不出一個好的方法來做到這一點,但一種方式可能是填充銷售人員的PHP數組,將其轉換爲JavaScript數組,然後檢查表單值是否在數組中。在這裏使用服務器端驗證可能會更快(代碼少)。

+0

幸運的是,這個網絡應用只能在內部網絡上運行。它通常只在少數幾臺機器上運行 - 所有這些都允許使用javascript :) – Barry