2017-07-18 16 views
5

Xin chào các bạn như là tiểu bang tiêu đề tôi đang tìm cách tạo các truy vấn động tới máy chủ MySQL của tôi. Tại thời điểm này đây là đoạn code tôi sử dụng để cập nhật dữ liệu trên máy chủ:Truy vấn MySQL động với PHP

$deskAttr = json_decode($_POST["desk_attributes"]); 

foreach($deskAttr as $key => $value) { 
    $sql = "UPDATE desk_attributes SET iw_standard=".$value->iw_standard.", avaya_standard=".$value->avaya_standard.", avaya_withcallid=".$value->avaya_withcallid.", avaya_withtransfer=".$value->avaya_withtransfer.", dual_screen=".$value->dual_screen.", air_conditioning=".$value->air_conditioning.", iw_obdialler=".$value->iw_obdialler." WHERE id=".$value->id; 
    $conn->query($sql); 
} 

Như bạn có thể thấy, các tên cột SQL cũng giống như các phím deskAttr. Tôi đang tìm một cách để làm cho dòng này một vòng lặp để tôi không cần phải thay đổi dòng này nếu tôi đã thêm nhiều cột hơn vào bảng MySQL.

Nó sẽ giống như thế này:

$deskAttr = json_decode($_POST["desk_attributes"]); 

foreach($deskAttr as $key => $value) { 
    $sql = "UPDATE desk_attributes SET"; 
    foreach($value as $k => $v) { 
     $sql .= " $k = $value->$k ,"; 
    } 
    $sql .= "WHERE id=".$value->id"; 
} 

Làm thế nào tôi có thể viết mã trên nên nó sẽ thực sự làm việc? Cảm ơn.


EDIT

Có lẽ nó sẽ rất hữu ích để biết rằng $deskAttr là một mảng của các đối tượng và tên của các cột cũng giống như tên của các phím đối tượng.

Đây là những gì tôi có nghĩa là trong mã giả:

foreach($object in $deskAttr) { 
    $sql = "UPDATE table SET "; 
    foreach($key in $object) { 
     if($key != "id") 
      $sql .= "$key = $object->$key, "; 
    } 
    $sql .= "WHERE id = $object->id; 
    $conn->query($sql); 
} 

Rõ ràng điều này sẽ thêm một dấu phẩy ở phần cuối của truy vấn trước khi WHERE phần nhưng hy vọng bạn sẽ có được những gì tôi đang cố gắng để đạt được.

+1

Bạn đang rộng mở cho [SQL Tiêm] (http://php.net/manual/en/security.database.sql-injection.php) và nên thực sự sử dụng [Statement Statements] (http://php.net/manual/en/mysqli.quickstart.prepared-statements.php) thay vì ghép nối các truy vấn của bạn. Đặc biệt vì bạn không thoát khỏi đầu vào của người dùng! –

+1

Bạn thực sự nên chuyển sang các câu lệnh đã chuẩn bị cho các giá trị và danh sách trắng cho các tên cột để tránh tiêm sql. – jeroen

+0

Bạn không thể liên kết tên cột thông qua câu lệnh đã chuẩn bị. Vì vậy, nếu bạn sẽ đặt một chuỗi biến trong chuỗi truy vấn SQL của bạn, juste thoát chúng một cách chính xác và bạn tốt. –

Trả lời

1

Bạn có thể thực hiện thay đổi nhỏ trong mã của mình bằng cách sử dụng chức năng implode() của PHP.

Lấy một mảng trống, nối các thông số cập nhật vào nó.

Và sau đó nếu không phải là empty(), implode() để nhận chuỗi.

Mã Cập nhật:

$sql = "UPDATE desk_attributes SET "; 
foreach ($deskAttr as $key => $value) { 
$value = mysqli_real_escape_string($link, $value); // $links is database connection string. 
$key = mysqli_real_escape_string($link, $key); // $links is database connection string. 
$updtAttrs[] = $key ." = '" . $value . "'"; 
} 
$sql .= ! empty($updtAttrs) ? implode(', ', $updtAttrs) : ''; 
$sql .= " WHERE id=" . $value->id; 
+2

Mã này là ** _ rất _ ** không an toàn. Nó rộng mở để tiêm SQl. Bạn nên sử dụng các câu lệnh được chuẩn bị thay vì ghép nối các đầu vào của người dùng trực tiếp như thế này. Bạn cũng nên có một danh sách các tên cột được cho phép. –

+0

Không, không. Ngừng là một chuẩn bị-tuyên bố-nazi và đi đọc tài liệu 'mysqli_real_escape_string' –

+0

@ KiJéy - Có lẽ bạn nên kiểm tra dòng thời gian của nhận xét và chỉnh sửa của bài đăng. ** 1. ** Khi tôi viết nhận xét, 'mysqli_real_escape_string()' không được bao gồm trong câu trả lời _at all_. ** 2. ** Phím '$' là _still_ hoàn toàn không thoát, _still_ làm cho nó mở 100% cho SQL Injection. Btw, thực sự có những tình huống mà 'mysqli_real_escape_string()' không đủ: https://stackoverflow.com/questions/5741187/sql-injection-that-gets-around-mysql-real-escape-string/12118602#12118602 –

Các vấn đề liên quan