تابع delete_option ابزار پایه وردپرس برای حذف گزینه‌ها از جدول wp_options است. این تابع در پاک‌سازی داده‌های موقت، حذف تنظیمات افزونه در زمان غیرفعال‌سازی و رعایت اصول پاک‌سازی داده نقشی کلیدی دارد. تشخیص درست میان حذف موفق و حذف ناموفق، پایه پیاده‌سازی حرفه‌ای چرخه عمر داده است. اشتباهات رایجی مانند نبود بررسی capability، نبود nonce، نبود بررسی مقدار بازگشتی و نبود تست می‌تواند به باقی ماندن داده‌های ناخواسته یا حذف ناخواسته منجر شود. تسلط بر این تابع برای افزونه‌نویسی حرفه‌ای ضروری است و در پروژه‌های سفارشی کاربرد گسترده دارد.

چرا حذف درست داده اهمیت دارد؟

هر افزونه‌ای که فعال می‌شود، داده‌هایی در پایگاه داده ذخیره می‌کند. اگر افزونه غیرفعال یا حذف شود و این داده‌ها پاک نشوند، جدول wp_options به‌تدریج متورم می‌شود و کارایی سایت کاهش می‌یابد. این پدیده که به Database Bloat معروف است، در پروژه‌های بزرگ به یک معضل جدی تبدیل می‌شود. تابع delete_option ابزار اصلی وردپرس برای پاک‌سازی کنترل‌شده گزینه‌ها است. استفاده درست از آن، به پاکیزگی پایگاه داده و رعایت اصول چرخه عمر داده کمک می‌کند.

تابع delete_option چیست؟

تابع delete_option() یک تابع هسته وردپرس است که در فایل wp-includes/option.php تعریف شده است. این تابع یک گزینه مشخص را از جدول wp_options و همچنین از Object Cache حذف می‌کند. برخلاف update_option که در صورت نبود گزینه، آن را ایجاد می‌کند، delete_option تنها حذف انجام می‌دهد. اگر گزینه وجود نداشته باشد، تابع مقدار false برمی‌گرداند و هیچ خطایی رخ نمی‌دهد. نکته مهم این است که این تابع به‌تنهایی ایمن است و می‌توان آن را بدون نگرانی از خطا فراخوانی کرد. اما در سناریوهایی که از فرم کاربر فراخوانی می‌شود، بررسی capability و nonce ضروری است.

امضای تابع و پارامترها

امضای این تابع به‌شکل زیر است:
function delete_option( $option ) {
    global $wpdb;

    if ( ! isset( $option ) ) {
        return false;
    }

    $option = trim( $option );
    if ( empty( $option ) ) {
        return false;
    }

    do_action( 'delete_option', $option );

    $row = $wpdb->get_row( $wpdb->prepare(
        "SELECT option_name, option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1",
        $option
    ) );

    if ( ! is_object( $row ) ) {
        return false;
    }

    $value = $row->option_value;

    do_action( "delete_option_{$option}", $option, $value );

    if ( ! wp_installing() ) {
        wp_cache_delete( $option, 'options' );
        wp_cache_delete( 'alloptions', 'options' );
    }

    $result = $wpdb->query( $wpdb->prepare(
        "DELETE FROM $wpdb->options WHERE option_name = %s",
        $option
    ) );

    return $result;
}
پارامتر ورودی (option) نام گزینه است. باید رشته‌ای یکتا باشد و دقیقاً با نامی که در add_option یا update_option استفاده شده مطابقت داشته باشد. خروجی یک مقدار بولی است: true در صورت موفقیت و false در صورت نبود گزینه یا خطا.

سازوکار داخلی و مقدار بازگشتی

تابع delete_option ابتدا نام گزینه را trim می‌کند و بررسی می‌کند که خالی نباشد. سپس دو هوک فراخوانی می‌کند: یکی عمومی delete_option و یکی اختصاصی delete_option_{$option}. سپس مقدار فعلی گزینه را از پایگاه داده می‌خواند. اگر گزینه وجود نداشته باشد، مقدار false برمی‌گرداند. اگر وجود داشته باشد، مقدار را ذخیره می‌کند و کوئری DELETE ارسال می‌کند. در نهایت، مقدار گزینه از Object Cache نیز حذف می‌شود تا بازخوانی‌های بعدی داده قدیمی را نبینند. نکته مهم: مقدار بازگشتی false ممکن است به دو معنا باشد: نبود گزینه یا خطای کوئری. برای تفکیک این دو، بررسی کنید که آیا گزینه پیش از حذف وجود داشته است یا نه.

چرخه عمر داده افزونه

