این تمرین به PHP، افزونه pdo_mysql و یک دیتابیس آزمایشی MySQL نیاز دارد. متغیرهای محیطی DB_HOST، DB_PORT، DB_DATABASE، DB_USERNAME و DB_PASSWORD را برای حساب مخصوص تمرین تنظیم کنید؛ رمز را داخل کد ننویسید. حساب تمرین باید مجوز CREATE TEMPORARY TABLES داشته باشد. جدول موقت پس از بسته شدن اتصال حذف می‌شود.

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

ورودی کاربر نباید بخشی از ساختار رشته SQL شود. Prepared Statement ساختار کوئری را از مقدار داده جدا می‌کند. نام جدول و ستون را نمی‌توان با placeholder مقداردهی کرد؛ برای انتخاب‌های پویا باید از فهرست مجاز استفاده کنید.

یک مثال قابل اجرا

کد زیر را در demo.php ذخیره کنید. هم درج داده و هم جست‌وجو با پارامتر انجام می‌شوند. خروجی شامل نام Reza خواهد بود.

<?php
$dsn = sprintf("mysql:host=%s;port=%d;dbname=%s;charset=utf8mb4",
    getenv("DB_HOST") ?: "127.0.0.1",
    (int) (getenv("DB_PORT") ?: 3306), getenv("DB_DATABASE"));
$db = new PDO($dsn, getenv("DB_USERNAME"), getenv("DB_PASSWORD"), [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_EMULATE_PREPARES => false,
]);
$db->exec("CREATE TEMPORARY TABLE practice_users (name VARCHAR(100), email VARCHAR(254))");
$insert = $db->prepare("INSERT INTO practice_users VALUES (?, ?)");
$insert->execute(["Reza", "reza@example.test"]);

$query = $db->prepare("SELECT name FROM practice_users WHERE email = :email");
$query->execute(["email" => "reza@example.test"]);
print_r($query->fetchAll(PDO::FETCH_ASSOC));

تمرین

با php demo.php برنامه را اجرا کنید. یک کاربر دیگر درج کنید و ایمیل جست‌وجو را تغییر دهید. وقتی ایمیل وجود ندارد، خروجی آرایه خالی می‌شود. در برنامه واقعی، اطلاعات اتصال را بیرون از کد عمومی نگه دارید و پیام خطای داخلی را به کاربر نمایش ندهید.

تمرین

placeholder در PDO برای کدام مورد مناسب است؟

  • نام جدول
  • مقدار ایمیل کاربر
  • کل دستور SQL
پارامترها برای مقادیر هستند؛ ساختار SQL باید از قبل تعیین شده باشد.

PHP Manual — Prepared Statements ↗