Вопрос или проблема
У меня есть этот громадный запрос, вызывающий головную боль, который мне нужно выполнить, envolvendo 65 полей формы, которые необходимо вставить в базу данных, используя подготовленные операторы mysqli.
Проблема, с которой я сталкиваюсь, заключается в том, что количество переменных, на которые я пытаюсь вызвать bind_param
, не соответствует количеству “s”, которые я использую. Я посчитал это десятки раз и не вижу, где я ошибаюсь. Переменных 65, и “s” тоже 65.
Кто-нибудь видит что-то, что я упускаю? Или, возможно, я использую метод bind_param неправильным образом?
// Подготовка нашего запроса через mysqli, который будет автоматически экранировать все некорректные символы, чтобы предотвратить инъекцию
$query3 = 'INSERT INTO datashep_AMS.COMPLETE_APPLICATIONS (
project_name,
status,
funding_requested,
project_title,
program,
county,
parish,
name_of_watercourse,
which_is_a_tributary_of,
name_of_applicant,
contact_person_or_project_supervisor,
relationship_to_organization,
business_phone,
home_phone,
email,
signature_of_thesis_or_study_supervisor,
mailing_address,
postal_code,
website,
mailing_address_for_payment,
hst_registration_no,
total_cost_dollar,
total_cost_percent,
dollar_amount_requested_from_nbwtf,
percent_amount_requested_from_nbwtf,
descriptive_summary,
background_of_organization,
mandate,
years_in_existence,
membership,
accomplishments,
previous_project_name,
previous_project_number,
previous_project_amount_received_from_nbwtf,
summary_of_activities,
summary_of_Results,
project_title_2,
reason_and_or_purpose,
objectives,
project_description,
methods,
equipment_and_materials_required,
personnel_required,
proposed_start_date,
proposed_end_date,
type_of_data_to_be_stored,
where_will_it_be_housed,
monitoring,
short_term_achievement,
long_term_achievement,
previous_studies,
required_permits,
consultants,
short_term_commitment,
long_term_commitment,
project_duration,
project_evaluation,
promotion_of_project,
promotion_of_client,
publication_of_results,
community_benefits,
effects_on_traditional_uses,
possible_changes_in_public_access_to_areas,
possible_impact_on_wildlife_and_or_environment,
likelihood_of_future_requests_for_funding,
list_all_other_funding_sources_for_this_project
) VALUES (
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?
)';
// "Подготовка" запроса с использованием mysqli->prepare(query) -- что эквивалентно mysql_real_escape_string -- другими словами, это безопасный метод инъекции в базу данных
$stmt = $dbConnection->prepare($query3);
// "Bind_param" == замена всех "?" в вышеупомянутом запросе переменными ниже
$stmt->bind_param("s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s", $project_name, $status, $funding_requested, $project_title, $program, $county, $parish, $name_of_watercourse, $which_is_a_tributary_of, $name_of_applicant, $contact_person_or_project_supervisor, $relationship_to_organization, $business_phone, $home_phone, $email, $signature_of_thesis_or_study_supervisor, $mailing_address, $postal_code, $website, $mailing_address_for_payment, $hst_registration_no, $total_cost_dollar, $total_cost_percent, $dollar_amount_requested_from_nbwtf, $percent_amount_requested_from_nbwtf, $descriptive_summary, $background_of_organization, $mandate, $years_in_existence, $membership, $accomplishments, $previous_project_name, $previous_project_number, $previous_project_amount_received_from_nbwtf, $summary_of_activities, $summary_of_Results, $project_title_2, $reason_and_or_purpose, $objectives, $project_description, $methods, $equipment_and_materials_required, $personnel_required, $proposed_start_date, $proposed_end_date, $type_of_data_to_be_stored, $where_will_it_be_housed, $monitoring, $short_term_commitment, $long_term_achievement, $previous_studies, $required_permits, $consultants, $short_term_commitment, $long_term_commitment, $project_duration, $project_evaluation, $promotion_of_project, $promotion_of_client, $publication_of_results, $community_benefits, $effects_on_traditional_uses, $possible_changes_in_public_access_to_areas, $possible_impact_on_wildlife_and_or_environment, $likelihood_of_future_requests_for_funding, $list_all_other_funding_sources_for_this_project);
// Выполнение фактического запроса!
$stmt->execute();
Количество символов в строке определения типа должно быть равно количеству заполнительных знаков (? знаков) в SQL запросе.
// три ? знака
$stmt->prepare("INSERT INTO table (one, two, three) VALUES (?,?,?)");
$stmt->bind_param("sss", $one, $two, $three);
// три символа s (и три переменные тоже)
Обратите внимание, что символы в строке определения типа не должны разделяться запятыми.
Вы можете увидеть этот формат в примерах на странице руководства.
Есть 65 строковых параметров, так что если есть 65 символов s, то у вас правильное количество. Однако ошибки появляются, потому что вы разделили символы s запятыми. Вместо $stmt->bind_param("s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s..."
должно быть
$stmt->bind_param("sssssssssssssssss..."
Это должно решить ваши ошибки.
Символ в bind_param
не должен разделяться запятой.
Если вам нужно связать две переменные, сделайте так:
$stmt->bind_param('ss', $firstvariable, $secondvariable);
.
Ответ или решение
Когда вы сталкиваетесь с ошибкой mysqli_stmt::bind_param(): Number of elements in type definition string doesn't match number of bind variables
, это обычно указывает на несоответствие между количеством переменных и количеством символов в строке определения типа. В вашем случае приведённый запрос включает в себя 65 переменных, поэтому строка определения типов также должна содержать ровно 65 символов ‘s’ без каких-либо разделителей между ними.
Основные нюансы, о которых стоит помнить:
-
Строка определения типов: Строка, передаваемая в
bind_param
, должна содержать только типы данных, которые вы передаете, и не должна содержать запятых или пробелов. Ваша текущая строка имеет вид:"s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s"
Это неверно. Вместо этого она должна выглядеть так:
"ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"
-
Количество переменных и символов: Убедитесь, что количество переменных, передаваемых в функцию
bind_param
, соответствует количеству символов в строке определения типов. Например, если вы используете 65 строковых переменных, количество символов ‘s’ должно быть 65. -
Правильное использование: Также в методе
bind_param
необходимо избегать синтаксических ошибок и следить за тем, чтобы все переменные правильно определялись и передавались в функцию. Это важно для обеспечения корректности выполнения запроса.
Пример коррекции
В вашем случае, корректный вызов метода bind_param
должен выглядеть следующим образом:
$stmt->bind_param("ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss",
$project_name,
$status,
$funding_requested,
$project_title,
$program,
// добавьте здесь оставшиеся переменные
$list_all_other_funding_sources_for_this_project);
Заключение
Правильная структура вызова bind_param
жизненно важна для успешного выполнения подготовленных запросов. Убедитесь, что вы точно подсчитали количество переменных и не добавляли лишние символы между ними. В случае возникновения дальнейших проблем полезно использовать отладочные сообщения для проверки, какие переменные и типы данных вы передаете на каждом шаге.