🎉 سال نو، مهارت نو، مشاوره رایگان نقشه راه برنامه نویسی (آفر ویژه ثبت نام قبل از افزایش قیمت 🔥)
۰ ثانیه
۰ دقیقه
۰ ساعت
۲ علی
prepare statement
محسن موحد حل شده توسط محسن موحد

سلام خدمت استاد و دوستان عزیز

 

 

استاد من تویه درک نحوه عملکرد متدهای prepare و bind_param کمی مشکل دارم. اینطور که شما تو کلیپ توضیح دادی برداشت من این بوده که با استفاده از این دوتا متد میشه قبل از اجرای query مقادیری که کاربر وارد کرده رو validation کرد تا امن بشن. مفهوم کلیشو فهمیدم ولی هنو کلمه اماده سازی واسم مبهمه

 

۱. طبق نوشته پایین (از سایت w۳schools) متد prepare ابتدا دستور sql رو به طرف پایگاه داده میفرسته (البته به جای پارامتر‌ها از علامت ؟ استفاده شده) 

۲. پایگاه داده اونو پردازش و کامپال و بهینه سازی میکنه و نتیجه رو بدون اجرای دستور ذخیره میکنه.

۳. اخرشم متد bind_param مقادیر رو میچسبونه به پارامترها و پایگاه داده دستور رو اجرا میکنه.  (و چون مقادیر پارامترها بعدا و توسط یک پروتکل متفاوت به سرور ارسال شده از حملات SQL جلوگیری می‌کنند)

 

از طرفی شما گفتین مقادیر رو میزاریم تویه متد bind_param  تا مشکلات امنیتیشو رفع کنه و در نهایت بزاره تویه علامت سوالا و کوئری اجرا بشه.

 

 

الان سوال من اینکه : بلاخره این وسط چه اتفاقی میوفته ؟

 

چیزی که خودم در کل فهمیدم (درست یا غلطتشو نمی‌دونم) اینه که متد prepare دستور query رو میفرسته سمت database و یک ابجکتی در اختیار ما میزاره تا بتونیم با اون کوئری که سمت database هست کار کنیم. بعدشم میشه با استفاده از متد bind_param مقادیرو جا علامت سوالا بزاریم و چون مقادیر پارامترها بعدا و توسط یک پروتکل متفاوت به سرور ارسال شده از حملات SQL جلوگیری می‌شود ( و بر خلاف گفته شما خود متد bind_param  تو امن سازی مقادیر نقش مستقیم نداره و صرفا مقادیرو bind میکنه)

 

 

Prepared statements basically work like this:

۱. Prepare: An SQL statement template is created and sent to the database. Certain values are left unspecified, called parameters (labeled "?"). Example: INSERT INTO MyGuests VALUES(?, ?, ?)

 

۲.The database parses, compiles, and performs query optimization on the SQL statement template, and stores the result without executing it

 

۳.Execute: At a later time, the application binds the values to the parameters, and the database executes the statement. The application may execute the statement as many times as it wants with different values

 

Prepared statements are very useful against SQL injections, because parameter values, which are transmitted later using a different protocol, need not be correctly escaped. If the original statement template is not derived from external input, SQL injection cannot occur.

سلام و احترام

بله درست متوجه شدید، متد prepare میاد query مارو آماده میکنه و با متد bind_param ما میایم مقادیر رو جای این علامت سوالا میزاریم

امیر صالحی ۱۹ بهمن ۱۳۹۹، ۰۸:۵۷

سلام.

مفهوم ساده ای وجود داره، طبق تعاریف ابتدا تمپلیت آماده و اصطلاحاً prepare میشه و در مرحله ی بعد عمل bind و execute انجام میشه. در PDO میتونید مقادیرو داخل متد execute بعنوان پارامترهای این تابع bind کنید. البته متدهای bindParam و bindValue هم وجود دارد.

اما Mysqli بعد از prepare از bind_param و در نهایت از execute استفاده میشه.

عمل bind و execute ممکنه چندین بار و در یک حلقه انجام بشه. (برای مثال عمل اینسرت چند کاربر و ...’)

این کلیتش بود که البته تا اینجا چیز جدیدی نگفتم فقط میخوام با مثال زیر توسط کدهای PHP و نظیرش در کدهای SQL داخل دیتابیس بهتون نشون بدم چه اتفاقی میوفته:

مثال کدهای PHP در Mysqli:

$stmt = $mysqli->prepare("SELECT * FROM users WHERE id = ?");
$stmt->bind_param("i", 5);
$stmt->execute();

مقادیرو بصورت مستقیم ارسال نمیکنیم و تمپلیت بهمراه placeholder (منظور ؟) به موتور دیتابیس ارسال میشه.

ما میتونیم مقادیرو بصورت مستقیم وارد کنیم ولی برای جلوگیری از Sql Injection از prepared statement یا parameterized statement‌ها استفاده میشه. در این روش دیگه value‌ها بصورت مستقیم در کوئری قرار نمیگیرند. چون اگر مقادیر بعنوان بخشی از کوئری باشن، کلاینت میتونه کدهای مخربی رو داخل کوئری بعنوان value تزریق کنه و در نتیجه اون value روی دیتابیس بعنوان یک دستور اجرا خواهد شد که ما با استفاده از prepare ازین اتفاق جلوگیری میکنیم.

در ادامه همین کدهای بالارو مثالش در SQL رو میارم که ببینید placeholder‌ها چطور میتونن مقدار دهی بشن:

mysql> PREPARE stmt1 FROM 'SELECT * FROM users WHERE id = ?';
mysql> SET @id = 5;
mysql> EXECUTE stmt1 USING @id;
---------------
mysql> DEALLOCATE PREPARE stmt1;

 

 

بهترین پاسخ
محسن موحد ۲۲ بهمن ۱۳۹۹، ۰۸:۰۴