سلام دوست وردپرسی من . احتمالا این پست رو با جستجوی کلیدواژه “PHP Warning: Missing argument 2 for wpdb::prepare” در اینترنت پیدا کردید !
خوب در اولین پست سال ۱۳۹۲ فتولیا (سال نوتون هم مبارک :)) می خواهیم این مشکل را ک در وردپرس نسخه ۳.۵ به بعد رخ داده است برطرف کنیم.البته این خطا باعث ازکار افتادن سایت نمی شود ولی باز لازم است یه سری بخش ها را مورد بازنگری قرار دهیم (در فتولیا هم همین مشکل رو داشتیم و قالب سایت به هم می ریخت ک با مسکن @ در php موقتا حل شده بود!) مخصوصا اینکه تصحیح این خطا یم تواند در افزایش امنیت سایت در حملات تزریق sql موثر باشد .
در ابتدا اگر صرفا یک کاربر وردپرس هستید ،برای عدم نمیاش این قبیل خطاها، باید نمایش خطاها در وردپرس را خاموش کنید . برای انجام این کار روش های مختلفی از قبیل php.ini,htaccess و … وجود دارد.دراینجا کافیست خط زیر را در داخل فایل wp-config.php قرار دهید (توجه داشته باشید عدم نمایش دادن خطاها در همه سایت هایی ک به مرحله بهره برداری عمومی رسیده اند خوب و لازم است)
@ini_set('display_errors', 0);
حالا برای حل مشکل کمی وارد جزئیات کار این تابع می شویم و نحوه به کار بردن صحیح اون رو مرور می کنیم .
کاربرد صحیح متد $wpdb->prepare()
به این صورت هست
$wpdb->prepare( "SELECT * FROM table WHERE ID = %d AND name = %s", $id, $name );
همانطور ک می دانید و در کد بالا می بینید از این متد برای اجرای کوئری برای کار با دیتابیس در وردپرس استفاده می شود . این متدی ک در بالا آمده است ۳ آرگومان قبول می کند ک همیشه تعداد آرگومان های بعدی را مقداری مشخص می کند ک به آرگومان اول پاس داده ایم . در آرگومان اول این کد دو علامت % داریم ک مشخص می کند باید ۲ آرگومان دیگر هم به متد پاس دهیم . حالا چرا این روش را استفاده می کنیم و مقدار را مستقیما به جای % ها قرار نمی دهیم ؟ جواب هم اینه: امنیت بیشتر . در این روش با مسقیما مقدار id و name رو در داخل کوئری قرار ندادیم بلکه نشانگری گذاشتیم (d%) ک مشخص می کنه مقداری ک می توان به ورودی id داد فقط داده ی عددی می تونه باشه و مقداری ک به ورودی دوم می شه داد صرفا از نوع رشته ای (s%) می تونه باشه.(دوستانی ک با زبان php آشنا هستند احتمالا با تابع sprintf آشنایی دارند ک از همین روش برای فیلتر کردن ورودی ها استفاده می کنه . اطلاعات بیشتر : http://php.net/manual/en/function.sprintf.php)
مشکل هم در همین جا نهفته است :
$wpdb->prepare( "SELECT * FROM table WHERE id = $id" );
می بینید ؟ این کوئری امن نیست و ممکنه اطلاعات دیتابیس شما رو با مشکل مواجه کنه .شاید فکر کنید ک چون کوئری را با متد $wpdb->prepare()
اجرا می کنید پس مشکلی نیست ولی چون $id
را مستقیما در کوئری قرار داده اید در واقع کاری از این متد برنمی آید . مشکل هم از اینجا به بعده . چون این متد نمی تونه یک آرگومان داشته باشه و حتما باید بیشتر از یکی را پاس بدیم وگرنه همون خطایی ک دنبال حلش هستین رو نشون می ده .
پس نمونه صحیح کد بالا رو به این شکل می شه نوشت:
$wpdb->prepare( "SELECT * FROM table WHERE id = %d", $id );
خوب با این روش می تونید مشکل خطای مذکور رو حل کنید . البته اگه خودتون تمایلی به این کار ندارید می تونید با توسعه دهنده دیگری یا همون کسی که پلاگین یا قالب رو نوشته تماس بگیرید و با دادن لینک این مطلب ازش بخواهید مشکل رو حل کنه .
توصیه : اگر با برنامه نویسی وب آشنایی ندارید توصیه می کنیم از روشی ک در سطر بالا گفته شد استفاده کنید و شخصا در کدها دستکاری نکنید . چون احتمال از کار افتادن سایت زیاد هست
منتظر نظرات و پیشنهاداتون هستیم
عالی بود مرسی مشکل حل شد