توابع وردپرس برای کار با گزینههای سایت
راهنمای کاربردی توابع Options API در وردپرس؛ از ذخیره و بازیابی تا autoload، امنیت و ساختاردهی بر پایه تجربه پروژههای واقعی.
اولین بار که با یک دیتابیس وردپرسِ بادکرده مواجه شدم، سایت یک فروشگاه عطر بود. هفت سال، چهار تیم توسعه مختلف، سه بار تغییر قالب، و نصب و حذفِ بالای پنجاه افزونه در کارنامهاش. کارفرما شکایت داشت که پیشخوان کند است و صفحه محصول نیم دقیقه باز میشود. کوئری که روی جدول wp_options زدم، نتیجهاش شوکهکننده بود: از یک میلیون و چهارصد هزار ردیف، بیش از هفتصد هزار ردیف مربوط به افزونههایی بود که دو سال پیش حذف شده بودند. هر get_option روی صفحه محصول، یک بار در دیتابیس میگشت؛ و هر بار، روی یک انبار بههمریخته از دادههای یتیم. پاکسازی آن جدول، دو روز کار شد و سرعت پیشخوان را سه برابر کرد. آن هفته، درس بزرگی گرفتم: Options API سادهترین API وردپرس است برای استفاده، ولی مخربترین آنها اگر جدی گرفته نشود.
در این مقاله، تجربهام از کار با توابع گزینههای سایت را با شما به اشتراک میگذارم. اگر با مفاهیم پایه آشنا نیستید، وردپرس چیست و چگونه شروع کنیم و نحوه استفاده از توابع وردپرس در پروژهها را پیش از ادامه ببینید. همچنین برای درک عمیقتر، کار با Options API مرجع کامل است.
Options API چیست و چه زمانی بهکار میآید؟
Options API مکانیزم استاندارد وردپرس برای ذخیرهسازی دادههای ساختاری نامنظم (key-value) در جدول wp_options است. سه ستون اصلی این جدول: option_name (کلید یکتا)، option_value (مقدار، سریالایزشده در صورت لزوم)، و autoload (تعیینکننده بارگذاری خودکار). چهار سناریوی اصلی برای Options API:
- تنظیمات افزونه: کلید API، سطح فعالسازی، حالتهای پیشفرض.
- تنظیمات قالب: رنگبندی، فونت، چیدمان پیشفرض.
- دادههای سراسری سایت: آمار، لاگ، کش ساده.
- پرچمهای وضعیت: نسخهٔ دیتابیس، تنظیمات نصب.
تفاوت Options API با ترنزینتها را در ترنزینتها در وردپرس، با متادیتای پست در کار با متاباکسها، و با User Meta در کار با User Meta آوردهام.
Options API مکانیزم ذخیرهسازی دادهٔ سراسری در وردپرس است؛ نه جای دادهٔ کاربر، نه جای متادیتای پست. تفکیک این سه، اولین گام معماری دادهٔ درست است.
چهار عمل اصلی: افزودن، خواندن، بهروزرسانی، حذف
چهار تابع پایه در Options API:
// افزودن
add_option( "my_plugin_api_key", "abc123", "", "yes" );
// خواندن
$api_key = get_option( "my_plugin_api_key", "پیشفرض" );
// بهروزرسانی
update_option( "my_plugin_api_key", "xyz789" );
// حذف
delete_option( "my_plugin_api_key" );
نکتهها: یک — get_option با مقدار پیشفرض: همیشه پارامتر دوم را بگذارید. بدون آن، اگر option وجود نداشت، false برمیگرداند و نمیتوان تفاوت «نبود» با «مقدار false» را تشخیص داد. دو — add_option در برابر update_option: add_option فقط اگر option وجود ندارد اضافه میکند؛ update_option اگر وجود دارد بهروزرسانی و اگر ندارد اضافه میکند. برای امنیت بیشتر، در فعالسازی افزونه از add_option استفاده کنید و در عملیات روزمره از update_option. سه — پیشوند یکتا: تمام کلیدهای option باید با پیشوند افزونه شروع شوند تا تعارض با افزونههای دیگر رخ ندهد. چهار — delete_option هنگام غیرفعالسازی: نه همیشه. اگر کاربر افزونه را موقتاً غیرفعال میکند، احتمالاً نمیخواهید تنظیمات از دست برود. حذف فقط در uninstall.php. راهنمای کامل توابع در توابع وردپرس برای گزینههای سایت و توابع متادیتا.
سه تابع مکمل که گاهی بهکار میآیند: یک — update_site_option: در مالتیسایت، برای ذخیرهٔ در سطح شبکه. دو — get_site_option: متناظر خواندن. سه — delete_site_option: حذف در سطح شبکه. تفاوت اینها با نسخههای معمول در بخش مالتیسایت همین مقاله میآید.
autoload و تأثیر آن بر عملکرد
ستون autoload در جدول wp_options، یکی از کمتوجهشدهترین و در عین حال مهمترین فیلدهای وردپرس است. سه مقدار ممکن: یک — yes: option بهطور خودکار در هر بازدید بارگذاری میشود. مناسب optionهایی که تقریباً همیشه بهکار میآیند (تنظیمات پایهٔ سایت، تنظیمات افزونههای فعال). دو — no: option فقط وقتی لود میشود که صریحاً get_option فراخوانی شود. مناسب optionهای سنگین یا کممصرف. سه — auto-on یا auto-off: در نسخههای اخیر وردپرس، رفتار پویا.
// با autoload = yes
add_option( "my_plugin_settings", $data, "", "yes" );
// با autoload = no (پیشنهاد برای دادههای سنگین)
add_option( "my_plugin_large_cache", $data, "", "no" );
نکتهٔ کلیدی: هر option با autoload = yes، در هر بازدید لود میشود — حتی اگر در آن درخواست بهکار نرود. اگر ۵۰ option با autoload=yes در سایت وجود داشته باشد و هرکدام ۵ کیلوبایت باشد، ۲۵۰ کیلوبایت به هر ریکوئست اضافه میشود. تجربهٔ میدانی من در سایتهای قدیمی: گاهی دهها مگابایت option با autoload=yes دیدهام که نتیجهاش کندی مزمن سایت و فشار روی دیتابیس بوده. روش بررسی: با یک کوئری ساده در phpMyAdmin:
SELECT SUM( LENGTH( option_value ) ) AS total_size
FROM wp_options
WHERE autoload = "yes";
اگر عدد بالای ۱ مگابایت است، زمان بازبینی رسیده. راهنمای تکمیلی در بهینهسازی کوئریهای MySQL، پاکسازی دیتابیس وردپرس، و بهینهسازی کد وردپرس.
یک نکتهٔ عملی دربارهٔ تغییر autoload روی option موجود:
// روش استاندارد - حذف و افزودن مجدد
$value = get_option( "my_plugin_large_data" );
delete_option( "my_plugin_large_data" );
add_option( "my_plugin_large_data", $value, "", "no" );
این الگو در نسخههای قدیمی وردپرس، تنها راه امن است. در نسخههای جدید، میتوانید با WP-CLI هم این کار را انجام دهید: wp option update my_plugin_large_data --autoload=no.
ذخیرهٔ دادههای ساختاریافته
Options API بهطور خودکار آرایه و آبجکت را سریالایز میکند. سه الگوی متداول: یک — آرایهٔ تنظیمات:
$settings = array(
"api_key" => "abc123",
"debug" => true,
"retry_max" => 3,
"cache_ttl" => 3600,
);
update_option( "my_plugin_settings", $settings );
// خواندن
$settings = get_option( "my_plugin_settings", array() );
$api_key = $settings["api_key"] ?? "";
$debug = ! empty( $settings["debug"] );
مزیت این الگو: تمام تنظیمات در یک ردیف از جدول. بدون آن، هر تنظیم یک ردیف جداگانه میشد که جدول را شلوغ میکرد. دو — آبجکت: مشابه آرایه، ولی توصیه نمیشود چون در خواندن و بهروزرسانی، تبدیلهای اضافه لازم دارد. سه — دادهٔ عددی بزرگ: برای آمار یا لاگ، از نوع دادهٔ مناسب استفاده کنید:
$stats = array(
"total_visits" => 125000,
"unique_visitors" => 45000,
"last_reset" => time(),
);
update_option( "my_plugin_stats", $stats );
نکته: دادههای حجیم (بیش از چند صد کیلوبایت) را در Options API نگه ندارید. برای این موارد، یا از کش اختصاصی (Redis/Memcached) استفاده کنید، یا از جداول اختصاصی دیتابیس. راهنمای انتخاب در تأثیر دیتابیس بر سرعت سایت. یک قاعدهٔ عملی: اگر دادهای قرار است بیشتر از ۱۰۰ کیلوبایت باشد، بهتر است از Options API خارج شود. دلیل: هر بار که option با autoload=yes لود میشود، تمام محتوایش در حافظه قرار میگیرد، حتی اگر آن درخواست به بخشی از آن نیاز نداشته باشد.
رابطه با Settings API
Settings API، لایهای بالاتر از Options API است که مدیریت فرم، nonce، sanitize و ذخیره را خودکار انجام میدهد. تفاوت بنیادین: Options API — ذخیرهسازی سطح پایین. Settings API — رابط مدیریت فرم که در پشت صحنه از Options API استفاده میکند. الگوی ترکیبی:
function my_plugin_register_settings() {
register_setting(
"my_plugin_group",
"my_plugin_options",
array(
"type" => "array",
"sanitize_callback" => "my_plugin_sanitize",
"default" => array(),
"autoload" => "yes",
)
);
}
add_action( "admin_init", "my_plugin_register_settings" );
پارامتر autoload در register_setting از وردپرس ۴.۲ به بعد پشتیبانی میشود. مزیت این الگو: فرم مدیریت، nonce و sanitize خودکار. در پسزمینه، ذخیره در wp_options انجام میشود. راهنمای کامل در ساخت صفحهٔ تنظیمات اختصاصی و پاکسازی دادهها. یک نکتهٔ مهم: برای تنظیمات پیچیده با چند فیلد، همیشه Settings API را انتخاب کنید. Options API تنها برای ذخیرهسازی داخلی و بدون فرم مدیریتی، انتخاب درست است.
Options API در مالتیسایت
در وردپرس مالتیسایت، دو سطح ذخیرهسازی وجود دارد: یک — سطح سایت (blog): هر سایت، جدول wp_options خودش را دارد. توابع get_option، add_option، update_option، delete_option در این سطح کار میکنند. دو — سطح شبکه: تمام شبکه، جدول wp_sitemeta دارد. برای این سطح، از توابع get_site_option، add_site_option، update_site_option، delete_site_option استفاده میشود.
// ذخیرهٔ تنظیمات در سطح شبکه
update_site_option( "my_plugin_network_settings", array(
"enabled" => true,
"version" => "1.0.0",
) );
// خواندن
$settings = get_site_option( "my_plugin_network_settings", array() );
نکته: در مالتیسایت، اگر میخواهید تنظیمات در تمام سایتها یکسان باشد، از توابع سطح شبکه استفاده کنید. برای تنظیمات اختصاصی هر سایت، از توابع معمول. ترکیب هوشمندانه: تنظیمات سراسری در شبکه، تنظیمات اختصاصی هر سایت در site_option. راهنمای مالتیسایت در وردپرس مالتیسایت و مدیریت دیتابیس وردپرس.
کش و بازیابی سریع
Options API دو لایهٔ کش داخلی دارد: یک — کش حافظهای درخواست (request-level cache): در هر درخواست، اولین get_option کوئری میزند، ولی فراخوانیهای بعدی همان option، از حافظه خوانده میشوند. دو — کش سراسری با object cache: اگر Redis یا Memcached فعال باشد، optionها در کش سراسری ذخیره میشوند و بین درخواستها به اشتراک گذاشته میشوند.
// در wp-config.php
// برای فعالسازی object cache با Redis
// نیاز به نصب Redis و افزونهٔ Redis Object Cache
نکته: با فعالسازی object cache، تعداد کوئریهای wp_options بهطور چشمگیری کاهش مییابد. تجربههای میدانی من در پروژههای پرترافیک: با Redis، تعداد کوئریهای دیتابیس از چند صد به زیر بیست در هر ریکوئست رسیده. راهنمای کامل کش در افزونههای کش وردپرس و بهینهسازی کد وردپرس.
پاکسازی و مدیریت حجم
با گذشت زمان، جدول wp_options ممکن است با ردیفهای بیاستفاده پر شود. سه منبع رایج: یک — افزونههای حذفشده که uninstall.php نداشتهاند. دو — optionهای موقت که پاک نشدهاند. سه — ترنزینتهای منقضی. دو ابزار پاکسازی: یک — پاکسازی دستی با phpMyAdmin:
-- یافتن optionهای بزرگ
SELECT option_name, LENGTH(option_value) AS size
FROM wp_options
WHERE autoload = "yes"
ORDER BY size DESC
LIMIT 30;
دو — پاکسازی با افزونه: افزونههایی مثل WP-Optimize یا Advanced Database Cleaner امکان پاکسازی هدفمند optionها، ترنزینتها و ردیفهای بیاستفاده را میدهند. راهنمای کامل در پاکسازی دیتابیس وردپرس، افزونههای بهینهسازی دیتابیس، و پاکسازی ترنزینتها. یک نکتهٔ مهم: پیش از هر پاکسازی، بکاپ کامل از دیتابیس بگیرید. راهنمای بکاپ در بکاپ دیتابیس و افزونههای بکاپ.
ساختار کلاسمحور
در افزونههای جدی، منطق Options API در یک کلاس اختصاصی نگه داشته میشود:
class My_Plugin_Settings {
const OPTION_KEY = "my_plugin_settings";
const DEFAULTS = array(
"api_key" => "",
"debug" => false,
"cache_ttl" => 3600,
);
public static function init() {
add_action( "admin_init", array( __CLASS__, "register" ) );
}
public static function get( $key = null ) {
$settings = get_option( self::OPTION_KEY, self::DEFAULTS );
if ( ! is_array( $settings ) ) {
$settings = self::DEFAULTS;
}
$settings = wp_parse_args( $settings, self::DEFAULTS );
return $key ? ( $settings[ $key ] ?? null ) : $settings;
}
public static function update( $key, $value ) {
$settings = self::get();
$settings[ $key ] = $value;
return update_option( self::OPTION_KEY, $settings );
}
public static function delete_all() {
return delete_option( self::OPTION_KEY );
}
public static function register() {
register_setting(
"my_plugin_group",
self::OPTION_KEY,
array(
"type" => "array",
"sanitize_callback" => array( __CLASS__, "sanitize" ),
"default" => self::DEFAULTS,
)
);
}
public static function sanitize( $input ) {
$clean = self::DEFAULTS;
if ( isset( $input["api_key"] ) ) {
$clean["api_key"] = sanitize_text_field( $input["api_key"] );
}
if ( isset( $input["debug"] ) ) {
$clean["debug"] = (bool) $input["debug"];
}
if ( isset( $input["cache_ttl"] ) ) {
$clean["cache_ttl"] = absint( $input["cache_ttl"] );
}
return $clean;
}
}
My_Plugin_Settings::init();
مزیت این ساختار: یک نقطهٔ دسترسی برای تمام تنظیمات، مدیریت پیشفرضها در یک نقطه، و امکان تست. الگوهای مشابه در کدنویسی اختصاصی افزونه و ساختار فایلهای افزونهٔ استاندارد. یک نکتهٔ ساختاری مهم: همیشه مقادیر پیشفرض را در یک ثابت نگه دارید. اگر روزی ساختار تنظیمات تغییر کرد، فقط یک نقطه را ویرایش میکنید. الگوهای استاندارد کد در استانداردهای کدنویسی وردپرس و پیادهسازی استانداردها.
امنیت در Options API
چهار قاعدهٔ الزامی: یک — پاکسازی پیش از ذخیره. هر مقدار بسته به نوع خود. دو — escape در نمایش. esc_html، esc_attr، esc_url. سه — نانس در فرمهای مدیریت. اگر از Settings API استفاده میکنید، خودکار. اگر فرم دستی دارید، نانس الزامی است. چهار — محدودسازی دسترسی. توابعی که option را بهروزرسانی میکنند، باید در فرمهای مدیریت و با capability مناسب محافظت شوند. نمونهٔ نانس دستی:
// در فرم
<?php wp_nonce_field( "my_plugin_save", "my_plugin_nonce" ); ?>
// در پردازش
if ( ! isset( $_POST["my_plugin_nonce"] ) ) {
return;
}
if ( ! wp_verify_nonce( $_POST["my_plugin_nonce"], "my_plugin_save" ) ) {
return;
}
if ( ! current_user_can( "manage_options" ) ) {
return;
}
راهنمای کامل در PHP امن در وردپرس، نانس وردپرس، پاکسازی دادهها، و اعتبارسنجی دادهها. یک آسیبپذیری شایع که در پروندههای امنیتی دیدهام: endpointهای AJAX که optionهای حساس را بدون check_ajax_referer بهروزرسانی میکردند. نتیجه: هر کاربری میتوانست با یک درخواست ساختگی، تنظیمات افزونه را تغییر دهد. هیچ endpoint AJAX در Options API نباید از این بررسی معاف باشد.
الگوهای پیشرفته
سه الگوی پیشرفته در کار با Options API: یک — Version Tracking. ذخیرهٔ نسخهٔ دیتابیس و اجرای مهاجرتها در فعالسازی:
function my_plugin_maybe_upgrade() {
$current_version = get_option( "my_plugin_db_version", "0.0.0" );
$target_version = "1.2.0";
if ( version_compare( $current_version, $target_version, ">=" ) ) {
return;
}
// مهاجرت از 0.0.0 به 1.2.0
if ( version_compare( $current_version, "1.0.0", "<" ) ) {
// مهاجرت به 1.0.0
}
if ( version_compare( $current_version, "1.2.0", "<" ) ) {
// مهاجرت به 1.2.0
}
update_option( "my_plugin_db_version", $target_version );
}
add_action( "plugins_loaded", "my_plugin_maybe_upgrade" );
دو — Options as Feature Flags. استفاده از option برای فعال/غیرفعالسازی قابلیتها بدون انتشار نسخهٔ جدید:
if ( get_option( "my_plugin_enable_new_editor", false ) ) {
// نسخهٔ جدید
} else {
// نسخهٔ قدیم
}
سه — Options Backup and Restore. در پروژههای مشتریمحور، امکان Export/Import تنظیمات:
// Export
$settings = get_option( "my_plugin_settings" );
header( "Content-Type: application/json" );
header( "Content-Disposition: attachment; filename="my-plugin-settings.json"" );
echo wp_json_encode( $settings );
exit;
// Import
$json = file_get_contents( $_FILES["settings_file"]["tmp_name"] );
$data = json_decode( $json, true );
if ( is_array( $data ) ) {
update_option( "my_plugin_settings", $data );
}
راهنمای الگوهای مشابه در اتصال وردپرس به سرویسهای خارجی و بهینهسازی کد وردپرس.
اشتباهات رایج
- نبود پیشوند یکتا در کلید: تعارض با افزونههای دیگر. اشتباهات رایج توسعه.
- نبود مقدار پیشفرض در
get_option: برگشتfalseو مشکل در تشخیص نبود از false. توابع گزینههای سایت. - ذخیرهٔ دادههای حجیم با
autoload=yes: کندی در هر ریکوئست. تأثیر دیتابیس بر سرعت. - نبود sanitize در ذخیره: خطر XSS. پاکسازی دادهها.
- نبود escape در نمایش: خطر XSS در پیشخوان و front-end. اعتبارسنجی دادهها.
- نبود nonce در فرم دستی: خطر CSRF. نانس وردپرس.
- نبود check_ajax_referer در AJAX: تغییر تنظیمات از طرف کاربران غیرمجاز.
- حذف option در غیرفعالسازی افزونه: از دست رفتن تنظیمات کاربر. حذف فقط در
uninstall.php. - نبود version tracking و migration: شکستن تنظیمات در آپدیتهای بزرگ. ساختاربندی پروژه.
- استفاده از Options API برای دادهٔ کاربر یا متادیتای پست: ساختار نادرست داده. User Meta و متاباکسها.
- نادیدهگرفتن cache اختصاصی: کوئریهای تکراری. افزونههای کش.
- ذخیرهٔ آرایههای بسیار بزرگ در option: کندی ذخیره و بازیابی. بهینهسازی کوئریهای MySQL.
جمعبندی
Options API، یکی از پایهایترین و در دسترسترین مکانیزمهای ذخیرهسازی در وردپرس است. مسیر حرفهای کار با آن، هفت گام دارد: چهار تابع اصلی، توجه به autoload، انتخاب صحیح نوع داده، ترکیب هوشمندانه با Settings API، مدیریت مالتیسایت، کش اختصاصی، و ساختار کلاسمحور. اگر امروز یک کار در این مسیر انجام میدهید: به جدول wp_options نگاه کنید و ببینید کدام optionهای autoload=yes بیش از ۱۰۰ کیلوبایت حجم دارند؛ انتقال آنها به autoload=no یا کش اختصاصی، ممکن است بهتنهایی سرعت سایت را محسوس کند.
اگر تجربهای از یک option سنگین یا مشکل autoload در پروژهٔ خود دارید، در دیدگاهها بنویسید — همان گزارشهای واقعی، این راهنما را دقیقتر میکند. ⚙️