آموزش PDO در php

برای اتصال به دیتابیس در PHP روش های متفاوتی وجود داره که میتوان از دستورات mysql , mysqli و PDO نام برد. دستورات mysql در نسخه های آینده کنار گذاشته خواهند شد! ورژن ارتقاع یافته ی mysql با نام mysqli وجود دارد که میتونید ازش استفاده کنید 😀 اما باید بگم که دستورات PDO برای اتصال و کار با دیتابیس از همه بهتر است, چرا؟ یکی از دلایلش میتونه سرعت بالاتر باشه , دلیل دیگه میتونه در این باشه که PDO میتونه به راحتی به ۱۲ نوع دیتابیس مختلف متصل بشه (مثلا دیتابیس هایی از نوع mysql , sqlserver , oracle , sqlite و …).

در ابتدا لازم به ذکره که بگم برای کار با دستورات PDO شما باید کمی با اصول شی گرایی در php اشنا باشید.

من در اینجا دستورات PDO رو در چندین قسمت زیر توضیح میدم :

  1. نحوه اتصال به دیتابیس mysql با PDO
  2. نحوه ی اجرای دستورات مورد نظرمون
  3. ایجاد دستورات اماده (prepare)

قسمت اول : نحوه اتصال به دیتابیس MySQL با استفاده از PDO

برای اتصال به پایگاه داده میتونیم به شیوه ی زیر عمل کنیم , به دستورات زیر دقت کنید:

در دستورات بالا یک شی از نوع PDO (دقت کنید حروف بزرگ است) میسازیم , شی PDO سه تا مقدار ورودی میگیره. مقدار اول هاست و نام دیتابیس ما رو مشخص میکنه , دو مقدار بعدی به ترتیب یوزرنیم و پسوورد مورد نیاز برای اتصال به دیتابیس رو مشخص میکنه.

دوستان عزیز دقت کنید که دستور اتصال به پایگاه داده ی PDO رو درون try catch قرار میدیم تا اگه هنگام اتصال خطا ایجاد شد بتونیم خطا رو مدیریت کنیم.

در اگه خطایی رخ بده اون خطا به قسمت catch ارسال میشه و ما اون خطا رو درون یه متغیر از نوع PDOException (استثنا از نوع PDO) دریافت میکنیم , متن خطا رو میشه با متد getMessage دریافت کرد 😀 به همین راحتی. البته متد errorInfo هم وجود داره که اطلاعات ارور رو به صورت ارایه ای به ما میده.

خب الان با موفقیت به دیتابیس متصل شدیم 😀 حالا میریم ببینیم چجوری میتونیم دستوراتمون رو اجرا کنیم یو هاهاهاها هخخخخ

قسمت دوم : نحوه ی اجرای دستورات SQL مورد نظر در PDO

برای اجرای دستورات مورد نظرمون توسط PDO میشه روش های مختلفی رو در نظر گرفت. این روش ها از متدهای متفاوتی استفاده میکنند که به صورت زیر هستند:

  • متد exec : این متد یک مقدار ورودی از نوع دستورات SQL میگیره و اجرا میکنه , بعد از اجرا کردن دستور , تعداد رکورد هایی که مورد تاثیر قرار گرفته اند را به شما میدهد , دقت کنید که وقتی از این دستور استفاده میکنید نمیتونید داده هایی را از پایگاه داده دریافت کنید. یعنی اگه سعی کنید با دستور select داده هایی را انتخاب کنید عمل انتخاب کردن انجام می شود اما نمیشه با دستوراتی که در PDO وجود داره این داده ها رو دریافت کرد. پس این دستور فقط برای اجرای دستوراتی که با اون نمیخوایم داده هایی رو از دیتابیس دریافت کنیم خوبه.
  • متد query : این متد یه مقدار ورودی از نوع SQL میگیره و اجرا میکنه , دقت کنید که این تابع هر دستوری که بهش بدید رو اجرا میکنه و مشکلات امنیتی دستورات رو باید خودتون حل کنید (مثلا مشکلات مربوط به injection)
  • متد execute : این دستور همانند دستور query هست اما با این تفاوت که این دستور این قابلیت رو به ما میده تا بتونیم دستوراتی رو ابتدا آماده (prepare) کنیم و بعدش با این دستور اجرا کنیم و این باعث میشه که مشکلات امنیتی حل بشه 😀

خب 😀 پس ما برای اجرای دستورات SQL میتونیم از متدهای بالا استفاده کنیم. در ادامه نحوه ی کار با هرکدوم رو بهتون میگم. با من همراه باشید.

