نقطه ویرگول;

هر از گاهی از هر چیزی

هر از گاهی از هر چیزی

PDO یا MySQLi یک انتخاب ساده

دوشنبه, ۸ اسفند ۱۳۹۰، ۰۲:۵۰ ب.ظ
برای کار با یه دیتابیس در پی اچ پی شما می تونید انتخاب های گوناگونی داشته باشید. اما دوتا از بهترین ها در این زمینه PDO و MySQLi هستند که در این بخش قصد داریم مقایسه ی مختصری داشته باشیم بین این دو کتابخانه. شما کدوم رو انتخاب کردید؟ آیا می دونید که هر کدوم چه ویژگی هایی دارن؟ برای بررسی این دو کلاس می تونید این بحث رو تا انتها بخونید و نظراتتون رو بگید.
برای دسترسی به دیتابیس در php دو راه خوب هست : PDO و MySQLi. اما هر کدوم از این دو کتابخانه ویژگی هایی دارن که آشنایی باهاشون باعث می شه انتخاب بهتری داشته باشید.
توضیحات کلی:
PDO MySQLi
پشتیبانی از دیتابیس ها 12 موتور مختلف MySQL فقط
API شی گرا شی گرا + معمولی
برقراری ارتباط آسان آسان
پارامترهای نامگذاری شده بله خیر
پشتیبانی از آبجکت بله بله
عبارات فراهم شده
(برای کاربر)
بله نه
کارایی سریع سریع
پشتیبانی از استورد پروسیجر ها بله بله

اتصال :


روش اتصال به پایگاه داده در هر دوی این کتابخانه ها ساده ست. می تونید به این روش عمل کنید:
// PDO
$pdo = new PDO("mysql:host=localhost;dbname=database", 'username', 'password');

// mysqli, روش معمول
$mysqli = mysqli_connect('localhost','username','password','database');

// mysqli, روش شی گرا
$mysqli = new mysqli('localhost','username','password','database');

پشتیبانی از API ها:


هر دوی این کتابخانه ها از شی گرایی پشتیبانی می کنن اما MySQLi علاوه بر پشتیبانی از شی گرایی، اجازه برنامه نویسی به روش معمولی رو هم میده. این یکی از مزایای MySQLi هستش که به برنامه نویس های مبتدی اجازه می ده سریع تر به سمتش برن اما از طرف دیگه اگر شما در کار با PDO کمی حرفه ای بشید می تونید از تمام دیتابیس های موجود استفاده کنید که خوب این براتون خیلی می تونه مفید باشه.

پشتیبانی از دیتاتبیس ها:


فکر این رو بکنید که شروع می کنید به کار با MySQL و پس از اتمام برنامه تون کارفرما می خواد که از MSSQL استفاده کنه یا اینکه حجم دیتابیس تون بالا می ره و تصمیم می گیرید از oracle استفاده کنید. در این صورت آرزو می کردید که کاش با PDO کار کرده بودید :D چون در این مورد MySQLi فقط از دیتابیس MySQL پشتیبانی می کنه ولی PDO از 12 پایگاه داده ی متفاوت پشتیبانی می کنه و به راحتی می تونید بین اینها سوییچ کنید.
لیست دیتابیس هایی که PDO پشتیبانی می کنه به شرح زیر می باشد :
  • CUBRID
  • MS SQL Server
  • Firebird/Interbase
  • IBM
  • Informix
  • MySQL
  • MS SQL Server
  • Oracle
  • ODBC and DB2
  • PostgreSQL
  • SQLite
  • 4D
خوب نظرتون چیه؟ :)
با استفاده از این کد می تونید لیست پایگاه داده هایی رو که PDO پشتیبانی می کنه ببینید:
var_dump(PDO::getAvailableDrivers());

پشتیبانی از پارامترهای نامگذاری شده:


