چرا داده قدیمی در سایت شما باقی میماند؟ راهنمای تخصصی delete_transient
تابع delete_transient برای حذف داده کششده در وردپرس؛ بررسی پارامترها، زمان صحیح پاکسازی، ترکیب با هوکها و اشتباهات رایج در مدیریت کش.
چرا پاکسازی کش حیاتی است؟
در هر سیستمی که از کش استفاده میکند، مدیریت صحیح انقضا و پاکسازی مهمترین بخش طراحی است. اگر داده در سمت سرور تغییر کند اما Transient همچنان معتبر باشد، کاربران داده قدیمی میبینند. این مسئله در فروشگاهها، سیستمهای رزرو، نمایش موجودی و قیمت بسیار خطرناک است. تابعdelete_transient ابزار اصلی وردپرس برای پاکسازی کنترلشده کش است. این تابع به شما امکان میدهد در نقاط بحرانی تغییر داده، کش را باطل کنید تا داده تازه به کاربران نمایش داده شود.
تابع delete_transient چیست؟
تابعdelete_transient() یک تابع هسته وردپرس است که در فایل wp-includes/option.php تعریف شده است. این تابع یک Transient مشخص را از سیستم کش حذف میکند.
برخلاف انقضای خودکار که توسط زمان انجام میشود، این تابع امکان پاکسازی دستی و لحظهای را فراهم میکند. این ویژگی در سناریوهایی که داده در سمت سرور تغییر کرده و باید فوراً در سایت اعمال شود، حیاتی است.
نکته مهم این است که این تابع در صورت نبود Transient، خطا نمیدهد و مقدار false برمیگرداند. بنابراین میتوان آن را بدون نگرانی از خطا فراخوانی کرد.
امضای تابع و پارامترها
امضای این تابع بهشکل زیر است:function delete_transient( $transient ) {
if ( wp_using_ext_object_cache() ) {
$result = wp_cache_delete( $transient, 'transient' );
} else {
do_action( 'delete_transient', $transient );
delete_option( '_transient_timeout_' . $transient );
$result = delete_option( '_transient_' . $transient );
}
return $result;
}
پارامتر ورودی (transient) نام کلید کش است که باید دقیقاً با نامی که در set_transient استفاده شده مطابقت داشته باشد.
خروجی یک مقدار بولی است: true اگر حذف موفق باشد و false در غیر این صورت.
سازوکار داخلی تابع
تابعdelete_transient بسته به نوع Object Cache دو مسیر متفاوت دارد:
**مسیر External Object Cache**:
اگر سایت از Redis یا Memcached استفاده کند، تابع wp_cache_delete فراخوانی میشود و داده از حافظه حذف میشود.
**مسیر Options Table**:
اگر Object Cache خارجی وجود نداشته باشد، وردپرس دو رکورد را از جدول wp_options حذف میکند:
- _transient_timeout_{name}: زمان انقضا
- _transient_{name}: مقدار داده
پیش از حذف، هوک delete_transient با نام transient فراخوانی میشود. این هوک امکان اجرای عملیات جانبی مانند ثبت لاگ یا پاکسازی کشهای وابسته را فراهم میکند.
زمان صحیح پاکسازی
انتخاب زمان صحیح برای فراخوانیdelete_transient، به ماهیت داده بستگی دارد. چند سناریوی رایج:
**پس از ذخیره تنظیمات افزونه**:
function myplugin_save_settings( $settings ) {
update_option( 'myplugin_settings', $settings );
delete_transient( 'myplugin_settings_cache' );
delete_transient( 'myplugin_settings_frontend' );
}
**پس از افزودن یا ویرایش نوشته**:
add_action( 'save_post', 'myplugin_invalidate_post_cache' );
function myplugin_invalidate_post_cache( $post_id ) {
delete_transient( 'myplugin_latest_posts' );
delete_transient( 'myplugin_post_' . $post_id );
}
**پس از پردازش سفارش**:
add_action( 'woocommerce_order_status_changed', 'myplugin_invalidate_order_cache' );
function myplugin_invalidate_order_cache() {
delete_transient( 'myplugin_top_products' );
delete_transient( 'myplugin_sales_stats' );
}
نکته مهم: پاکسازی باید در همان مکانی انجام شود که داده اصلی تغییر میکند. راهنمای هوک save_post در صفحه save_post آمده است.
ترکیب با هوکهای وردپرس
هوکdelete_transient امکان اجرای عملیات جانبی هنگام پاکسازی را فراهم میکند:
add_action( 'delete_transient', 'myplugin_log_deletion', 10, 1 );
function myplugin_log_deletion( $transient_name ) {
if ( 0 === strpos( $transient_name, 'myplugin_' ) ) {
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
error_log( sprintf( 'Transient deleted: %s', $transient_name ) );
}
}
}
همچنین میتوانید یک الگوی متمرکز برای پاکسازی همه Transientهای افزونه بسازید:
function myplugin_flush_all_transients() {
$prefix = 'myplugin_';
global $wpdb;
if ( wp_using_ext_object_cache() ) {
// در حالت Object Cache، بهتر است از الگوی کشینگ استاندارد استفاده کنید
return;
}
$rows = $wpdb->get_col( $wpdb->prepare(
'SELECT option_name FROM {$wpdb->options}
WHERE option_name LIKE %s OR option_name LIKE %s',
'_transient_' . $prefix . '%',
'_transient_timeout_' . $prefix . '%'
) );
foreach ( $rows as $row ) {
$key = str_replace(
array( '_transient_', '_transient_timeout_' ),
'',
$row
);
delete_transient( $key );
}
}
نکته مهم: این الگو تنها در حالت Options Table کاربرد دارد. در حالت External Object Cache، باید از الگوهای مخصوص آن سیستم استفاده کنید.
کاربردهای عملی در افزونه
پاکسازی کامل کش با دکمه در پنل مدیریت:add_action( 'wp_ajax_myplugin_flush_cache', 'myplugin_flush_cache_handler' );
function myplugin_flush_cache_handler() {
check_ajax_referer( 'myplugin_flush_nonce', 'nonce' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( array( 'message' => 'دسترسی غیرمجاز' ), 403 );
}
$transients_to_flush = array(
'myplugin_latest_posts',
'myplugin_top_products',
'myplugin_category_stats',
'myplugin_site_stats',
);
foreach ( $transients_to_flush as $key ) {
delete_transient( $key );
}
wp_send_json_success( array(
'message' => 'کش با موفقیت پاک شد',
'count' => count( $transients_to_flush ),
) );
}
راهنمای توابع استفادهشده در این بخش: check_ajax_referer، current_user_can، wp_send_json_success و wp_send_json_error.
پاکسازی خودکار هنگام انتشار نوشته جدید:
add_action( 'transition_post_status', 'myplugin_invalidate_on_publish', 10, 3 );
function myplugin_invalidate_on_publish( $new_status, $old_status, $post ) {
if ( 'publish' !== $new_status ) {
return;
}
if ( ! in_array( $post->post_type, array( 'post', 'product' ), true ) ) {
return;
}
delete_transient( 'myplugin_latest_' . $post->post_type );
delete_transient( 'myplugin_featured_content' );
delete_transient( 'myplugin_sitemap_cache' );
}
پاکسازی پس از بهروزرسانی محصول:
add_action( 'woocommerce_update_product', 'myplugin_invalidate_product_cache', 10, 1 );
function myplugin_invalidate_product_cache( $product_id ) {
delete_transient( 'myplugin_product_' . $product_id );
delete_transient( 'myplugin_related_' . $product_id );
delete_transient( 'myplugin_price_range' );
}
الگوهای Cache Invalidation
**الگوی Time-Based**: سادهترین الگو که بر پایه انقضای زمانی کار میکند. کافی است درset_transient مقدار expiration مناسب بدهید.
**الگوی Event-Based**:
پاکسازی در زمان رخداد تغییر داده. این الگو برای دادههایی مناسب است که بهندرت اما بهصورت غیرمنظم تغییر میکنند.
**الگوی Key Versioning**:
بهجای حذف، نسخه کلید را افزایش دهید:
function myplugin_get_versioned_cache( $base_key ) {
$version = (int) get_option( $base_key . '_version', 1 );
$cache_key = $base_key . '_v' . $version;
$cached = get_transient( $cache_key );
if ( false !== $cached ) {
return $cached;
}
$data = myplugin_fetch_data();
set_transient( $cache_key, $data, HOUR_IN_SECONDS );
return $data;
}
function myplugin_bump_cache_version( $base_key ) {
$version = (int) get_option( $base_key . '_version', 1 );
update_option( $base_key . '_version', $version + 1 );
}
این الگو از حذف مکرر Transient جلوگیری میکند و در سایتهای پربازدید کارایی بهتری دارد.
نکات امنیتی و اشتباهات رایج
اشتباه اول، نبود بررسی است. اگر نام Transient اشتباه باشد، حذف ناموفق میماند و هیچ خطایی نمایش داده نمیشود. مقدار بازگشتی را بررسی کنید. اشتباه دوم، نبود شرط است. اگرdelete_transient را بدون شرط فراخوانی کنید، ممکن است دادهای را حذف کنید که هنوز معتبر است.
اشتباه سوم، نبود هوک مناسب است. پاکسازی باید در همان مکانی انجام شود که داده اصلی تغییر میکند.
اشتباه چهارم، پاکسازی زودهنگام است. اگر پیش از ذخیره داده اصلی، Transient را پاک کنید، ممکن است فرآیند نیمهکاره بماند.
اشتباه پنجم، نبود توجه به ترتیب است. در سناریوهایی که چند Transient وابسته هستند، ترتیب پاکسازی مهم است.
اشتباه ششم، نبود تست است. باید بررسی کنید که پس از پاکسازی، داده تازه بازخوانی میشود.
اشتباه هفتم، حذف انبوه بدون احتیاط است. اگر با کوئری مستقیم همه Transientها را حذف کنید، ممکن است Transientهای هسته وردپرس و سایر افزونهها را نیز از بین ببرید.
تحلیل فنی پیشرفته
در نگاه مهندسی، تابعdelete_transient() یک نقطه معماری در لایه Cache Invalidation است که بر چند جنبه از سیستم اثر میگذارد. لایه اول لایه Storage Abstraction است. این تابع دو مسیر متفاوت برای Object Cache و Options Table دارد.
لایه دوم لایه Hook-based Invalidation است. هوک delete_transient امکان اجرای عملیات جانبی را فراهم میکند.
لایه سوم لایه Concurrency است. اگر دو درخواست همزمان یک Transient را حذف کنند، نتیجه idempotent است و مشکلی رخ نمیدهد.
لایه چهارم لایه Versioning است. الگوی Key Versioning از حذف مکرر جلوگیری میکند و در سایتهای پربازدید کارایی بهتری دارد.
لایه پنجم لایه Multi-Level Cache است. اگر سایت از چند لایه کش (Page Cache، Object Cache، CDN) استفاده میکند، حذف Transient تنها یکی از لایهها را پاک میکند.
لایه ششم لایه Security است. نام Transientها باید از افشای اطلاعات حساس جلوگیری کند.
لایه هفتم لایه Multisite است. در شبکههای Multisite، Transient در هر سایت مستقل حذف میشود.
لایه هشتم لایه Testing است. تستهای واحد باید سناریوهای نبود، وجود، پاکسازی موفق و پاکسازی ناموفق را پوشش دهند.
مفاهیم پایهای Cache Invalidation در Cache Invalidation در ویکیپدیا توضیح داده شده است.
برای مطالعه بیشتر روی توابع مرتبط، میتوانید به راهنمای get_transient، راهنمای set_transient، راهنمای get_option، راهنمای update_option، راهنمای delete_option، راهنمای هوک save_post و راهنمای wp_send_json_success مراجعه کنید.
پرسشهای پرتکرار
اگر Transient وجود نداشته باشد، این تابع خطا میدهد؟ خیر، مقدارfalse برمیگرداند.
تفاوت delete_transient و delete_option چیست؟ اولی برای Transientها و دومی برای سایر گزینهها.
آیا پاکسازی همه Transientها توصیه میشود؟ تنها در مواقع بحرانی. حذف انبوه میتواند عملکرد سایت را تحت تأثیر قرار دهد.
آیا پاکسازی Transient در Multisite بین سایتها مشترک است؟ خیر، هر سایت مستقل است.
آیا میتوان با کوئری مستقیم، Transientها را حذف کرد؟ ممکن است، اما خطرناک است و میتواند به Transientهای هسته آسیب بزند.
نتیجه و مسیر ادامه
تابعdelete_transient() ابزار اصلی وردپرس برای مدیریت صحت داده کششده است. استفاده درست از آن یعنی انتخاب زمان صحیح پاکسازی، ترکیب با هوکهای مناسب، بررسی نتیجه و استفاده از الگوهای حرفهای مانند Key Versioning. اشتباههای کوچک در این تابع اغلب به نمایش دادههای قدیمی یا مصرف بیدلیل منابع منجر میشوند.
اگر این تابع را در پروژهای واقعی به کار بردهاید و رفتار غیرمنتظرهای دیدهاید — بهخصوص در ترکیب با External Object Cache یا در سناریوهای چندسروری — تجربهتان میتواند راهگشای دیگران باشد. کدام بخش بیشترین زمان را از شما گرفت؟ دیدگاه خود را بنویسید.