পিএইচপি প্রিপেয়ার্ড স্টেটমেন্ট
SQL Injections প্রতিরোধে প্রিপেয়ার্ড স্টেটমেন্ট খুবই গুরুত্বপূর্ণ ভূমিকা পালন করে।
প্রিপেয়ার্ড স্টেটমেন্ট এবং আবদ্ধ(Bound) প্যারামিটার
প্রিপেয়ার্ড স্টেটমেন্ট এমন একটি বৈশিষ্ট্য যা সর্বোচ্চ দক্ষতার সাথে একই বা অনুরূপ SQL স্টেটমেন্টগুলোকে বার বার সম্পাদন করতে পারে।
প্রিপেয়ার্ড স্টেটমেন্ট এর কাজের ধারাঃ
- একটি SQL স্টেটমেন্টের টেমপ্লেট তৈরি করে ডেটাবজে পাঠায়। যাতে ভ্যালু উল্লেখ করা থাকে না। ভ্যালুর পরিবর্তে ("?") প্যারামিটার দেওয়া থাকে।
উদাহরনস্বরূপঃINSERT INTO testTB VALUES(?, ?, ?)
- ডেটাবেজ এই SQL স্টেটমেন্ট টেমপ্লেটকে পার্স(parse), কম্পাইল উপর ডেটাবেসে কুয়েরি অপ্টিমাইজেশন(optimization) হয় এবং ফলাফল সম্পাদন করা ছাড়া জমা করা হয়।
- পরবর্তিতে অ্যাপ্লিকেশনটি প্যারামিটারের সাথে ভ্যালু গুলোকে আবদ্ধ করে দেয় এবং ডেটাবেস স্টেটমেন্টি সম্পাদন করে। অ্যাপ্লিকেশনটি বিভিন্ন ভ্যালু সহ যতবার ইচ্ছা স্টেটমেন্টিকে সম্পাদন করতে পারে।
SQL স্টেটমেন্ট সরাসরি সম্পাদন। প্রিপেয়ার্ড স্টেটমেন্টের দুইটি প্রধান সুবিধা রয়েছেঃ
- প্রিপেয়ার্ড স্টেটমেন্টের ক্ষেত্রে সময় কম লাগে। কারন এটি কুয়েরি একবার করেই বারবার কার্য-সম্পাদন করতে পারে।
- আবদ্ধ(Bound) প্যারামিটার ব্যবহারে সার্ভারে ব্যান্ডউইডথ কম খরচ হয়। কারন এটি প্রতিবারে সম্পূর্ন কুয়েরির পরিবর্তে শুধুমাত্র প্যারামিটার গুলো পাঠায়।
- SQL ইঞ্জেকশনের প্রতিরোধে প্রিপেয়ার্ড স্টেটমেন্ট খুবই গুরুত্বপূর্ণ। কারন এর প্যারামিটারের মানগুলি যা পরবর্তীতে একটি ভিন্ন প্রোটোকল ব্যবহার করে প্রেরন করা হয়। এগুলো সঠিকভাবে পাঠানোর প্রয়োজন হয় না। তাই মূল স্টেটমেন্ট টেমপ্লেট বহিরাগত ইনপুট থেকে পাওয়া যায় না। তাই SQL ইঞ্জেকশন ঘটতে পারে না।
নিম্নের উদাহরনে মাইSQLআই(MySQLi) তে প্রিপেয়ার্ড স্টেটমেন্ট এবং আবদ্ধ প্যারামিটার ব্যবহার করা হয়েছেঃ
মাইSQLআই(MySQLi) প্রক্রিয়াঃ
<?php
// সংযোগ তৈরি
$conn = new mysqli("localhost", "username", "password", "testDB");
// সংযোগ পরীক্ষা
if ($conn->connect_error) {
die("সংযোগ ব্যর্থ হয়েছেঃ " . $conn->connect_error);
}
// SQL কমান্ডের সাথে প্যারামিটারের বন্ধন তৈরি
$statement = $conn->prepare("INSERT INTO testTB (firstname, lastname, email) VALUES (?, ?, ?)");
$statement->bind_param("sss", $firstname, $lastname, $email);
// প্যারামিটার সমুহ সেট করুন এবং কার্য-সম্পাদন করুন
$firstname = "Azizur";
$lastname = "Rahman";
$email = "aziz@example.com";
$statement->execute();
$firstname = "Tamjid";
$lastname = "Hasan";
$email = "tamjid@example.com";
$statement->execute();
$firstname = "Saleh";
$lastname = "Ahammed";
$email = "saleh@example.com";
$statement->execute();
echo "নতুন রেকর্ড সংযোগ হয়েছে।";
// স্টেটমেন্ট বিচ্ছিন্ন
$statement->close();
// সংযোগ বিচ্ছিন্ন
$conn->close();
?>
উপরের উদাহরন থেকে কোড লাইনের বর্ণনাঃ
"INSERT INTO testTB (firstname, lastname, email) VALUES (?, ?, ?)"
SQLে আমরা (?)প্রশ্নবোধক চিহ্ন ব্যবহার করি যেসকল ক্ষেত্রে আমরা পরবর্তীতে integer
, string
, double
অথবা blob
ভ্যালু ব্যবহার করবো।
তারপর bind_param()
ফাংশনটি দেখুনঃ
$statement->bind_param("sss", $firstname, $lastname, $email);
এই ফাংশনটি SQL কুয়েরির সাথে প্যারামিটারের বন্ধন যুক্ত করে এবং ডেটাবেসকে বলে প্যারামিটার গুলো কি হবে। প্যারামিটার "sss" আর্গুমেন্ট গুলো হচ্ছে ডেটা টাইপ। "s" ক্যারেক্টারটি মাইSQLকে বলে যে প্যারামিটারটি স্ট্রিং টাইপের।
আর্গুমেন্ট গুলো নিম্নের যে কোনো একটি হতে পারেঃ
- i - integer
- d - double
- s - string
- b - BLOB
আমাদের প্রতিটি প্যারামিটারের জন্য অবশ্যই এইগুলির একটি থাকতে হবে।
আমরা ডেটাবেস কিধরনের তথ্য পেতে পারে তা উল্লেখ করার মাধ্যমে SQL ইঞ্জেকশনের ঝুঁকি কমিয়ে দিচ্ছি।
সতর্কতাঃ আপনি যদি ব্যবহারকারীর কাছ থেকে ইনপুট গ্রহন করেন সে ক্ষেত্রে তথ্য অবশ্যই ভেলিডেট করে নিবেন।