نحوه ی استفاده از متد exec به صورت زیر است :

در دستور بالا نوع داده هایی که میخوایم با اونها کار کنیم رو توسط متد exec روی utf8 قرار دادیم , در اینجا چون نمیخوایم داده هایی رو از دیتابیس دریافت کنیم بهترین کار اینه که از دستور exec استفاده کنیم.

نحوه ی استفاده از دستور query به صورت زیر هست :

در دستورات بالا با استفاده از دستور query یک دستور SQL رو اجرا کردیم و سپس داده هایی که از دیتابیس انتخاب کردیم رو با متد fetchAll دریافت میکنیم 😀 دوستان عزیزم تابع FetchAll رکورد هایی که از ارایه دریافت شدن رو به صورت ارایه به ما تحویل میده. من این رکورد ها رو با دستور fetchAll (به بزرگ و کوچک بودن حروف دقت کنید چون مهمه) درون متغیر data قرار دادم و سپس با دستور print_r توی صفحه نمایش دادم. (دستور print_r محتویات ارایه رو نمایش میده.)

متد execute هم مثل متد query مورد استفاده قرار میگیره به مثال زیر دقت کنید (همون مثال بالا رو با دستور execute انجام میدم)

خب بریم سراغ دستورات اماده (prepare): ما برای جلوگیری از حملات injection دستورات SQL خودمون رو ابتدا آماده میکنیم و سپس اون رو اجرا میکنیم.

برای اماده کردن یک دستور SQL از متد prepare استفاده میکنیم , به مثال زیر دقت کنید:

در دستورات بالا ابتدا یک دستور SQL رو اماده کردیم و بعدش اون رو با استفاده از تابع Execute با مقادیر ورودی مورد نظر خودمون اجرا میکنیم. مقادیر ورودی به عنوان مقدار های متنی محسوب میشن و توی دستورات ما اجرا نمیشن و این باعث میشه که دستورات SQL ما مورد حمله قرار نگیرن. توی دستورات SQL قسمت هایی که با علامت  ? یا علامت سوال نوشتم به معنی این هستند که بعدا مقدار هایی رو به تابع execute میدیم تا دستور SQL ما رو کامل کنه و اجرا کنه.

دوستان عزیز امیدوارم که در برنامه نویسی خودتون از PDO برای اتصال PHP با پایگاه داده استفاده کنید 😀 این بهترین روش است شک نکنید. کسانی که سوال دارند میتونن از بخش نظرات بپرسند تا پاسخ بدم.

موفق باشییییییید.

