میخوای وارد بازار کار بشی و محصولات خودت رو بفرشی همین الان ثبت نام کن
0

دستور prepare در PHP

دستورات prepare برای مقابله با SQL injection ها بسیار کارآمداند.


دستورات (Prepared) و Bind کردن پارامترها

با استفاده از  Prepared، می توانید یک کوئری یکسان را به تعداد دفعات دلخواه با راندمان بالا اجرا نمایید.

نحوه عملکرد دستورات آماده یا Prepared:

  1. Prepare: با استفاده از این دستور می توانید قالبِ یک کوئری SQL را ایجاد کرده و به پایگاه داده ارسال نمایید. در واقع دلیل استفاده از کلمه قالب در اینجا این است که بجای پارامترهای لازم در کوئری، از علامت سوال (؟) استفاده می کنیم.

    مثال (دستور prepare در PHP)

    INSERT INTO MyGuests VALUES(?, ?, ?)
  2. حالا قالب SQL ارسال شده، توسط پایگاه داده، تجزیه و کامپایل می شود و در ادامه بهینه ساز کوئری (query optimization) روی آن اجرا می شود و در نهایت نتیجه کار بدون اجرا در پایگاه داده ذخیره می شود.
  3. Execute: در ادامه ی اسکریبت، مقادیر لازم را به پارامترهای کوئری مان Bind می کنیم و با استفاده از دستور Execute، کوئری را اجرا می کنیم. اما نکته ای که وجود دارد این است که کوئری ما همچنان در پایگاه داده وجود دارد و می توانیم مجدداً آنرا با پارامترهای جدید اجرا کنیم !

روش استفاده از دستورات prepare در مقایسه با اجرای مستقیم کوئری ها دو مزیت اصلی دارد:

  • دستورات prepare ، زمان تجزیه (parsing) کوئری را کاهش می دهند و این در حالی است که برای مواقعی که قصد داریم یک کوئری را به دفعات اجرا کنیم، این زمان فقط یکبار محاسبه خواهد شد.
  • از آنجایی که برای هر بار اجرای کوئری، فقط باید پارامترها را ارسال کنیم، بنابراین پهنای باند کمتری مصرف خواهد شد.
  • دستورات prepare برای مقابله با SQL injection ها بسیار کارآمد هستند و این بخاطر استفاده از یک پروتکل متفاوت برای انتقال مقادیر پارامترهاست.

 

تزریق SQL یا SQL injection چیست؟
SQL injection زمانی رخ می دهد که شما از کاربر یک ورودی می خواهید ( مثلا نام خانوادگی ، سن و … ) و کاربر بجای نام، یک دستور MySQL را وارد می نماید و این دستور بدون اطلاع شما بر روی دیتابیس اجرا می شود.

مثال (دستور prepare در PHP)

$username="''; Delete From users";
$query="Select From users where usernamr=$username";
echo $query;

نتیجه کد بالا

Select From users where usernamr= ''; Delete From users

توضیح: همان طور که در کد بالا مشاهده می کنید، ورودی مخرب، باعث می شود که دو کوئری روی پایگاه داده اجرا شود و از آن مهمتر، کوئری دوم است که باعث می شود تا تمام اطلاعات جدول users حذف شود

 


دستورات Prepared در MySQLi

در مثال زیر،نحوه ی استفاده از دستورات Prepared و همچنین نحوه ی Bind کردن پارامترها در MySQLi نشان داده شده است:

مثال(MySQLi with Prepared Statements)

<?php
$servername = “localhost”;
$username = “username”;
$password = “password”;
$dbname = “myDB”;

// ایجاد ارتباط به پایگاه داده
$conn = new mysqli($servername, $username, $password, $dbname);

// اطمینان از صحت ارتباط
if ($conn->connect_error) {
die(“Connection failed: ” . $conn->connect_error);
}

// تنظیم کوئری و بایند کردن پارامترها با استفاده از دستورات آماده
$stmt = $conn->prepare(“INSERT INTO MyGuests (firstname, lastname, email) VALUES (?, ?, ?)”);
$stmt->bind_param(“sss”, $firstname, $lastname, $email);

