2017-07-28 35 views
-1

你好,我已經試過這兩個問題的解決方案(最終目標添加在底部)PHP如何提取關聯數組鍵名稱和值,MySQL查詢

INSERT array - PDO

Binding values from arrays?

,但我不在$ fields和$ newdata中沒有獲得預期的變量內容

所以我在這裏打印一些var_dump並轉換以提請您的支持。從HTML表

我的陣列衍生物爲簡單起見,我學習的實驗,我只用5場的虛表的工作,當你看到他們是:selecteduser_iduser_nameuser_companyuser_email。 最後,我插入了2行值。

表內容發佈爲JSON.stringify。

在這裏,你我的結果

使用通常

print_r ($Arr); 

我可以看到這個輸出

Array ( 
[0] => Array ([selected] => [user_id] => 3 [user_name] => nome3 [user_company] => azien3 [user_email] => email3) 
[1] => Array ([selected] => 1 [user_id] => 6 [user_name] => nome6 [user_company] => azien6 [user_email] => email6) 
) 

下一個我試圖應用的代碼從上面的兩個問題

24 $fields = implode(",", array_keys($Arr)); 
25 $newdata = "'" . implode("','", $Arr) . "'"; 
26 
27 var_dump($fields); 
28 echo "<br><br>"; 
29 var_dump($newdata); 

但我的解釋或我的代碼有些問題,因爲輸出是

Notice: Array to string conversion in D:\xampp\htdocs\ajax-json\post.php on line 25 

Notice: Array to string conversion in D:\xampp\htdocs\ajax-json\post.php on line 25 
string(3) "0,1" 

string(15) "'Array','Array'"

你能指出什麼是錯的嗎? 例如我的數組是否正確形成?

最終目標是建立一個查詢,它們將從關聯數組中取得的鍵名和鍵值直接綁定到INSERT的列和值到mysql表中。

換句話說,由於數組的鍵名與數據庫表的列名是相同的,所以我想知道如何創建一個自動模式來創建查詢,就像在這個問題開頭的兩個問題中一樣。

隨着「全自動」是爲了有變數,也許循環建立一個查詢,而不是比寫單列名和相同的列值要插入


編輯:從接受的答案,這是工作代碼。

$my_keys = array_keys($Arr[0]); 

// ---- This prevents PDO SQL Injection 
$stmt=$pdo->prepare("DESC my_table"); 
$stmt->execute(); 
$whitelist_columns=$stmt->fetchAll(PDO::FETCH_COLUMN); 
foreach($my_keys as $key){ 
    if(!array_search($key,$whitelist_columns)){ echo "ERROR!"; } 
} 
// ---- End of prevention 

$field_names = implode(",", $my_keys); // build column list 

/** @JBH this foreach is needed otherwise the $q_markers will result not PDO placeholders like. 
If this is missing, the query inserts all "" values, no matter if you'll adopt bindValue or bindParam**/ 
foreach($my_keys as &$key){ 
    $key = ":".$key; 
} 
$q_markers = implode(",", $my_keys);  // build PDO value markers 

$stmt = $pdo->prepare("INSERT INTO my_table (".$field_names.") VALUES (".$q_markers.")"); 
foreach($Arr as $key => $val){ 
    foreach($val as $bind_marker => &$bind_val){ /** @ JBH Without "&" here, it will work 
only bindValue. Instead with "&", they work both bindParam and bindValue **/ 
     $stmt->bindParam($bind_marker, $bind_val); 
    } 
    $stmt->execute(); 
} 
+0

你在$ newdata期待什麼?你正在試圖破解兩個你不能做的數組。你是否試圖破壞每個陣列? $ Arr [0]和$ Arr [1]?即使這是不對的。你不能爆發一個關聯數組。請輸入你期望看到的例子。 – JBH

+0

'$ Arr'是一個多維數組。它的行爲不符合你的期望。 –

+0

嗯,最終目標是建立一個查詢,它們將從關聯數組中取得的鍵名和鍵值直接綁定到mysql表的列和值。換句話說,由於鍵名與數據庫表的列名相同,所以我想知道如何創建一個自動操作來創建查詢,就像在頂部的兩個鏈接中一樣。 – Robert

回答

1

您可以使關聯數組implode,但不能使多維數組撞擊。這就是錯誤告訴你的。例如...

$my_array = array('a'=>'1', 'b'=>'2', 'c'=>'3'); 
echo "\n\n".implode(',',array_keys($my_array)); 
echo "\n\n".implode(',',$my_array)."\n\n"; 

結果在......