به اشتراک بگذارید:Email this to someoneShare on FacebookTweet about this on TwitterShare on Google+Digg thisShare on LinkedInPin on PinterestShare on StumbleUponFlattr the authorShare on RedditBuffer this pageShare on TumblrPrint this pageShare on YummlyShare on VK
  1. حمیدرضا

    سایت فوق العاده ای دارین. امیدوارم جای این سایتای در پیت رو بگیرین که همش پاپ آپ و تبلیغات میزارن.

    • مرسییییییییییی. اونا هدفشون تبلیغاته بقلش یه اموزشم میزارن 😀 ولی ما هدفمون اموزش است و بس.

  2. علی طبا

    سلام
    شدیدا به یک سری مقاله درمورد از بین بردن امکان نفوذ (هک) در php به شیوه های مختلف دارم. میشه راهنمایی کنید.
    ممنون

    • سلام دوست عزیز. مقاله نیاز دارید یا آموزش؟ میخوام بدونم که این مقاله رو قراره جایی ارائه بدید به عنوان واحد درسی و یا مقاله رسمی , یا اینکه فقط برای اطلاعات شخصی خودتون میخواید؟

  3. علی طبا

    سلام
    بصورت یک راهنما برای کارهای خودم و شاید خیلی ها. آموزشی و غیر رسمی.
    ممنون

    • چشم. اموزش هایی در مورد نکات امنیتی برنامه نویسی وب و PHP قرار خواهیم داد. منتظر اموزش های ما در مورد نکات امنیتی باشید 😀

  4. علی طبا

    سلام
    مشکل جایگزین شدن ” با \" در کد زیر را چطور میشه حل کرد؟
    محتوای prddesc$ کد html هست که از ادیتور آنلاین میاد و طبیعتا (“) را داره.

    ممنون

    $stmt= $dbh->prepare(“UPDATE tbl_products SET prdtitle=:prdtitle, prddesc=:prddesc, prdtag=:prdtag WHERE id=:id”);

    $stmt->execute(array(‘:prdtitle’=>$prdtitle, ‘:prddesc’=>$prddesc, ‘:prdtag’=>$prdtag, ‘:id’=>$id));

    • محتوا رو میتونید با استفاده از تابع htmlspecialchars_decode دیکد کنید مثلا به صورت زیر:
      echo htmlspecialchars_decode(“$stmt= $dbh-&gt”);
      من یه تیکه از متن شما رو دیکد کردم و توی صفحه echo کردم. اگه دقت کنید به درستی نمایش داده میشه! همچنین از تابع html_entity_decode نیز میتونید استفاده کنید.
      تفاوت این دو تابع در بازه ی کاراکترهایی هست که به حالت عادی تبدیل میکنند. تابع html_entity_decode همه ی کاراکتر ها رو دیکد میکنه ولی اون یکی تابع فقط کاراکتر های از نوع html رو دیکد میکنه! موفق باشید.

  5. علی طبا

    سلام
    این دستور درست باید قبل از prepare بیاد ؟ یا در قسمت تعریف متغیرها؟ یا در execute؟
    ضمنا خود این کد escape و راست به چپ شده بنظر درست نمیاد!

    ممنون

    • شما با استفاده از این دستور محتویات textarea رو به حالت نرمال تبدیل میکنید! این دستور باید قبل از استفاده کردن متغیر ها بیاد. اگه متوجه نشدید توی فروم بگید تا یه کد به عنوان مثال براتون بزارم.

  6. سلام خسته نباشید.من وقتی میخوام داده های یه جدول رو از دیتابیس فتچ کنم این ارور رو میده
    Not Found

    The requested URL /e-shop/test.php was not found on this server.

    Apache/2.4.9 (Win64) PHP/5.5.12 Server at localhost Port 80
    واسه چیه این ارور؟ ممنون

    • سلام , شما با js به صورت Ajax وقتی درخواست میفرستید این خطا رو میده؟ ادرس مستقیم فایل رو توی مرورگر بزنید امکانش هست که درخواست ajax رو به یه صفحه ای که وجود نداره ارسال میکنید.

  7. ببخشید یه سوال دیگه هم داشتم که هرکاری میکنم مشکل برطرف نمیشه
    من یه سبد خرید طراحی کردم که وقتی روی یه محصول کلیک میکنی یه کوکی تولید میشه و همچنین آی دی اون محصول هم دریافت میشه.بعد میخوام این اطلاعات توو دیتابیس توو یه تیبل تحت عنوان تیبل سبد ذخیره بشه.اما وقنی کلیک میکنم نه کوکی ثبت میشه نه آی دی محصول.کد ها هم این هستنش که توو کامنت بعدی مینویسم که بهم ریختگی نداشته باشه

    • سلام دوست عزیز من کدهای شما رو دیدم قسمت مربوط به اجرا کردن دستورات sql مشکل داره. برای prepare کردن متغیر داخل کوئری Sql قرار نمیدیم بلکه از علامت جا نگهدار استفاده میکنیم و بعد اون رو prepare میکنیم. در اخر نیز bind میکنیم. اینجا رو مطالفعه کنید

  8. من دقیقا کد های شمارو زدم بازم نشد.نمیدونم مشکل چیه.اگه لطف کنید خودتون یه بار کد رو واسم بنویسید و من کپی کنم ممنون میشم.واقعا گیر کردم

  9. سلام
    خدا خیرت بده دستتون درد نکنه
    خیلی کامل و شسته و رفته

    • فدا مدا 😀 به سایت آموزشی ما هم با ادرس youlearn.ir سربزنید! البته تازه تاسیس هست هنوز کار داره تا راه بیوفته ولی محتوا داریم توش میزاریم به زودی پر از مطالب آموزشی خواهد بود.

  10. میشه این کد اتصال رو برام به pdo تبدیل کنید؟

    // ###################### اتصال #######################
    function connect()
    {
    if(0 == $this->conn)
    {
    if($this->password==””)
    {
    $this->conn = mysql_connect ($this->server,$this->user);
    }
    else
    {
    $this->conn = mysql_connect($this->server,$this->user,$this->password);
    }

    $sqlversion = @mysql_get_server_info();
    if(empty($sqlversion)){$sqlversion=’5.0′;}

    if($sqlversion >= ‘4.1’){
    mysql_query(“set names ‘utf8′”);

    }

    if($sqlversion >= ‘5.0’) {
    mysql_query(“SET sql_mode=””);
    }

    if(!$this->conn)
    {
    $this->error(“Connection == false, connect failed”);
    }

    if($this->database != “”)
    {
    if(!mysql_select_db($this->database, $this->conn))
    {
    $this->error(“cannot use database “.$this->database);
    }
    }
    }
    }

    • سلام دوست عزیز. اموزش ها رو بخونید متوجه میشید! دقیقا تمامی خطوط کدهایی که نوشتید رو توی مثال های اموزش گذاشتم! اگه بازم مشکلتون حل نشد بگید کد رو براتون از طریق ایمیل ارسال میکنم. موفق باشید.

  11. والا شاید باور نکنید روش وقت گذاشتم ولی نشد که نشد واسه همین اینجا مشکلم رو مطرح کردم شرمنده
    اگه امکانش هست همینجا برام بنویسید بهتره شاید یکی مثل من به دردش خورد یه روزی

  12. با سلام .
    ممنون از سایت خوبتان . یک سوال داشتم . دلیل اینکه از علامت سوال در این کد استفاده کردید چیه ؟
    $prepared=$connection->prepare(‘select * from users_table where username=? and password=?’);
    چرا به جای علامت سوال از همون اول مستقیما متغیر رو نگذاشتید ؟
    ممنون

    • متغیرها حاوی اطلاعاتی هستند که ما از input ها دریافت کردیم و این اطلاعات توسط کاربران به ما داده میشن! حالا اگه ما مستقیم از متغیرها استفاده کنیم کاربران میتونن دستورات sql برای ما ارسال کنن و با اجرا شدن این دستورات پایگاه داده ی ما تخریب بشه که بهش میگن sql injection , برای جلوگیری از این کار از روشی که توضیح داده شد استفاده میکنیم.
      موفق باشید. 😀

  13. ببخشید . یک سوال دیگه هم داشتم .
    فقط برای select کردن باید از دستور prepare استفاده کنیم ؟ مثلا برای insert یا delete لازم نیست از تابع prepare استفاده کنیم ؟
    ممنون

    • هرجا که میخواید از متغیرها استفاده کنید میتونید علامت ؟ رو به عنوان جا نگهدار قرار بدید و بعدا اطلاعات رو بهش bind کنید. شما میتونید در همه ی دستورات Sql ازش استفاده کنید و مختص دستور خاصی نیست.

  14. سلام عرض می کنم خدمت مدیر طرح چه
    خسته نباشید عزیز یه سوالی برام پیش اومد نمی دونم چطوری حلش کنم
    یه کدی نوشتم با استفاده از pdo کارش اینه که می خواد یک رکورد به جدولم اضافه کنه ولی id رو اتوماتیک اضافه نمی کنه خالی گذاشتم مقدارش رو ولی باز هم عمل نکرد
    $bind=array(”,’saeed’,’123456′,’saeed@yahoo.com’,’41526′);
    دقیقا هم کد خودتون رو کپی کردم و تغییرات دادم ولی نمی دونم چرا اجرا نمیشه
    ممنون میشم راهنمایی کنید

    • سلام دوست گرامی. ارور یا خطا نمیده؟ شاید توی دستورات خودتون اشتباه کردید. قسمت id رو اگه auto increment است اصلا توی دستورات Sql خودتون نزاریدش. کد Sql رو برام ایمیل کنید بررسی کنم براتون.
      ایمیل بنده : khanzadimahdi@gmail.com
      یا اینکه از طریق تلگرام برام بفرستید : ۰۹۳۷۳۶۲۰۵۳
      موفق باشید.

  15. امید

    با سلام و خسته نباشی خدمت شما و تشکر از آموزش های خوبتون واقعا مفید و کار آمد هستن .میخواستم ازتون بخوام اگر میشه یک سورس کد insert هم بنویسید البته به همین روش PDO چون من تازه کار هستم و به اینجور آموزش ها نیاز دارم .ممنون از سایت خوبتون

  16. امید

    سلام به شما .ببخشید من این کدهای که شما در بالای همین صفحه نوشتید رو در ای دی ای نوشتم و ذخیره کردم و بعد از چاپ در مرورگر ارور میده و ارورش هم فتال اروره و میگه که فانکشین getmessage آندیفاین یا تعریف نشده است

    • سلام کدها رو توی چه namespace نوشتید؟ اگه از namespace به غیر از global استفاده میکنید باید در اولین خط از صفحه دستور use \PDO رو بنویسید.

می‌خواهید دیدگاهتان را بیان کنید؟