این هم یکی از ویژگی های PDO هستش که از پارامترهای نام گذاری شده خیلی ساده تر از پارامترهای عددی میشه باهاش کار کرد. برای درک بهتر موضوع به این دوتکه کد دقت کنید:
//pdo
$params = array(':username' => 'test', ':email' => $mail, ':last_login' => time() - 3600);

$pdo->prepare('
SELECT * FROM users
WHERE username = :username
AND email = :email
AND last_login > :last_login');

$pdo->execute($params);

//MySQLi
$query = $mysqli->prepare('
SELECT * FROM users
WHERE username = ?
AND email = ?
AND last_login > ?');

$query->bind_param('sss', 'test', $mail, time() - 3600);
$query->execute();

شاید کدها در MySQLi کمی کوتاه تر و ساده تر به نظر بیان ولی وقتی به پارامترها دقت کنید می بینید که در PDO شما می تونید پارامترها رو نامگذاری کنید. گاهی در حین کار برنامه نویس با بزرگ تر شدن برنامه اش کمی گیج می شه و این پارامترهای نامگذاری شده می تونن توی درک بهتر کد و خوانایی شون اهمیت ویژه ای داشته باشن.
ولی متاسفانه MySQLi این ویژگی رو نداره و ازش پشتیبانی نمی کنه.

پشتیبانی از آبجکت ها:


هر دوی این کتابخانه ها از آبجکت ها پشتیبانی می کنن و می تونن پس از درخواست نتیجه رو به صورت آبجکت برگردونن. اما این کجا و آن کجا :D
فرض کنید یه جدول تو پایگاه داده داریم با نام user و فیلدهای خودش. به این کد دقت کنید:
class User {
public $id;
public $first_name;
public $last_name;

public function info()
{
return '#'.$this->id.': '.$this->first_name.' '.$this->last_name;
}
}

بدون استفاده از این ویژگی شما باید قبل از استفاده از () info مقدار تمامی فیلدها رو شخصن تعیین کنید. اما با استفاده از این روش شما می تونید مقادیر موردنظرتون رو از پیش تعریف کنید قبل از اینکه هنوز آبجکتی ساخته شده باشه. برای نمونه به این کد توجه کنید:
$query = "SELECT id, first_name, last_name FROM users";

// PDO
$result = $pdo->query($query);
$result->setFetchMode(PDO::FETCH_CLASS, 'User');

while ($user = $result->fetch()) {
echo $user->info()."n";
}
// MySQLI, روش معمولی
if ($result = mysqli_query($mysqli, $query)) {
while ($user = mysqli_fetch_object($result, 'User')) {
echo $user->info()."n";
}
}
// MySQLi, روش شی گرا
if ($result = $mysqli->query($query)) {
while ($user = $result->fetch_object('User')) {
echo $user->info()."n";
}
}

امنیت:


هر دوی این کتابخانه ها به صورت پیش فرض از حملات SQL injection جلوگیری می کنند. توابعی دارن که می تونید با استفاده از اونا ورودی هاتون رو پاک سازی کنید. یا بر اساس مقادیر از پیش تعریف شده چک کنید.
یه مثال ساده از این روش. آقای هکر می خواد از طریق نام کاربری و از طریق درخواست HTTP دیتابیس ما رو هک کنه. کد ما این میشه:
$query = "SEL$_GET['username'] = "'; DELETE FROM users; /*"
اگر ما ورودی رو چک و پاکسازی نکنیم آقای هکر عزیز مثلن می تونه تمامی یوزرهای مارو پاک کنه (البته هر دوی این کتابخونه ها کوئری های چنگانه (multiple query) رو پشتیبانی می کنن)
// PDO, پاکسازی دستی
$username = PDO::quote($_GET['username']);

$pdo->query("SELECT * FROM users WHERE username = $username");

// mysqli, پاکسازی دستی
$username = mysqli_real_escape_string($_GET['username']);

$mysqli->query("SELECT * FROM users WHERE username = '$username'");

همونطوری که می بینید ()PDO::quote علاوه بر پاکسازی ورودی ها اونها رو داخل کوتیشن هم میگذاره. اما () mysqli_real_escape_string فقط رشته رو پاکسازی می کنه و خودتون به صورت دستی باید اون رو داخل کوتیشن بزارید.
// PDO
$pdo->prepare('SELECT * FROM users WHERE username = :username');
$pdo->execute(array(':username' => $_GET['username']));

// mysqli
$query = $mysqli->prepare('SELECT * FROM users WHERE username = ?');
$query->bind_param('s', $_GET['username']);
$query->execute();

ما توصیه می کنیم که همیشه از عبارات آماده در کنار() PDO::quote و () mysqli_real_escape_string استفاده کنید (کار از محکم کاری عیب نمی کنه :D )

کارآیی (Performance) :


هر دوی این کتابخونه ها سریع هستند و از این نظر مشکلی ندارید. MySQLi در استفاده معمولی (بدون عبارات تعیین شده) سریع تره (~2.5%) و در حالت استفاده با عبارات تعیین شده یه مقدار سرعتش کم تر می شه (~6.5%) اما کتابخونه ی خود MySQL از هر دوی اینها سریع تره اما خوب مشکلات خودش رو هم داره. اگر اصرار خیلی زیادی روی سرعت دارید و نمی تونید ازش بگذرید این گزینه ای هستش که باید بهش فکر کنید و تصمیم بگیرید.

نتیجه گیری:


در نهایت PDO در این مسابقه به راحتی پیروز می شه :D چرا؟ خوب یکیش به خاطر پشتیبانی از 12 نوع دیتابیس و پارامترهای نامگذاری شده، ما میتونیم به سادگی از سرعت کمترش چشم پوشی کنیم و از لحاظ امنیت هم هر دوی این کتابخونه ها به اندازه ی کافی امن هستن ضمن اینکه برنامه نویس ها هم معمولن راه های خودشون رو دارن برای حفظ امنیت بیشتر. برای همین به همتون توصیه می کنم که PDO می تونه یه جایگزین بسیار خوب باشه به جای سایر کتابخونه ها. درموردش فکر کنید. برای اطلاعات بیشتر هم می تونید به سایت رسمی php مراجعه کنید.
امیدوارم به دردتون خورده باشه و در تصمیم گیری کمکتون کرده باشیم.
موفق باشید
منبع : net.tutsplus.com

نظرات  (۳)

لزوما این که pdo از ۱۲ تا پایگاه داده مختلف پشتیبانی می‌کنه به این معنی نیست که هر query که باهاش نوشته بشه روی همه‌ی ۱۲ پایگاه داده هم کار می‌کنه. مثلا اگه توی query از یه تابع مثل ifnull استفاده شده باشه روی نسخه‌های قدیمی‌تر از ۵.۰ روی mysql کار نمی‌کنه. حتی ممکنه چیز‌های خیلی ساده‌تر هم مشکل ساز بشن مثل delimiter که توی mysql کاراکترش ` هست اما توی پایگاه داده‌های دیگه مثل postgresql کاراکترش " هست (که البته راه حل این مورد اجرا کردن mysql تو حالت ANSI mode هستش).
ببین کی اینجاست :)
خیلی مخلصیم بهروز جان
ممنون بابت توضیحات
بهره حلال بردیم.

ارسال نظر

ارسال نظر آزاد است، اما اگر قبلا در بیان ثبت نام کرده اید می توانید ابتدا وارد شوید.
شما میتوانید از این تگهای html استفاده کنید:
<b> یا <strong>، <em> یا <i>، <u>، <strike> یا <s>، <sup>، <sub>، <blockquote>، <code>، <pre>، <hr>، <br>، <p>، <a href="" title="">، <span style="">، <div align="">
تجدید کد امنیتی