ویکی کد دستورات Prepared MySQL در PHP

دستورات Prepared MySQL در PHP

از ویکی‌کد، دانشنامهٔ برنامه‌نویسی
Main Page Tutorial
Php-menu.png
موارد آموزشی
فرم‌ها در PHP
PHP پیشرفته
شیء گرایی در PHP
پایگاه داده MySQL
۱پایگاه داده MySQL
۲اتصال به MySQL
۳ساخت پایگاه داده
۴ساخت جدول
۵وارد کردن داده
۶دریافت شناسهٔ آخرین سطر
۷وارد کردن چندین داده
۸دستور Prepared
۹انتخاب داده
۱۰دستور Where
۱۱دستور Order By
۱۲حذف داده
۱۳بروزرسانی داده
۱۴محدودسازی داده
XML در PHP
AJAX در PHP
مثال‌های PHP
مرجع PHP

دستورات Prepared در برابر حملات SQL injection بسیار کاربردی هستند.

دستورات Prepared و پارامترهای Bound

یک دستور Prepared یک قابلیت است که برای اجرای دستورات SQL یکسان (یا مشابه) به صورت مکرر با راندمان بالا استفاده می‌شود.[۱]

دستورات Prepared به صورت پایه ای همانند زیر کار می‌کنند:

  1. Prepare: یک الگوی دستور SQL ایجاد می‌شود و به پایگاه داده ارسال می‌شود. مقادیر اصلی در سمت چپ که مشخص نشده‌اند، پارامترها نامیده می‌شود (که با علامت "?" مشخص شده‌اند). مثال: INSERT INTO MyGuests VALUES(?, ?, ?)
  2. پایگاه داده، الگوی دستورات SQL را پارس می‌کند، کامپایل می‌کند و بهبود عملکرد کوئری را فراهم می‌کنند و نتیجه را بدون اجرای آن ذخیره می‌کنند
  3. Execute: بعد از یک مدت زمانی، نرم‌افزار مقادیر را به پارامترها متصل می‌کند، و پایگاه داده دستور را اجرا می‌کند. نرم‌افزار ممکن است دستور را به هر تعداد که بخواهد با مقادیر مختلف اجرا کند

در مقایسه با اجرای دستورات SQL به صورت مستقیم، دستورات Prepared سه مزیت دارند:

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

دستورات Prepared در MySQLi

مثال زیر از دستور Prepared و پارامترهای bound استفاده می‌کند:

مثال (MySQLi با دستورات Prepared)

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

// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);

// Check connection
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}

// prepare and bind
$stmt = $conn->prepare("INSERT INTO MyGuests (firstname, lastname, email) VALUES (?, ?, ?)");
$stmt->bind_param("sss", $firstname, $lastname, $email);

// set parameters and execute
$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 (?, ?, ?)"

در SQL، ما یک علامت سوال (?) درج کرده‌ایم که ما می‌خواهیم به جای آنها، یک عدد صحیح، یک رشته متنی، یک عدد اعشاری یا سایر مقدارها را جایگزین کنیم.

سپس، نگاهی به تابع bind_param() داشته باشید:

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

این تابع پارامترها را به کوئری SQL متصل می‌کند و به پایگاه داده می‌گوید که پارامتر‌ها چه هستند. آرگومان "sss" نوع داده‌هایی که پارامتر از آن نوع هستند را لیست می‌کند. کاراکتر s به MySQL می‌گوید که پارامتر یک رشته متنی است.

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

  • i - عدد صحیح
  • d - عدد اعشاری
  • s - رشته‌ای
  • b - سایر

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

با گفتن نوع داده‌ها به mysql، ما ریسک حملات SQL injection را به حداقل می‌رسانیم.

نکته: اگر ما بخواهیم که هرگونه داده را از منابع خارجی (مانند ورودی کاربر) درج کنیم، این امر بسیار مهم است که کاراکترهای غیرمجاز از داده پاک شده و داده ارزیابی شود.

دستورات Prepared در PDO

مثال زیر از دستورات Prepared و پارامترهای bound در PDO استفاده می‌کند:

مثال (PDO با دستورات Prepared)

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

try {
    $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
    // set the PDO error mode to exception
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // prepare sql and bind parameters
    $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);

    // insert a row
    $firstname = "John";
    $lastname = "Doe";
    $email = "john@example.com";
    $stmt->execute();

    // insert another row
    $firstname = "Mary";
    $lastname = "Moe";
    $email = "mary@example.com";
    $stmt->execute();

    // insert another row
    $firstname = "Julie";
    $lastname = "Dooley";
    $email = "julie@example.com";
    $stmt->execute();

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


منابع آموزشی