در وب سایت PHP: Hypertext Preprocessor (http://php.net/) هشدار جدیدی در مورد توابع mysql_* ( مانند mysql_connect , mysql_close , mysql_query و ... ) داده شده که واقعا نیازه اونو جدی بگیرید
تمام این توابع کنار گذاشته شده اند و در ورژن های بعدی حذف خواهند شد
و به زودی تمام اسکریپت هایی که از این توابع استفاده میکنند از کار خواهند افتاد !
پس این تایپک رو جدی بگیرید
متن هشدار خود سایت
This extension is deprecated as of PHP 5.5.0, and will be removed in the future. Instead, the MySQLi (http://www.php.net/manual/en/book.mysqli.php) or PDO_MySQL (http://www.php.net/manual/en/ref.pdo-mysql.php) extension should be used. See also MySQL: choosing an API (http://www.php.net/manual/en/mysqlinfo.api.choosing.php) guide and related FAQ (http://www.php.net/manual/en/faq.databases.php#faq.databases.mysql.deprecated) for more information.
همانطور که ذکر شده 2 راه جایگزین پیشنهاد شده
1-استفاده از mysqli
2-استفاده از pdo
خب در سایت های مختلف مقایسه هایی انجام شده که بنده از سایت Web development tutorials, from beginner to advanced | Nettuts+ (http://net.tutsplus.com/) یک مقایسه رو برای شما بیان میکنم
PDO
MySQLi
پشتیبانی از دیتابیس
12 نوع مختلف
تنها mysql
API
شی گرای
شی گرایی + توابع
پارامتر های اسمی
بله
خیر
در مورد تفاوت های دیگر با توابع قدیمی mysql در همین تایپک به بحث میپردازم
همچنین ابتدا اموزش PDO رو بیان خواهم کرد و سپس در صورت نیاز MySQLi
با این وجود اگر به هیچ کدام اشنایی نداریم پیشنهاد میکنم حتما از PDO استفاده کنید
تمام مطالب توسط خود بنده نوشته شد است با استفاده از 3 منبع که در پایان ذکر میکنم
کپی برداری از مطالب با ذکر لینک تایپک بلامانع است
cooper47
July 22nd, 2013, 02:00
اتصال به دیتابیس
PDO از 12 نوع مختلف دیتابیس پشتیبانی میکند به شرطی که درایور ان نصب باشد،
با این وجود چون قصد جایگزینی توابع mysql_* رو داریم، دیتابیس mysql رو بررسی خواهیم کرد
$db = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);
در هنگام ساخت شی PDO یک ارگومان متنی به آن میدهیم که در مثال بالا "mysql:host=$host;dbname=$dbname", $user, $pass می باشد
که host هست ما و متغیر های user pass یوزر و پسورد دیتابیس هستند
دقت کنید تمام توابع با متغیر $db در اموزش بیان میشود و اگر با یک نام دیگر این شی رو ایجاد کردید باید با اون نام توابع رو استفاده کنید
قطع اتصال دیتابیس
برای قطع اتصال تنها کافی هست شی را از بین ببرید و یا مقدار جدید به ان بدهید
unset($db);
$db = null
با یکی از دستورات بالا دیتابیس بسته خواهد شد.
cooper47
July 22nd, 2013, 02:31
تنظیمات خصوصیات دیتابیس
با استفاده از متد setAttribute میتوانید خصوصیات مورد نظر خود را تنظیم کنید،
این که روش خوبی هست که قبل از کار با دیتابیس خصوصیات رو تنظیم کنید
بعضی از این خصوصیات در لینک PHP: PDO::setAttribute - Manual (http://www.php.net/manual/en/pdo.setattribute.php) قابل مشاهده هست
در اینجا به چند خصوصیت مهم می پردازم
PDO::ATTR_ERRMODE
با این خصوصیت تعیین میکنید در هنگام مواجه با ارور در اجرای دستورات ، PDO چگونه برخورد کند
مقادیر این خصوصیت
PDO::ERRMODE_SILENT ( پیش فرض )
با این مقدار تنها اررور در متغیر pdo ذخیره میشود و هیچ عمل دیگری صورت نمیگیرد ( نحوه کار با اررور ذخیره شده رو در اینده توضیح خواهم داد)
PDO::ERRMODE_WARNING
با این مقدار pdo یک هشدار ایجاد میکند که بر حسب کانفیگ شما ، به کاربر نمایش داده میشود یا در فایل ذخیره میشود یا اصلا ذخیره نمیشود.
PDO::ERRMODE_EXCEPTION (پیشنهاد بنده )
با استفاده از این مقدار در صورت برخورد با اررور throw رخ میدهد
دقت کنید برای استفاده از این خصوصیت باید از try catch استفاده کنید
یک مثال برای ست کردن و PDO::ERRMODE_EXCEPTION
try {
$db = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass); //اتصال
$db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION ); //ست کردن نحوه نمایش ارور
$db->prepare('DELECT test FROM db'); // یک دستور که باعث ایجاد خطا میشود
}
catch(PDOException $e) {
echo "یک خطا رخ داده است : ".$e->getMessage()ک
}
PDO::ATTR_DEFAULT_FETCH_MODE
با استفاده از این خصوصیت نحوه fetch (خروجی یک ردیف ) را معین میکنید
مقدایر به صورت زیر است
PDO::FETCH_ASSOC
خروجی یک ارایه با اندیس های نام فیلد ها می باشد ( اگر دارای فیلد name باشد مقدار به صورت ['name'] قابل دسترسی هست )
PDO::FETCH_BOUND
یک نوع خاصی از خروجی هست که نیازمند درس های اینده هست، و تا اون موقع بدون توضیح رها میشود
PDO::FETCH_CLASSیک نوع خاصی از خروجی هست که نیازمند درس های اینده هست، و تا اون موقع بدون توضیح رها میشود
PDO::FETCH_NUM
خروجی یک ارایه با اندیس های شماره می باشد ( اگر اولین فیلد name باشد مقدار به صورت [0] قابل دسترسی هست )
PDO::FETCH_BOTH (پیشفرض)
تلفیقی از FETCH_ASSOC و FETCH_NUM
PDO::FETCH_OBJ (پیشنهاد بنده)
خروجی به صورت شی خواهد بود ( اگر در خروجی فیلد name باشد و متغیر $row باشد، مقدار فیلد با $row->name قابل دسترس خواهد بود )
PDO::ATTR_EMULATE_PREPARES
در مورد این در آینده صحبت میکتیم، با این وجود فعلا این مقدار را false قرار بدید(مهم)
اینو هم بنده اضافه کنم حتما باید extention PDO ئ همچنین mysqli روی سرور و php کامپایل گردد در غیر اینصورت از PDO و mysqli نمیتوانید روی سرور استفاده نمایید
روی پنل هایی مانند directadmin - kloxo بصورت default فعال می باشد اما روی پنل هایی مانند سی پنل - پلسک پیش فرض فعال نمی باشد
:53:
cooper47
July 22nd, 2013, 04:26
متد quote جایگزین تابع mysql_real_escape_string
با استفاده از این متد میتوانید در برابر حملات sql injection برنامه خود را محافظت کنید
دقت داشته باشید قبل از اجرای این کد باید charset را ست کنید
برای utf-8 کد زیر را به کار ببرید
$db->exec("SET NAMES utf8");
خوب 2 ارگومان تابع دارد
ارگومان اول متغیر ما هست
ارگومان دوم که اختیاری هست نوع متغیر رو بیان میکند برای مثال PDO::PARAM_STR یا PDO::PARAM_INT یا PDO::PARAM_NULL
به توصیه PHP هم دقت کنید
you are strongly recommended to use PDO::prepare() (http://www.php.net/manual/en/pdo.prepare.php) to prepare SQL statement
همانطور که ذکر کرده استفاده ازین تابع توصیه نمیشود و سرعت کمتری دارند، به جای اون استفاده از prepare پیشنهاد شده که در اینده اموزش داده خواهد شد
هشدار: این تابع برای تمام نوع متغیر ها quotes ( علامت ' ) را در 2 طرف متغیر قرار میدهد و نیاز به قرار دادن ان در کوئری نیست !
مثال :
$unsafe = "I'm Ali!"; //متغیر مورد نظر
$safe = $db->quote($unsafe); //مقدار خروجی : 'I''m Ali!'
اجرای کوئری Query با PDO
خوب قسمت اصلی دیتابیس مسلما اجرای دستورات هست
3 متد برای اینکار در PDO موجود هست که به توضیح 2 متد در اینجا اکتفا میکنم
1-متد exec
این متد دستورات شما رو اجرا میکند و تعداد ردیف تحت تاثیر را برمیگرداند ( برای UPDATE , DELETE و CREATE )
هشدار: این متد برای دستورات SELECT به هیچ وجه کاربرد ندارد
هشدار2: این تابع در صورت مواجه با خطا مقدار FALSE را برمیگرداند، برای مقایسه برای جلوگیری از اشتباه شدن مقدار FALSE با 0 باید از ==! استفاده کنید به مثال توجه کنید
در صورتی که مایل به اجرای دستورات SELECT هستید ( برای بقیه دستورات هم میتوانید از این متد استفاده کنید ) این متد کاربرد دارد
دقت کنید خروجی این متد یک شئ دیگر هست به نام PDOStatement (http://www.php.net/manual/en/class.pdostatement.php)
و برای پردازش اطلاعات باید اموزش این شی که در اینده مطرح خواهد شد را بخوانید
یک دستور ساده
$query = "SELECT * FROM `users`";
$result = $db->query($query);
//$result یک شئ از نوع دیگر است
print_r($result->fetchAll());
در مورد متد fetchAll بعدا صحبت خواهد شد فعلا بدانید این متد تمام ردیف ها را برمیگرداند و متد fetch یک ردیف را
3-متد prepare
کار با این متد همانند متد قبلی هست ولی تفاوت هایی دارند که بعدا ذکر خواهد شد
خروجی این متد یک شئ دیگر هست به نام PDOStatement (http://www.php.net/manual/en/class.pdostatement.php)
فعلا بدانید مثال بالا را با prepare میتوان به این شکل اجرا کرد
$query = "SELECT * FROM `users`";
$result = $db->prepare($query);
$result->execute(); // این خط اضافه شده است
print_r($result->fetchAll());
cooper47
July 22nd, 2013, 05:07
PDOStatement چیست ؟
بعد از اجرای متد های prepare و query خروجی انها به صورت PDOStatement هست،
PDOStatement در واقع شی ای برای پردازش اطلاعات می باشد و دارای متد های مختلفی هست
در اینجا متد های مهم و پر کاربرد ذکر خواهد شد
متغیر $result در اموزش ازین پس یک PDOStatement می باشد
متد setFetchMode
این متد همانند خصوصیت PDO::ATTR_DEFAULT_FETCH_MODE که در پست http://www.webhostingtalk.ir/f148/86678/#post819518 اموزش داده شد نحوه خروجی ردیف ها را تعیین می کند
دقت کنید تفاوت ان این است که تنها برای این شی کاربرد دارد
برای مثال اگر شما 2 PDOStatement دارید و در یکی این خصوصیت را تغییر دهید در دیگری تغییر نمیکند
مقدار پیشفرض ان مقداری است که به PDO::ATTR_DEFAULT_FETCH_MODE دادید
متد fetch
این متد یک ردیف را برمیگرداند ( خروجی بسته به fetchmode میتواند ارایه یا شی باشد )
دقت کنید در ورودی این متد هم میتوانید نحوه خروجی را جدا تنظیم کنید
برای مثال
$result->fetch(PDO::FETCH_OBJ)
متد fetchAll
این متد ارایه ای از تمام ردیف ها را بر میگرداند ( مقدار هر فیلد ارایه بسته به fetchmode میتواند ارایه یا شی باشد )
دقت کنید در ورودی این متد هم میتوانید نحوه خروجی را جدا تنظیم کنید
متد rowCount
این متد جایگزین متد mysql_num_rows و mysql_affected_rows می باشد
در صورتی که دستور INSERT , UPDATE , DELETE اجرا شده باشد تعداد ردیف های تحت تاثیر قرار گرفته را بر میگرداند
در غیر این صورت در بعضی از دیتابیس ها ( از جمله MySQL ) اگر دستور SELECT اجرا شده باشد تعداد ردیف های انتخابی را برمیگرداند
cooper47
July 22nd, 2013, 05:32
Prepared Statements( متد prepare )تا اینجا اکثر توضیحات جایگزینی برای توابع mysql بود و با توضیحات بالا تقریبا میتوانید توابع را جایگزین کنید
اما دست نگه دارید !
امکان جدیدی اضافه شده است !
Prepared Statements !
با استفاده از این امکان میتوانید سرعت را افزایش دهید ، امنیت کد های خود را بالا ببرید
یکی از کابرد های Prepared Statements این هست که شما میتوانید با استفاده از اون چندین دستور مشابه با ارسال تنها متغیر اجرا کنید،
فرض کنید میخواهید در دیتابیس 2 ردیف ذخیره کنید ، اگر به روش قبلی بخواهید اینکارو انجام بدید باید 2 بار کوئری مشابه بنویسید که تنها مقادیر فیلد ها عوض خواهد شد
اما با Prepared Statements میتوانید یک کوئری بنویسید و مقداری فیلد ها را جداگانه به دیتابیس ارسال کنید
در Prepared Statements شما به جای مقادیر یک مکان قرار میدهید
جایگزین میتواند با نام باشد یا بدون نام
مکان بدون نام
در این روش شما به جای مقدار تنها علامت سوال ( ؟ ) قرار میدهید
برای مثال
$query = "SELECT * FROM `users` WHERE username = ?";
$result = $db->prepare($query);
مکان با نام
در این روش شما به جای مقدار تنها نامی برای ان مکان انتخاب میکنید ( دقت کنید نام با : شروع می شود )
برای مثال
$query = "SELECT * FROM `users` WHERE username = :username"; // :username
$result = $db->prepare($query);
مقدار دهی به مکان با متد bindParam از PDOStatement
در هردو روش مکان دهی بعد از اجرای متد prepare خروجی همانطور که ذکر شد شی PDOStatement هست
این شئ متدی به نام bindParam دارد که با کمک ان میتوان مقدار مکان ها را مشخص کرد
قبلا ذکر شد مقدار این خصوصیت را false قرار دهید، اما این خصوصیت چیست
اکثر دیتابیس های جدید از prepare پشتیبانی میکنند ولی ورژن های قدیمی پشتیبانی نمیکنند، هنگامی که این مقدار true باشد pdo عملیات prepare را شبیه سازی میکند،
با این وجود توصیه میشود همیشه این مقدار را خاموش کنید ، چرا که pdo در ورژن جدید php قرار داده شده هست و مسلما هنگامی که ورژن php این هست ورژن دیتابیس هم پشتیبانی خواهد کرد
گرفتن اخرین ای دی ذخیره شده در دیتابیس
echo $db->lastInsertId();
اخرین ای دی را به شما بر میگرداند
تعداد ردیف های تحت تاثیر قرار گرفته
1-اگر از exec استفاده کردید
متد exec تعداد را بر میگرداند
2-اگر از prepare و query استفاده کردید