یکی از اصول حرفه‌ای در توسعه افزونه، رعایت چرخه عمر داده است. داده‌های افزونه باید در سه نقطه مدیریت شوند: **فعال‌سازی**: در زمان فعال‌سازی، مقادیر پیش‌فرض ایجاد می‌شوند. استفاده از هوک register_activation_hook برای این کار توصیه می‌شود.
register_activation_hook( __FILE__, 'myplugin_activate' );
function myplugin_activate() {
    if ( false === get_option( 'myplugin_settings' ) ) {
        add_option( 'myplugin_settings', myplugin_get_default_settings(), '', false );
    }
}
**غیرفعال‌سازی**: در زمان غیرفعال‌سازی، می‌توان داده‌های موقت را پاک کرد اما داده‌های کاربر را نگه داشت. استفاده از هوک register_deactivation_hook برای این کار توصیه می‌شود.
register_deactivation_hook( __FILE__, 'myplugin_deactivate' );
function myplugin_deactivate() {
    delete_transient( 'myplugin_cache' );
    delete_transient( 'myplugin_stats' );
}
**حذف (Uninstall)**: در زمان حذف کامل افزونه، می‌توان همه داده‌ها را پاک کرد. استفاده از فایل uninstall.php برای این کار توصیه می‌شود.
// uninstall.php
if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
    exit;
}

$options = array(
    'myplugin_settings',
    'myplugin_api_key',
    'myplugin_enabled',
    'myplugin_state',
);

foreach ( $options as $option ) {
    delete_option( $option );
}
نکته مهم: راهنمای توابع مرتبط در صفحه register_activation_hook و صفحه register_deactivation_hook آمده است.

کاربردهای عملی در افزونه

حذف گزینه با بررسی دسترسی و nonce:
add_action( 'wp_ajax_myplugin_reset_settings', 'myplugin_reset_settings_handler' );
function myplugin_reset_settings_handler() {
    check_ajax_referer( 'myplugin_reset_nonce', 'nonce' );

    if ( ! current_user_can( 'manage_options' ) ) {
        wp_send_json_error( array( 'message' => 'دسترسی غیرمجاز' ), 403 );
    }

    $options_to_delete = array(
        'myplugin_settings',
        'myplugin_api_key',
        'myplugin_state',
    );

    $deleted = array();
    foreach ( $options_to_delete as $option ) {
        if ( delete_option( $option ) ) {
            $deleted[] = $option;
        }
    }

    delete_transient( 'myplugin_cache' );

    wp_send_json_success( array(
        'message' => 'تنظیمات بازنشانی شد',
        'deleted' => $deleted,
    ) );
}
حذف گزینه‌های افزونه با الگوی Prefix:
function myplugin_delete_all_options() {
    global $wpdb;

    $prefix = 'myplugin_';
    $rows = $wpdb->get_col( $wpdb->prepare(
        "SELECT option_name FROM {$wpdb->options}
         WHERE option_name LIKE %s",
        $wpdb->esc_like( $prefix ) . '%'
    ) );

    if ( ! is_array( $rows ) ) {
        return 0;
    }

    $count = 0;
    foreach ( $rows as $option_name ) {
        if ( delete_option( $option_name ) ) {
            $count++;
        }
    }

    return $count;
}
نکته مهم: این الگو تنها گزینه‌هایی را حذف می‌کند که با prefix اختصاصی شما شروع می‌شوند. هرگز از کوئری مستقیم بدون محدودیت استفاده نکنید، چرا که ممکن است گزینه‌های هسته وردپرس یا سایر افزونه‌ها را حذف کنید. حذف گزینه در زمان غیرفعال‌سازی با حفظ داده کاربر:
register_deactivation_hook( __FILE__, 'myplugin_deactivate_cleanup' );
function myplugin_deactivate_cleanup() {
    delete_option( 'myplugin_temp_state' );
    delete_option( 'myplugin_runtime_cache' );

    delete_transient( 'myplugin_api_cache' );
    delete_transient( 'myplugin_stats_cache' );
}
راهنمای توابع کش در صفحه delete_transient آمده است.

هوک‌های مرتبط با حذف

وردپرس سه هوک مرتبط با حذف گزینه‌ها فراهم می‌کند: - delete_option: برای همه گزینه‌ها، پیش از حذف - delete_option_{$option}: برای گزینه مشخص، پیش از حذف - deleted_option: پس از حذف موفق نمونه استفاده:
add_action( 'delete_option_myplugin_settings', 'myplugin_on_settings_deleted', 10, 2 );
function myplugin_on_settings_deleted( $option, $value ) {
    delete_transient( 'myplugin_cache' );
    delete_transient( 'myplugin_stats' );

    if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
        error_log( sprintf(
            'Option deleted: %s with size %d bytes',
            $option,
            strlen( maybe_serialize( $value ) )
        ) );
    }
}
نکته مهم: این هوک امکان پاک‌سازی کش‌های وابسته را فراهم می‌کند. اگر داده‌ای بر پایه گزینه حذف‌شده کش شده باشد، باید در این هوک پاک شود.

نکات امنیتی و اشتباهات رایج

