آموزش PDO در php
PDO کوتاهشدهی عبارت «PHP Data Objects» به معنی اشیای اطلاعاتی پیاچپی است. PDO جدیدترین روش ارتباط با پایگاه داده از انواع مختلف به شمار میرود. با استفاده از PDO میتوان به بیش از ۱۰ پایگاه دادهی مختلف از جمله MySQL، SQLite ، Firebird و SQL Server متصل شد.
علاوه بر این PDO قابل توسعه است و با ایجاد و نصب افزونههای جدید، امکان اتصال آن به انواع سیستمهای ذخیرهسازی اطلاعاتی فراهم است.
چرا از PDO استفاده میکنیم؟
در گذشته و در هنگام طراحی سایت با php دو روش برای ارتباط با پایگاه داده وجود داشته است. روش نخست و قدیمیتر دستوراتی هستند که با mysql پیشوند شدهاند و دستوراتی که اندکی جدیدتر هستند، دستوراتی هستند که با عبارت mysqli شروع میشوند.
این دو سیستم هر یک مزایا و معایبی داشتند. با توجه حرکت اغلب زبانهای برنامهنویسی به سمت سیستمهاش شیئ گرا، و نیاز به رابطی که بتواند با انواع مختلف پایگاههای داده ارتباط برقرار کند، PDO طراحی و در نگارشهای جدید php به صورت پیشفرض قرار گرفت.
PDO بر خلاف دو روش قبلی، تنها با استفاده از سیستم شیئگرایی قابل استفاده است. و مانند mysql و mysqli توابعی برای خواندن و نوشتن اطلاعات از پایگاه داده در اختیار برنامهنویسان قرار نمیدهد.
ارتباط با پایگاه داده
ارتباط با پایگاه داده در PDO به شکل زیر انجام میشود:
1 2 3 4 5 6 7 8 9 10 11 12 |
$dsn = 'mysql:dbname=roka;host=localhost;port=3306'; $username = 'root'; $password = 'password'; try { $db = new PDO( $dsn, $username, $password, array( PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8" ) ); } catch( PDOException $e ) { die( 'رخداد خطا در هنگام ارتباط با پایگاه داده:<br>' . $e ); } |
قرارگیری عبارت «mysql» در ابتدای dsn یا Data Source Name بالا سبب میشود تا PDO برای ارتباط با پایگاه داده از افزونهی MySql استفاده کند.
در هنگام ایجاد ارتباط با پایگاه داده، مشخص میکنیم که اطلاعات ما به صورت UTF8 ارسال و دریافت میشود تا بتوانیم متنهای فارسی را به درستی ذخیره و بازیابی کنیم.
خواندن اطلاعات - جستجوی پایگاه داده
اکنون برای خواندن اطلاعات به شکل زیر عمل خواهیم کرد. در قطعه کد زیر شرکتهایی که نام آنها با عبارت مورد نظر ما یکسان است جستجو میکنیم:
1 2 3 |
$company_name = 'roka'; $sql = "SELECT * FROM `companies` WHERE `name` = '{$company_name}'"; $companies = $db->query( $sql ); |
مقدار بازگشتی در دستور query یک PDOStatement است که میتواند برای خواندن تک تک ردیفهای دارای شرط کوئری مورد استفاده قرار گیرد.
1 2 3 |
foreach( $companies->FetchAll() as $company ) { echo "<div>{$company[ 'name' ]}</div>"; } |
محاسبه تعداد ردیفها
همچنین میتوانیم تعداد ردیفهای موجود در PDOStatement را به صورت زیر محاسبه کنیم:
1 |
echo $companies->rowCount(); |
امنیت
PDO علاوه بر پشتیبانی از سیستم قدیمی جلوگیری از SQL Injection، از روش جدید Prepared Statement هم پشتیبانی میکند که مانع رخداد خطاهای امنیتی میشود. در ادامه کدهایی برای شیوهی عملکرد هر دو روش مشاهده میکنید:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// old method $escaped_param = $db->quote( 'عبارت خطرناک دریافت شده از کاربر' ); // prepared statements $statement = $db->prepare( 'SELECT * FROM companies WHERE `name`=?'); $statement->bindValue(1, 'roka'); $statement->execute(); // $statement->Fetch(); // $statement->FetchAll(); $statement2 = $db->prepare('SELECT * FROM companies WHERE `name`=:name' ); $statement2->bindValue(':name', 'roka'); $statement2->execute(); // $statement2->Fetch(); // $statement2->FetchAll(); |
با ارسال پارامتر به دستور execute میتوانیم از دستورات bindValue صرف نظر و کدهای نوشتهشده را کوتاهتر کنیم:
1 2 |
$statement->execute( array( 1 => 'roka' ) ); $statement2->execute( array( ':name' => 'roka' ) ); |
درج اطلاعات در پایگاه داده
برای درج اطلاعات میتوانیم به شکل زیر عمل کنیم:
1 2 3 4 5 |
$statement = $db->prepare( 'INSERT INTO students( fname, lname ) values ( :fname, :lname )' ); $statement->execute( [ ':fname' => $fname, ':lname' => $lname, ] ); |
دقت کنید که برای امنیت بیشتر، از حالت prepared استفاده کردهایم.
دریافت آخرین شناسه درج شده در پایگاه داده
پس از درج اطلاعات در جدول پایگاه داده، ممکن است بخواهیم شناسهی ردیف درج شده را در اختیار داشته باشیم. برای انجام این کار از کدهای زیر استفاده میکنیم:
1 |
echo $db->lastInsertId(); |
بهروزرسانی ردیفها در پایگاه داده
برای بهروزرسانی ردیفها در پایگاه داده مثل کاری که در INSERT انجام دادیم میتوانیم از عبارتهای prepared استفاده کنیم.
1 2 3 4 5 6 |
$sql = "UPDATE companies SET `name`=:new_name WHERE `name`=:old_name"; $statement = $db->prepare( $sql ); $statement->execute( [ ':old_name' => 'roka', ':new_name' => 'روکا', ] ); |
Transacionها
یکی دیگر از موارد مورد نیاز در هنگام خواندن و نوشتن اطلاعات از پایگاه داده، Transaction ها هستند.
Transaction زمانی کاربرد دارد که بخواهیم چندین کوئری را همراه یکدیگری اجرا کنیم و اگر به هر دلیل خطایی در یکی از کوئریها ایجاد شد، تمامی کارهای انجام شده تا کنون به حالت قبل برگردند. مزیت دیگر استفاده از Transaction افزایش سرعت ذخیرهسازی اطلاعات است. زیرا در حالت پیشفرض پس از هر ذخیرهسازی اطلاعات، بررسیهای امنیتی از ذخیرهسازی کامل اطلاعات به انجام میرسد که نیازمند صرف مقداری زمان است. با استفاده از Transaction این عملیات تنها یک بار پس از پایان تمامی دستورات انجام خواهد شد.
برای ایجاد یک Transaction به شیوهی زیر عمل میکنیم:
1 2 3 4 5 6 7 |
$db->beginTransaction(); var_dump( $db->inTransaction() ); // true // کوئریهای لازم در این بخش اجرا میشوند $db->commit(); |
برای کسب اطلاعات بیشتر در خصوص استفاده از امکانات PDO میتوانید به راهنمای php مراجعه کنید.