2011-12-12 29 views
3

我正在努力與此代碼的邏輯。我認爲使用後退按鈕時會出現空白條目。這是針對殘疾學習者的問卷系統,每個網頁只問1個問題,每個問題都會單獨提交結果。有一個單獨的表格用於確定調查是否已完全完成(我使用GET跟蹤uniqueID),結果只能從完全完成的結果中得出。避免空白和重複的條目提交到sql

我已經嘗試使用更新響應/評論,其中quesitonID和唯一ID存在,但這似乎創造更多的問題。爲了清晰起見,並允許一些想法的自由,我已經將代碼削減到最低限度。非常感謝。

編輯:'響應'是一個單選按鈕條目,'評論'是文本輸入。 'UniqueID','surveyID','QID'&'type'在URL中確定並使用GET進行捕獲。

mysql_query(" 

INSERT INTO answers (uniqueID, surveyID, QID, type, response, comment) 
SELECT '$U', '$S','$Q', '$t', '$response', '$comments' 

") 
or die(mysql_error()); 


if (isset($_GET['start'])) { 

mysql_query(" 

INSERT INTO complete (uniqueID, surveyID) 
VALUES('$U', '$S') 

") 
or die(mysql_error()); 

}  

if (isset($_GET['finished'])) { 

mysql_query(" 

UPDATE complete 
SET timestamp = NOW() 
WHERE uniqueID='$U' 

") 
or die(mysql_error()); 

} 
+0

驗證輸入的代碼在哪裏?當你的代碼沒有實現時,你想如何避免重複和空值? – newtover

+0

這是我感到困惑的驗證。你認爲哪種方法最適合於這個系統? –

回答

1

您的代碼不會進行任何驗證,它只是在出現錯誤時爲die
這不適用於生產代碼。

至於去驗證你有兩個選擇:

A - 檢查PHP的輸入,並禁止任何非法值。
B - 使用SQL約束並監視那裏的輸出。
或兩者的組合。

與選項的問題是,你只是得到一個錯誤從MySQL回來,你必須在PHP處理。
出於這個原因我會去的選項A.

第一步:逃避你輸入
要做到這一點,最好的辦法是使用PDO
如果你使用mysql_庫,你必須在每一個輸入上使用mysql_real_escape_string來逃避它並引用你的$vars;像這樣:

$a = mysql_real_escape_string($_GET['param1']); 
examplequery = "SELECT * FROM table1 WHERE field1 = '$a' "; 

對於整數值,您可以將該變量轉換爲整數,然後注入不帶引號。

$a = intval($_GET['param1']); 
$b = intval($_GET['param2']); 
if $a > $b { list($a,$b) = array($b,$a); } //Exchange the two vars if needed. 
examplequery = "SELECT * FROM table1 WHERE field1 BETWEEN $a AND $b"; 

驗證您的數據
這裏再次,你有兩個選擇,你可以硬編碼驗證到PHP,或使用SQL查詢的輸入。
我喜歡第二種方法,因爲它允許您將所有信息輸入到數據庫中。

table Checks (
    fieldname varchar(50) not null, 
    tablename varchar(50) not null, 
    fieldtype enum('int','varchar','enum','decimal'.....) not null, 
    min_value double default -1000000; 
    max_value double default 1000000; 
    validation_query varchar(1000) default null, 
    primary key (tablename, fieldname)) ENGINE = InnoDB; 

現在可以檢查像這樣(使用PDO)設置了一個param:

$stmt = $dbh->prepare("SELECT fieldtype, min_value, max_value, validation_query 
         FROM checks WHERE fieldname = ? AND tablename = ?"); 
$stmt->execute(array('field1', 'table1')); 
$result = $stmt->fetch(PDO::FETCH_ASSOC); 
switch ($result['type']) { 
    case 'int': 
    $allOK = isnumeric($inputvalue_to_check); 
    $allOK = $allOK AND ($intval($inputvalue_to_check) >= $result['min_value'] 
        AND $intval($inputvalue_to_check) <= $result['max_value']); 
    if is_null($result['validation_query']) { 
     $sql = $result['validation_query']; 
     $check = $dbh-?prepare($sql); 
     $check_result = $check->execute(array($inputvalue_to_check)); 
     $check_result->fetch(PDO::FETCH_ASSOC); 
     if is_null($check_result['result']) { //value is not OK} 
    break; 
    case ....... 

使用驗證表
一種選擇是創建一個像這樣的表驗證您的數據

驗證在php中
如果你知道你的數據,它不會改變,您可以使用ifswitch聲明進行驗證。
這段代碼看起來很像上面的代碼,只是它沒有從數據庫中獲取數據,邏輯被硬編碼或者存儲在php數據結構中。

+0

非常感謝你對這一級別的細節和努力。真的會幫助我理解驗證。 –

1

如果你問如何使MySQL抱怨時重複或空值插入的答案是:

    避免重複上(UNIQUEID,surveyID,QID)
  • UNIQUE約束
  • NOT NULL約束用於避免空白值

對約束讀入loook MySQL docs

但是,如果提供的值存在且格式正確,我也會檢查PHP。沒有提到SELECT '$U', '$S','$Q', '$t', '$response', '$comments'編寫查詢的方式是非常危險的,因爲允許注入不同種類的代碼。