چرا تنظیمات افزونه شما ذخیره نمیشود؟ راهنمای تخصصی update_option
تابع update_option برای ذخیره تنظیمات در وردپرس؛ بررسی پارامترها، sanitize، autoload، بررسی مقدار بازگشتی و اشتباهات رایج در افزونهنویسی.
چرا ذخیره درست تنظیمات اهمیت دارد؟
هر افزونهای که با کاربر تعامل دارد، نیازمند ذخیره وضعیت است: تنظیمات فرم، وضعیت فعال بودن، کلیدهای احراز هویت و پیکربندی سرویسهای خارجی. اگر ذخیرهسازی بهدرستی انجام نشود، افزونه پس از هر بار بازنشانی صفحه، تنظیمات خود را از دست میدهد. تابعupdate_option نقطه اصلی ذخیرهسازی در وردپرس است. این تابع با ایجاد یا بهروزرسانی رکورد در جدول wp_options، امکان ذخیره پایدار تنظیمات را فراهم میکند.
تابع update_option چیست؟
تابعupdate_option() یک تابع هسته وردپرس است که در فایل wp-includes/option.php تعریف شده است. این تابع مقدار یک گزینه را در جدول wp_options ذخیره میکند یا در صورت وجود، مقدار قبلی را بهروزرسانی میکند.
رفتار دوگانه این تابع یکی از ویژگیهای مهم آن است: اگر گزینه وجود نداشته باشد، با تابع add_option ایجاد میشود؛ اگر وجود داشته باشد، با کوئری UPDATE تغییر میکند.
نکته مهم این است که این تابع در صورت موفقیت، مقدار true و در صورت عدم تغییر مقدار یا خطا، مقدار false برمیگرداند.
امضای تابع و پارامترها
امضای این تابع بهشکل زیر است:function update_option( $option, $value, $autoload = null ) {
// ...
}
پارامتر اول (option) نام گزینه است. باید رشتهای یکتا باشد و از prefix اختصاصی استفاده کند.
پارامتر دوم (value) مقداری است که ذخیره میشود. میتواند هر نوع داده سریالایزپذیر باشد.
پارامتر سوم (autoload) از وردپرس ۶.۶ به بعد امکان تنظیم صریح Autoload را فراهم میکند. مقادیر مجاز:
- true: گزینه در فهرست Autoload قرار میگیرد
- false: گزینه از Autoload خارج میشود
- null: رفتار پیشفرض بر پایه وضعیت موجود گزینه
سازوکار داخلی و مقدار بازگشتی
تابعupdate_option ابتدا مقدار فعلی گزینه را با get_option میخواند. اگر مقدار جدید با مقدار فعلی یکسان باشد، تابع مقدار false برمیگرداند و کوئری بهروزرسانی ارسال نمیکند. این رفتار که به Optimistic Update معروف است، از کوئریهای بیمورد جلوگیری میکند.
اگر مقدار تغییر کرده باشد، وردپرس کوئری UPDATE ارسال میکند و مقدار جدید را ذخیره میکند. اگر گزینه وجود نداشته باشد، از add_option استفاده میکند.
نکته مهم این است که مقدار false ممکن است به دو معنا باشد: عدم تغییر مقدار یا خطا در ذخیرهسازی. برای تفکیک این دو، باید مقدار قبلی گزینه را با get_option بررسی کنید.
Sanitize پیش از ذخیره
یکی از اصول پایه امنیتی، sanitize داده پیش از ذخیرهسازی است. اگر داده خام از ورودی کاربر را ذخیره کنید، ممکن است در زمان نمایش به XSS منجر شود. نمونه اشتباه:// اشتباه
$title = $_POST['title']; // داده خام
update_option( 'myplugin_title', $title );
نمونه صحیح:
// صحیح
$title = isset( $_POST['title'] )
? sanitize_text_field( wp_unslash( $_POST['title'] ) )
: '';
update_option( 'myplugin_title', $title );
نکته مهم: تابع wp_unslash پیش از sanitize فراخوانی میشود تا کاراکترهای escape شده توسط PHP، به حالت اصلی بازگردند. راهنمای توابع escape در صفحه esc_html آمده است.
توابع sanitize پرکاربرد:
- sanitize_text_field: برای متن ساده
- sanitize_textarea_field: برای متن چندخطی
- sanitize_email: برای ایمیل
- sanitize_url یا esc_url_raw: برای URL
- absint: برای عدد صحیح نامنفی
- wp_kses_post: برای HTML محدود
- sanitize_key: برای شناسهها
- sanitize_title: برای نامک
نقش autoload در کارایی
انتخاب مقدار Autoload، اثر مستقیمی بر کارایی سایت دارد. اگر گزینهای در Autoload باشد، در هر بار بارگذاری صفحه از پایگاه داده خوانده و در حافظه کش میشود. اگر تعداد گزینههای Autoload بسیار زیاد باشد، مصرف حافظه و زمان بارگذاری افزایش مییابد. قاعده انتخاب Autoload: - گزینههای کوچک و پرکاربرد:true
- گزینههای بزرگ: false
- گزینههای بهندرت استفادهشده: false
- دادههای موقت: بهجای گزینه از Transient استفاده کنید
نمونه ذخیره با Autoload مشخص:
update_option( 'myplugin_api_key', $api_key, false );
update_option( 'myplugin_enabled', $enabled, true );
نکته مهم: پیش از وردپرس ۶.۶، مقدار Autoload تنها در زمان ایجاد گزینه قابل تنظیم بود و در بهروزرسانیهای بعدی تغییر نمیکرد. از وردپرس ۶.۶ به بعد، این مقدار در هر بهروزرسانی قابل تغییر است.
کاربردهای عملی در افزونه
ذخیره تنظیمات با پاکسازی داده:function myplugin_save_settings( $input ) {
$sanitized = array(
'enabled' => ! empty( $input['enabled'] ),
'api_key' => isset( $input['api_key'] )
? sanitize_text_field( wp_unslash( $input['api_key'] ) )
: '',
'cache_duration' => isset( $input['cache_duration'] )
? absint( $input['cache_duration'] )
: 3600,
'debug_mode' => ! empty( $input['debug_mode'] ),
);
$result = update_option( 'myplugin_settings', $sanitized, false );
return $result;
}
ذخیره فقط در صورت تغییر:
function myplugin_update_flag( $flag_name, $value ) {
$option_name = 'myplugin_flag_' . sanitize_key( $flag_name );
$current = get_option( $option_name, null );
if ( $current === $value ) {
return true;
}
return update_option( $option_name, $value, false );
}
نکته مهم: این الگو از کوئریهای بیمورد جلوگیری میکند. اگر مقدار تغییر نکرده باشد، تابع update_option بهتنهایی هم کوئری ارسال نمیکند، اما بررسی صریح این امکان را میدهد که منطق دیگری نیز اضافه کنید.
ذخیره وضعیت از طریق AJAX:
add_action( 'wp_ajax_myplugin_save_state', 'myplugin_save_state_handler' );
function myplugin_save_state_handler() {
check_ajax_referer( 'myplugin_state_nonce', 'nonce' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( array( 'message' => 'دسترسی غیرمجاز' ), 403 );
}
$state = isset( $_POST['state'] )
? sanitize_key( wp_unslash( $_POST['state'] ) )
: '';
if ( ! in_array( $state, array( 'active', 'paused' ), true ) ) {
wp_send_json_error( array( 'message' => 'وضعیت نامعتبر' ), 400 );
}
update_option( 'myplugin_state', $state, false );
wp_send_json_success( array( 'state' => $state ) );
}
راهنمای توابع استفادهشده در این بخش: check_ajax_referer، current_user_can، wp_send_json_success و wp_send_json_error.
هوکهای مرتبط با ذخیرهسازی
وردپرس دو هوک کلیدی برای رهگیری ذخیرهسازی گزینهها فراهم میکند: -add_option_{$option}: هنگام ایجاد گزینه جدید
- update_option_{$option}: هنگام بهروزرسانی گزینه موجود
نمونه استفاده:
add_action( 'update_option_myplugin_settings', 'myplugin_settings_updated', 10, 3 );
function myplugin_settings_updated( $old_value, $value, $option ) {
if ( $old_value === $value ) {
return;
}
if ( function_exists( 'myplugin_flush_all_transients' ) ) {
myplugin_flush_all_transients();
}
}
نکته مهم: این هوک امکان پاکسازی کش مرتبط را فراهم میکند. راهنمای توابع حذف کش در صفحه delete_transient آمده است.
نکات امنیتی و اشتباهات رایج
اشتباه اول، نبود sanitize است. اگر داده خام ذخیره شود، ممکن است در زمان نمایش به XSS منجر شود. اشتباه دوم، نبود Autoload مناسب است. گزینههای بزرگ Autoload، سرعت سایت را کاهش میدهند. اشتباه سوم، نبود بررسی مقدار بازگشتی است. اگرfalse برگردانده شود، ممکن است به معنای عدم تغییر یا خطا باشد.
اشتباه چهارم، نبود بررسی current_user_can است. اگر ذخیرهسازی از طریق فرم انجام شود، باید بررسی شود که کاربر مجاز است.
اشتباه پنجم، نبود بررسی nonce است. هر ذخیرهسازی از فرم باید nonce داشته باشد. راهنمای این تابع در صفحه wp_verify_nonce آمده است.
اشتباه ششم، ذخیره داده حساس در گزینههای Autoload است. این دادهها در هر بار بارگذاری صفحه خوانده میشوند و ممکن است در خطاهای سرور ظاهر شوند.
اشتباه هفتم، نبود تست است. باید سناریوهای ذخیره موفق، ذخیره ناموفق، عدم تغییر و نوع داده اشتباه را بررسی کنید.
تحلیل فنی پیشرفته
در نگاه مهندسی، تابعupdate_option() یک نقطه معماری در لایه Data Persistence است که بر چند جنبه از سیستم اثر میگذارد. لایه اول لایه Storage Abstraction است. این تابع لایهای از انتزاع روی جدول wp_options ایجاد میکند و رفتار درج یا بهروزرسانی را بر پایه وضعیت موجود تصمیم میگیرد.
لایه دوم لایه Optimistic Update است. اگر مقدار جدید با مقدار قبلی یکسان باشد، کوئری ارسال نمیشود. این رفتار از بار بیمورد روی پایگاه داده جلوگیری میکند.
لایه سوم لایه Serialization است. وردپرس داده را با maybe_serialize ذخیره میکند. اگر داده شامل Closure یا Resource باشد، سریالایز با شکست مواجه میشود.
لایه چهارم لایه Autoload Management است. از وردپرس ۶.۶ به بعد، Autoload در هر بهروزرسانی قابل تنظیم است.
لایه پنجم لایه Hook-based Observability است. هوکهای add_option_{$option} و update_option_{$option} امکان رهگیری تغییرات را فراهم میکنند.
لایه ششم لایه Caching است. تابع update_option مقدار جدید را در Object Cache نیز بهروزرسانی میکند تا بازخوانیهای بعدی سریع باشند.
لایه هفتم لایه Security است. داده ذخیرهشده باید sanitize شود و از ذخیره داده حساس خودداری شود.
لایه هشتم لایه Multisite است. در شبکههای Multisite، گزینهها در هر سایت مستقل ذخیره میشوند. توابع مخصوص شبکه مانند update_site_option برای گزینههای سطح شبکه استفاده میشوند.
لایه نهم لایه Testing است. تستهای واحد باید همه سناریوها را پوشش دهند.
مفاهیم پایهای Persistence در Persistence در ویکیپدیا توضیح داده شده است.
برای مطالعه بیشتر روی توابع مرتبط، میتوانید به راهنمای get_option، راهنمای delete_option، راهنمای set_transient، راهنمای get_transient، راهنمای delete_transient، راهنمای register_setting و راهنمای add_settings_field مراجعه کنید.
پرسشهای پرتکرار
تفاوتupdate_option و add_option چیست؟ اولی درج یا بهروزرسانی انجام میدهد؛ دومی تنها درج میکند.
اگر مقدار جدید با مقدار قبلی یکسان باشد، کوئری ارسال میشود؟ خیر، تابع مقدار false برمیگرداند.
آیا میتوان Autoload را در بهروزرسانی تغییر داد؟ از وردپرس ۶.۶ به بعد، بله.
آیا این تابع داده را sanitize میکند؟ خیر، sanitize به عهده توسعهدهنده است.
آیا این تابع در Multisite بین سایتها مشترک است؟ خیر، هر سایت مستقل است.
ادامه مسیر
تابعupdate_option() ابزار پایه وردپرس برای ذخیره و بهروزرسانی تنظیمات است. استفاده درست از آن یعنی sanitize داده پیش از ذخیره، انتخاب Autoload مناسب، بررسی مقدار بازگشتی و تست در سناریوهای مختلف. اشتباههای کوچک در این تابع اغلب به رفتار غیرمنتظره یا حفرههای امنیتی منجر میشوند.
اگر این تابع را در پروژهای واقعی به کار بردهاید و رفتار غیرمنتظرهای دیدهاید — بهخصوص در ترکیب با Object Cache یا در Multisite — تجربهتان میتواند راهگشای دیگران باشد. کدام بخش بیشترین زمان را از شما گرفت؟ دیدگاه خود را بنویسید.