General error: 25 bind or column index out of range

امروز میخوام درباره خطای General error: 25 bind or column index out of range صحبت کنم.

همونطور که از متن خطا معلوم هست مشکل در هماهنگ کردن پارامترهای متصل شده (بایند شده) به کوئری اس کیو ال هست.

کد زیر رو در نظر بگیرید

اگه این رو اجرا کنید با همین خطا مواجه میشید چون دو تا placeholder (تو اینجا منظور ? هست) مشخص شده ولی تو تابع execute فقط یک مقدار مشخص شده که دلیل بروز این خطا هست.

کدی که این مشکل رو برای من ایجاد کرده بود این هست

بعد از خوندن مستندات PHP و PDO متوجه شدم که خود placeholder نباید تو کوتیشن یا هرچیز دیگه ای قرار بگیره فقط خود placeholder باید باشه دلیلش هم این هست که وقتی کوئری prepare شده میخواد  شبیه سازی (emulate) بشه (چه توسط PDO چه توسط MySQL) سیستمی که قرار هست اون رو چک کنه (PDO یا MySQL منظورم هست) میاد placeholder ها رو جدا میکنه و کل کوئری رو صحت سنجی میکنه حالا اینجا اگه کوتیشن یا هرچیز دیگه ای ببینه خطا میده چون دیگه قرار نیست هیچ مقداری دیگه تو کوئری باشه. به خاطر همین صجت سنجی کوئری، دیگه نام جدول و نام ستون نمیتونه به صورت نشانگر placeholder باشه چون بدون مقادیر مشخص شده اونها، امکان صحت سنجی وجود نداره.

برابر توضیحات، کد بالا باید به این صورت باز نویسی بشه

همچنین میتونیم با استفاده از تابع bindParam این کار رو انجام بدیم.

یا

دلیل اصلی شبیه سازی هم جلوگیری از حملات SQL Injection هست; حالا شبیه سازی به دو صورت انجام میشه یا توسط PDO یا MySQL. حالا فرقشون چیه؟

اگه شبیه سازی رو MySQL انجام بده ابتدا خود کوئری ارسال میشه بعد از اینکه MySQL اون رو تائید کرد(البته کارهای دیگه ای مثل آنالیز کردن و بهینه سازی کوئری هم انجام میشه) در یک ارتباط دیگه خود مقادیر اصلی ارسال میشه.

اگه شبیه سازی توسط PDO انجام بشه اول PDO مقادیر رو فیلتر میکنه تا از نظر امنیتی مشکل ساز نشن و سپس داخل کوئری جایگزاری میکنه و اونرو به MySQL میفرسته همونجور که مشخص هست تو این روش یک درخواست کمتر به سرور MySQL ارسال میشه.

من خودم ترجیح میدم MySQL عملیات جایگزاری رو انجام بده فکر میکنم مطمئن تر هست همچنین فکر میکنم درخواست اضافی که تو این روش هست خیلی رو سرور فشار نمیاره یه چیز دیگه هم بگم که ممکن هست سیستم دیتابیستون از شبیه سازی پشتیبانی نکنه که اینجا میتونید کاری کنید که خود PDO این کار رو براتون انجام بده.

مقدار متغیر ATTR_EMULATE_PREPARES مشخص میکنه که عملیات شبیه سازی عبارات prepare شده توسط PDO انجام بشه یا توسط سرور دیتابیس.

 

جستجو در کل مطالب سایت

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *