2011-11-06 24 views
0

我通常只是插入到我的數據庫之前使用mysql_real_escape_string上的每個變量,因此,例如:在逃避一個數組變量和分配逃脫值原始變量值動態

$first_name = mysql_real_escape_string($first_name); // Bill 
    $last_name = mysql_real_escape_string($last_name); // O'Rielly 
    $email  = mysql_real_escape_string($email);  // [email protected] 

    $insert = mysql_query(" 
        INSERT INTO `users` (first_name, last_name, email) 
        VALUES ('$first_name', '$last_name', '$email') 
       ") or die(mysql_error()); 

但在某些形式的我能有可能我想要轉義20個不同的變量,所以我希望有一種方法可以使用數組,通過函數運行它來轉義每個數組。然後使原始變量($first_name$last_name,$email)具有數組中已轉義字符串的值。我想出了以下內容,但這是我所得到的。

$form_array = array($first_name, $last_name, $email); 

    print_r($form_array); 
    echo("<br />".$last_name."<br />"); 

    function cleanInput($array) { 
     return array_map('mysql_real_escape_string', $array); 
    } 

    $clean_array = cleanInput($form_array); 

    print_r($clean_array); 
    echo("<br />".$clean_array[1]."<br />"); 

,它輸出以下內容:

Array ([0] => Bill [1] => O'Rielly [2] => [email protected]) 
    O'Rielly 
    Array ([0] => Bill [1] => O\'Rielly [2] => [email protected]) 
    O\'Rielly 

所以,我們可以看到,它的逃逸正確,但我和整個製作$first_name難倒有$clean_array[0]值,$last_name具有的價值$clean_array[1]

我當然知道我可以只寫:

$first_name = $clean_array[0]; 
    $last_name = $clean_array[1]; 

但它有點讓這個數組/函數根本沒有意義,因爲我可能只是分別將每個變量/字符串轉義出來,我總是這樣做。所以我希望有一種方法可以在函數中做某種循環,根據數組中的內容動態地執行此操作。

因爲當談到在未來做驗證我只能

  • 全部分配$ _ POST數據到變量
  • 把它們放在變量數組
  • 運行通過功能的陣列和所有原始的$ _POST變量現在都有函數的轉義值
  • 使用開頭提到的插入方法,使用變量的原始名稱$first_name$last_name等。

相反則:

$insert = mysql_query(" 
        INSERT INTO `users` (first_name, last_name, email) 
        VALUES ('$clean_array[0]', '$clean_array[1]', '$clean_array[2]') 
       ") or die(mysql_error()); 

這可能嗎?

更新

從hakre的有關compactextract功能後,我現在已經想出了以下內容:

$array = compact(array("first_name", "last_name", "email")); 
    echo("<strong>Before:</strong><br />First Name: ".$first_name."<br />Last Name: ".$last_name."<br />Email: ".$email."<br /><br />"); 

    extract(array_map('mysql_real_escape_string', $array), EXTR_OVERWRITE); 
    echo("<strong>After:</strong><br />First Name: ".$first_name."<br />Last Name: ".$last_name."<br />Email: ".$email.""); 

,它輸出以下細節如何,我想他們:

之前:

名字:

比爾

姓:O'Rielly

電子郵件:[email protected]

後:

名字:

比爾

姓: O'Rielly

Email:[email protected]

我試過把extract放到一個函數中,但是它不起作用?

function cleanInput($array) { 

     $clean_array = extract(array_map('mysql_real_escape_string', $array), EXTR_OVERWRITE); 
     return $clean_array; 

    } 

    $array = compact(array("first_name", "last_name", "email")); 
    echo("<strong>Before:</strong><br />First Name: ".$first_name."<br />Last Name: ".$last_name."<br />Email: ".$email."<br /><br />"); 

    cleanInput($array); 
    echo("<strong>After:</strong><br />First Name: ".$first_name."<br />Last Name: ".$last_name."<br />Email: ".$email.""); 

我敢肯定,我一定要退回提取功能,但我已經嘗試了一些不同的東西,它要麼不給任何輸出或$last_name只是打印轉義值。

回答

2

您可能會感興趣於compactextract。兩者都允許您將變量作爲數組處理。陣列很舒服,因爲您可以將單個動作重複到所有值。

例子:

$vars = array('first_name', 'last_name', 'email'); 

$first_name = $last_name = $email = 'just some init value'; 

$array = compact($vars); 

foreach($array as &$value) 
    $value = str_shuffle($value); 
unset($value); 

extract($array); 

printf("First: %s; Last: %s; Email: %s", $first_name, $last_name, $email); 

輸出:

First: sjivus enta metluoi; Last: i evounes tliuat smj; Email: tleetnumav siuijo s 
+0

只是通過這些文檔快速閱讀,因爲我現在有點忙,但這看起來像我以後!一旦我以後陷入困境,我會再次聯繫,謝謝! – Joe

+0

hakre,我用'compact'和'extract'做了一個小提琴,我有一個工作的例子,但不是100%我想要它,我已經用我目前所得到的更新了我的問題,你能看一看,如果你能讓我更深入瞭解從哪裏出發?爲了向我展示這兩個功能+1! – Joe

+0

你使用它是錯誤的,因爲函數有它自己的變量表。緊湊和提取提供了一些基本的變量處理功能。你應該明智地使用它們,讓它們做你想做的事。我並不是說這些解決了你的問題或者你完全面對的設計問題。 – hakre

1
function dbSet($fields, $source = array()) { 
    $set = ''; 
    if (!$source) $source = &$_POST; 

    foreach ($fields as $field) { 
    if (isset($source[$field])) { 
     $set.="`$field`='".mysql_real_escape_string($source[$field])."', "; 
    } 
    } 
    return substr($set, 0, -2); 
} 

這段代碼被稱爲函數。儘管只有極少數的PHP用戶對它們有所瞭解,但功能是非常非常強大的。它可以使您的代碼簡潔易讀,併爲您節省數小時的打字時間。

所以,在你的配置文件中這個功能,你必須鍵入低至

$fields = explode(" ","name surname lastname address zip fax phone"); 
$query = "INSERT INTO table SET ".dbSet($fields); 

注意$的Fileds陣列。我希望這是不言而喻的,雖然

那麼,經過一些澄清的意見,我可以延長我的答案。

擺脫不斷逃跑的最佳方式是擺脫它。要麼創建你自己的,要麼使用一些現有的數據庫抽象庫,它將爲你做所有的轉義。

說一個代碼來檢查現有用戶名應該看起來像

$username_exists=$db->getOne("SELECT id FROM users WHERE name=?",$_POST['name']); 
if ($username_exists) // do stuff. 

其中,$ _ POST [「名」]將被正確格式化,或者通過利用本地準備的語句或適當的轉義/鑄造/白名單。

所以,根本不需要關心手動轉義。
這也是我首先發布的函數的確切點。

+0

那豈不是做什麼礦已經呢?除了你插入它稍微不同的數據庫?對不起,如果我誤解了它!它只是我想讓每個變量都通過該函數,但返回的變量的原始名稱下的轉義值。因爲我希望能夠繼續並單獨對每個變量執行其他檢查,這就是爲什麼我要將它們分開的原因。 – Joe

+0

轉義後您無法進行任何檢查。轉義應該是將數據插入數據庫之前的最後一個操作。 –

+0

對不起,我應該解釋一下,我的意思是我想做一些查詢來檢查郵件是否已被其他成員使用,諸如此類的事情,這就是爲什麼我需要以某種方式將它們分開的原因。因爲我不想像首字母和姓氏一樣檢查它們,因爲它們可能是重複的,但是電子郵件,用戶名等不能。那麼肯定爲我的電子郵件檢查查詢它需要在手之前逃脫? – Joe