a,b,c 

1,2,3 

但是......

$my_array = array(
    array('a'=>'1', 'b'=>'2', 'c'=>'3'), 
    array('d'=>'4', 'e'=>'5', 'f'=>'6') 
); 
echo "\n\n".implode(',',array_keys($my_array)); 
echo "\n\n".implode(',',$my_array)."\n\n"; 

結果...

0,1 
PHP Notice: Array to string conversion in /test.php on line 9 

修復代碼意味着要處理每個數據元素。回顯出來,他們會是這樣的:

selected, user_id, user_name, user_company, user_email 
,3,nome3,azien3,email3 
1,6,nome6,azien6,email6 

所以,基本的代碼看起來像......

$fields = implode(",", array_keys($Arr)); 
echo $fields."\n"; 
foreach($Arr as $key=>$val){ 
    $newdata = "'" . implode("','", $Arr[$key]) . "'"; 
    echo $newdata."\n"; 
} 

而一個PDO INSERT語句將建成這樣的...

$my_keys = array_keys($Arr[0]); 

$stmt=$pdo->prepare("DESC my_table"); 
$stmt->execute(); 
$whitelist_columns=$stmt->fetchAll(PDO::FETCH_COLUMN); 
foreach($my_keys as $key){ 
    if(!array_search($key,$whitelist_columns)){ echo "ERROR!"; } 
} 

$field_names = implode(",", $my_keys);  // build column list 
$q_markers = implode(",", $my_keys);  // build PDO value markers 

$stmt = $pdo->prepare("INSERT INTO my_table (".$field_names.") VALUES (".$q_markers.")"); 
foreach($Arr as $key => $val){ 
    foreach($val as $bind_marker => $bind_val){ 
     $stmt->bindParam($bind_marker, $bind_val); 
    } 
    $stmt->execute(); 
} 

請注意代碼段的whitelist變量。該代碼的目的是防止SQL注入,因爲使用未綁定列引用創建查詢。 PDO不允許您以與單元格數據相同的方式綁定列名稱。爲了保護自己,您必須證明傳入的數據與表格中的列匹配。如果他們不這樣做,請對此做點事情(echo "ERROR";)。通常,您希望完全停止該INSERT並將問題記錄在某處。

$my_keys = array_keys($Arr[0]); 
$q_marks = array(); 

$stmt=$pdo->prepare("DESC my_table"); 
$stmt->execute(); 
$whitelist_columns=$stmt->fetchAll(PDO::FETCH_COLUMN); 
foreach($my_keys as $key){ 
    if(!array_search($key,$whitelist_columns)){ echo "ERROR!"; } 
    array_push($q_marks, "?"); 
} 

$field_names = implode(",", $my_keys);  // build column list 
$field_markers = implode(",", $q_marks); 

$stmt = $pdo->prepare("INSERT INTO my_table (".$field_names.") VALUES (".$field_markers.")"); 

foreach($Arr as $key => $val){ 
    $stmt->execute($val); 
} 

上面的代碼是使用PDO而不bindParambindValue的一個例子。它有一個價格,但通常沒有實際成本。 bindParambindValue允許您專門識別數據類型。 E.G.,bindParam('myval', $myval, PDO::PARAM_INT)。當變量如上傳遞時,你不能這樣做。由於PHP正確識別數據類型,因此大多數情況下這不是問題。當PHP確實變得困惑時(或者你只是想強制檢查數據是你期望的),那麼你必須使用bindParambindValue

+0

謝謝JBH,我很耐心地嘗試它(目前我'遠離家鄉)。這似乎是正確的過程。這個問題來自我打開的這個其他問題,但它已被標記爲重複https://stackoverflow.com/questions/45349503/php-mysql-insert-multimensional-associative-array-building-query-from-array-關鍵在那裏,我提到PDO作爲首選!您閱讀我的想法;-)(儘管也許PDO是這種情況的唯一選擇(?)) – Robert

+0

PDO始終是最好的選擇,因爲它可以防止SQL注入。你應該總是使用PDO。 – JBH

+0

這是我的目標,我總是使用PDO,不得不學習,我明白這是一個學習msqli的人。我對PDO感到滿意,它使事情變得非常可讀,而如果正確實施,它使結構更加有效,輕薄且簡單,在準備語句時使用循環(如果需要)。例如。我想知道他們如何在沒有PDO佔位符的情況下做(如「他們沒有咖啡時他們如何做」:-))..我們知道它可以完成,但是一團糟。儘管如此,PDO從視角上檢驗了一些習慣的對象概念。 – Robert