2011-12-30 15 views
5
$sql='SELECT phrase,english FROM static_site_language WHERE page=?;'; 
$pds=$database->pdo->prepare($sql); $pds->execute(array($_POST['languagepage'])); 

Mã trên chạy tốt. Tuy nhiên tôi cần phải đặt một biến khác vào câu lệnh chuẩn bị. Tôi đã thử những điều sau nhưng có vẻ như không hoạt động:PHP PDO + Chuẩn bị Bảng sao kê

$sql='SELECT phrase,? FROM static_site_language WHERE page=?;'; 
$pds=$database->pdo->prepare($sql); $pds->execute(array($_POST['language'],$_POST['languagepage'])); 

Tôi biết $ _POST ['language'] (in từ đó) chỉ chứa từ 'tiếng Anh'. Có thể đặt biến chuẩn bị trong phần chọn này không?

thx

+0

Dường như không có lỗi về cú pháp, bạn đã nhận được mã lỗi nào? – LotusH

+0

không có lỗi - nhưng thay vì sau đó nhận được giá trị trở lại từ DB nó chỉ mang lại cho tôi từ tiếng anh. Đây là giá trị trong biến và tiêu đề của cột trong DB ... – Adam

+0

ví dụ: {"free": "english", "meetingles": "english", "searchprofiles": "english"} nhưng cần có các giá trị khác nhau trong đó từ tiếng Anh là ... – Adam

Trả lời

7

Thông số truy vấn chỉ có thể thay thế giá trị không đổi - không phải tên cột.

Tất cả các cột và bảng phải được đặt tên tại thời điểm bạn chuẩn bị truy vấn, bạn không thể trì hoãn việc chọn cột cho bước thực hiện tiếp theo.

Khi bạn muốn đầu vào của người dùng xác định tên cột, hãy sử dụng Bản đồ danh sách trắng để giới hạn đầu vào của người dùng cho các lựa chọn hợp lệ. Các khóa của mảng bản đồ là đầu vào của người dùng hợp pháp. Các giá trị của mảng bản đồ là các chuỗi bạn muốn sử dụng trong truy vấn SQL, trong trường hợp này là các tên cột.

$lang_col_map = array(
    "DEFAULT" => "english", 
    "en"  => "english", 
    "es"  => "spanish" 
); 
$lang_col = $lang_col_map[ $_POST["language"] ] ?: $lang_col_map[ "DEFAULT" ]; 

$sql='SELECT phrase,$lang_col FROM static_site_language WHERE page=?;'; 
$pds=$database->pdo->prepare($sql); 
$pds->execute(array($_POST['languagepage'])); 

Bằng cách này bạn có thể chắc chắn rằng chỉ có giá trị trong $ lang_col_map có thể trở thành một phần của truy vấn SQL, và nếu người dùng cố gắng gửi bất cứ điều gì khó khăn trong yêu cầu http, nó bỏ qua bởi vì nó không phù hợp bất kỳ khóa nào của bản đồ đó. Vì vậy, truy vấn là an toàn từ SQL injection.

Xem bản trình bày của tôi SQL Injection Myths and Fallacies để biết thêm thông tin.

+0

Theo thiết kế, tất cả các câu hỏi/truy vấn phải được biết trước khi chúng được yêu cầu. – Xeoncross

2

Tuyên bố được chuẩn bị chỉ hỗ trợ các tham số là các giá trị được cơ sở dữ liệu hỗ trợ.

Trong câu lệnh thứ hai của bạn, câu đầu tiên "?" là trình giữ chỗ cho tên cột, không phải là giá trị.

Bạn phải sử dụng câu lệnh SQL động thay thế. Đối với điều này, bạn phải ngăn chặn từ SQL injection.

$language_authorized = array('english', 'french', 'spanish'); 
$language = $_POST['language']; 
if (in_array($language_authorized, $language)) { 
    $sql='SELECT phrase,'.$language.' FROM static_site_language WHERE page=?;'; 
    $pds = $database->pdo->prepare($sql); 
    $pds->execute(array($_POST['languagepage'])); 
} 
Các vấn đề liên quan