$userData
của bạn phải có các trình giữ chỗ giống hệt nhau bị ràng buộc bởi câu lệnh của bạn, không hơn không kém. Xem PDOStatement::execute
tài liệu
, phần có nội dung "Bạn không thể ràng buộc nhiều giá trị hơn mức đã chỉ định".
Bạn cần chuẩn bị đối số của mình để execute()
để khớp chính xác các ràng buộc của bạn. Điều này thật dễ dàng với array_intersect_key()
nếu bạn sắp xếp các mảng của mình một cách chính xác. Tôi thường bao bọc điều này trong một hàm cũng sẽ xử lý tiền tố, như bên dưới:
// Adds a prefix to a name for a named bind placeholder
function prefix($name) {
return ':'.$name;
}
// like 'prefix()', but for array keys
function prefix_keys($assoc) {
// prefix STRING keys
// Numeric keys not included
$newassoc = array();
foreach ($assoc as $k=>$v) {
if (is_string($k)) {
$newassoc[prefix($k)] = $v;
}
}
return $newassoc;
}
// given a map of datakeyname=>columnname, and a table name, returns an
// sql insert string with named bind placeholder parameters.
function makeInsertStmt($tablename, $namemap) {
$binds = array_map('prefix', array_keys($namemap));
return 'INSERT INTO '.$tablename.' ('.implode(',',$namemap).') VALUES ('
.implode(',',$binds).')';
}
// returns an array formatted for an `execute()`
function makeBindData($data, $namemap) {
// $data assoc array, $namemap name->column mapping
return prefix_keys(array_intersect_key($data, $namemap));
}
// example to demonstrate how these pieces fit together
function RunTestInsert(PDO $pdo, $userData) {
$tablename = 'UserDetails';
// map "key in $userData" => "column name"
// do not include ':' prefix in $userData
$namemap = array(
'firstName' => "FirstName",
'lastName' => "LastName",
'address' => "Address",
'city' => "City",
'county' => "County",
'postCode' => "PostCode",
'phone' => "Phone",
'mobile' => "Mobile",
'sex' => "Sex",
'DOB' => "DOB",
'fundraisingAim' => "FundraisingAim",
'weeksAim' => "WeeksAim",
'lengthsAim' => "LengthsAim",
'hearAbout' => "HearAboutID",
'motivation' => "MotivationID",
'welcomePackPref' => "WelcomePackID",
'contactPref' => "ContactPrefID",
'title' => "TitleID",
);
$sql = makeInsertStmt($tablename, $namemap);
$binddata = makeBindData($userData, $namemap);
$pstmt = $pdo->prepare($sql);
$pstmt->execute($binddata);
}
Lợi ích của một sự trừu tượng như thế này là bạn không cần phải lo lắng về chính các tham số ràng buộc.