اشتباه اول، نبود بررسی capability است. اگر حذف از طریق فرم یا AJAX انجام شود، باید بررسی شود که کاربر مجاز است. راهنمای این تابع در صفحه current_user_can آمده است. اشتباه دوم، نبود بررسی nonce است. هر حذف از فرم باید nonce داشته باشد. راهنمای این تابع در صفحه wp_verify_nonce آمده است. اشتباه سوم، نبود بررسی مقدار بازگشتی است. اگر گزینه وجود نداشته باشد، تابع false برمی‌گرداند که ممکن است به معنای خطا یا عدم وجود باشد. اشتباه چهارم، حذف انبوه بدون محدودیت است. اگر با کوئری مستقیم همه گزینه‌ها را حذف کنید، ممکن است به هسته وردپرس یا سایر افزونه‌ها آسیب بزنید. اشتباه پنجم، نبود لاگ‌گیری است. حذف داده‌های مهم باید در لاگ سرور ثبت شود تا در صورت بروز مشکل، قابل ردیابی باشد. اشتباه ششم، حذف در زمان اشتباه است. حذف در زمان غیرفعال‌سازی باید محتاطانه باشد چرا که ممکن است کاربر افزونه را دوباره فعال کند. اشتباه هفتم، نبود تست است. باید سناریوهای وجود گزینه، نبود گزینه، حذف موفق و حذف ناموفق را بررسی کنید.

تحلیل فنی پیشرفته

در نگاه مهندسی، تابع delete_option() یک نقطه معماری در لایه Data Lifecycle Management است که بر چند جنبه از سیستم اثر می‌گذارد. لایه اول لایه Storage Abstraction است. این تابع لایه‌ای از انتزاع روی جدول wp_options ایجاد می‌کند. لایه دوم لایه Hooks-based Observability است. هوک‌های delete_option_{$option} و deleted_option امکان رهگیری تغییرات را فراهم می‌کنند. لایه سوم لایه Caching است. تابع delete_option مقدار را از Object Cache نیز حذف می‌کند تا بازخوانی‌های بعدی داده قدیمی را نبینند. لایه چهارم لایه Data Integrity است. حذف داده باید با احتیاط انجام شود چرا که ممکن است به نبود داده در کدهای دیگر منجر شود. لایه پنجم لایه Security است. حذف از فرم باید با بررسی capability و nonce همراه باشد. لایه ششم لایه Multisite است. در شبکه‌های Multisite، گزینه‌ها در هر سایت مستقل ذخیره می‌شوند. توابع مخصوص شبکه مانند delete_site_option برای گزینه‌های سطح شبکه استفاده می‌شوند. لایه هفتم لایه Performance است. حذف منظم داده‌های قدیمی، کارایی سایت را حفظ می‌کند و از Database Bloat جلوگیری می‌کند. لایه هشتم لایه Auditing است. در پروژه‌های حساس، حذف داده باید در لاگ حسابرسی ثبت شود تا در صورت بروز مشکل، قابل ردیابی باشد. لایه نهم لایه Testing است. تست‌های واحد باید سناریوهای وجود، نبود، حذف موفق و حذف ناموفق را پوشش دهند. مفاهیم پایه‌ای Data Lifecycle در Data lifecycle management در ویکی‌پدیا توضیح داده شده است. برای مطالعه بیشتر روی توابع مرتبط، می‌توانید به راهنمای get_option، راهنمای update_option، راهنمای delete_transient، راهنمای get_transient، راهنمای set_transient، راهنمای register_activation_hook و راهنمای register_deactivation_hook مراجعه کنید.

پرسش‌های پرتکرار

اگر گزینه وجود نداشته باشد، این تابع خطا می‌دهد؟ خیر، مقدار false برمی‌گرداند. تفاوت delete_option و delete_transient چیست؟ اولی برای گزینه‌های دائمی و دومی برای داده‌های کش با انقضا. آیا حذف گزینه در Object Cache نیز اعمال می‌شود؟ بله، تابع مقدار را از کش نیز حذف می‌کند. آیا می‌توان همه گزینه‌های افزونه را با یک تابع حذف کرد؟ بله، با الگوی حلقه روی گزینه‌ها، اما با محدودیت prefix. آیا حذف گزینه در Multisite بین سایت‌ها مشترک است؟ خیر، هر سایت مستقل است.

ادامه مسیر

تابع delete_option() ابزار پایه وردپرس برای پاک‌سازی داده‌های ذخیره‌شده است. استفاده درست از آن یعنی بررسی capability و nonce در فرم‌ها، پاک‌سازی کنترل‌شده با prefix اختصاصی، مدیریت چرخه عمر داده در سه نقطه فعال‌سازی، غیرفعال‌سازی و حذف و لاگ‌گیری از عملیات مهم. اشتباه‌های کوچک در این تابع اغلب به باقی ماندن داده‌های ناخواسته یا حذف ناخواسته منجر می‌شوند. اگر این تابع را در پروژه‌ای واقعی به کار برده‌اید و رفتار غیرمنتظره‌ای دیده‌اید — به‌خصوص در Multisite یا در افزونه‌های چندماژولی — تجربه‌تان می‌تواند راهگشای دیگران باشد. کدام بخش بیشترین زمان را از شما گرفت؟ دیدگاه خود را بنویسید.