// تنظیم پارامترها و اجرای کوئری
$firstname = “John”;
$lastname = “Doe”;
$email = “john@example.com“;
$stmt->execute();

$firstname = “Mary”;
$lastname = “Moe”;
$email = “mary@example.com“;
$stmt->execute();

$firstname = “Julie”;
$lastname = “Dooley”;
$email = “julie@example.com“;
$stmt->execute();

echo “New records created successfully”;

$stmt->close();
$conn->close();
?>

توضیح مثال بالا:

“INSERT INTO MyGuests (firstname, lastname, email) VALUES (?, ?, ?)”

در کوئری مان می توانیم از علامت سوال (؟) استفاده کنیم، این علامت در ادامه با یک عدد صحیح (integer)، رشته (string)، عدد اعشاری (double) یا داده های با اندازه بزرگ (BLOB – Binary Large OBject) جایگزین خواهد شد.

در ادامه نگاهی به تابع ()bind_param خواهیم انداخت:

$stmt->bind_param(“sss”, $firstname, $lastname, $email);

با استفاده از تابع ()bind_param، می توانیم پارامترها را به کوئری SQL مان Bind کنیم و به پایگاه داده بگوییم که چه پارامترهایی داریم. همچنین با استفاده از آرگومان اول یعنی “sss”، نوع پارامترها را تعیین می کنیم. کاراکتر s به MySQL می گوید که پارمتر ما از نوع رشته (string) است.

نوع آرگومان ها می تواند یکی از چهار گزینه زیر باشد:

  • i – integer
  • d – double
  • s – string
  • b – BLOB

برای هر کدام از آرگومان ها، باید یکی از چهار مقدار بالا را تنظیم کنیم.

زمانی که نوع پارامترها را مشخص می کنیم، ریسک تزریقات SQL یا SQL injections توسط هکرها را به حداقل می رسانیم.

توجه: اگر قصد دارید که داده ی دریافتی از کاربران را در پایگاه داده ذخیره کنید، اعتبارسنجی داده ها یک امر بسیار مهم است .

 


دستورات آماده یا Prepared در PDO

در مثال زیر،نحوه ی استفاده از دستورات آماده یا Prepared و همچنین نحوه ی Bind کردن پارامترها در PDO نشان داده شده است:

مثال(PDO with Prepared Statements)

<?php
$servername = “localhost”;
$username = “username”;
$password = “password”;
$dbname = “myDBPDO”;

try {
//ایجاد ارتباط
$conn = new PDO(“mysql:host=$servername;dbname=$dbname”, $username, $password);
// تنظیم حالت برخورد با خطاها
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

// تنظیم کوئری و بایند کردن پارامترها با استفاده از دستورات آماده
$stmt = $conn->prepare(“INSERT INTO MyGuests (firstname, lastname, email)
VALUES (:firstname, :lastname, :email)”);
$stmt->bindParam(‘:firstname’, $firstname);
$stmt->bindParam(‘:lastname’, $lastname);
$stmt->bindParam(‘:email’, $email);

// تنظیم پارامترها و اجرای کوئری
$firstname = “John”;
$lastname = “Doe”;
$email = “john@example.com“;
$stmt->execute();

// تنظیم پارامترها و اجرای کوئری
$firstname = “Mary”;
$lastname = “Moe”;
$email = “mary@example.com“;
$stmt->execute();

// تنظیم پارامترها و اجرای کوئری
$firstname = “Julie”;
$lastname = “Dooley”;
$email = “julie@example.com“;
$stmt->execute();

echo “New records created successfully”;
}
catch(PDOException $e)
{
echo “Error: ” . $e->getMessage();
}
$conn = null;
?>


 

نظراتتون رو زیر همین پست با ما به اشتراک بگذارید.

 

ارسال دیدگاه

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

×

سلام کاربر عزیز

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

روی لوگومون کلیک کنید

× چطور میتونم کمکتون کنم؟