چرا سایت وردپرسی شما ناگهان با صفحه سفید مواجه میشود و چطور ریشه مشکل را پیدا کنید؟
صفحه سفید مرگ وردپرس: تشخیص علت و راهحل قطعی بدون از دست دادن داده
طی این مدت که با کد وردپرس کار کردهام، تعداد زیادی تماس اضطراری درباره صفحه سفید دریافت کردهام؛ از یک فروشگاه ووکامرسی که در اوج کمپین فروش از کار افتاد تا یک سایت خبری که پس از یک بروزرسانی خودکار، تنها یک صفحه خالی نشان میداد. آنچه در همه این موارد مشترک بود، این نکته بود: هیچکدام از مدیران سایت نمیدانستند که خطای دقیق در کجا رخ داده است. همه آنها فقط میدانستند که «صفحه سفید شده». تجربه نشان داده که اگر خطای دقیق PHP استخراج شود، ریشهیابی در بیش از ۹۰ درصد موارد کمتر از پنج دقیقه طول میکشد. آنچه در ادامه میآید، همان مسیر استخراج و ریشهیابی است که در پروژههای واقعی بارها آزموده شده است.
WSOD دقیقاً چیست و چرا «سفید» است؟
صفحه سفید مرگ یا WSOD اصطلاحی است که از دنیای ویندوز به دنیای وب منتقل شده و به وضعیتی اشاره دارد که در آن، یک برنامه (اینجا وردپرس) بهطور کامل از کار میافتد و فقط یک صفحه خالی نمایش میدهد. این اصطلاح در سال ۱۹۹۸ توسط کاربران ویندوز ۹۸ رایج شد و از آن زمان در دنیای وب نیز استفاده میشود.
در وردپرس، WSOD زمانی رخ میدهد که:
- یک خطای Fatal در PHP رخ دهد (مانند فراخوانی تابع ناموجود، پارس خطا، یا اتمام حافظه).
- PHP بهدلیل خطا، اجرای اسکریپت را متوقف کند.
- خروجی که تا آن لحظه به مرورگر ارسال شده، خالی یا ناقص باشد.
- وردپرس نتواند پاسخ کامل خود را تولید کند.
سؤال کلیدی اینجاست: چرا صفحه «سفید» است و نه یک پیام خطا؟ پاسخ در دو تنظیم PHP نهفته است:
- display_errors = off: در محیطهای تولید، این تنظیم خاموش است تا خطاها به کاربران نمایش داده نشوند.
- توقف خروجی در میانه راه: اگر خطا قبل از ارسال محتوای اصلی رخ دهد، هیچ HTMLای تولید نمیشود.
نتیجه این دو عامل، یک پاسخ HTTP خالی است که مرورگر آن را بهصورت صفحه سفید نمایش میدهد. اگرچه سرور کد وضعیت ۵۰۰ (Internal Server Error) را برمیگرداند، اما مرورگر معمولاً این کد را به کاربر نمایش نمیدهد.
صفحه سفید، یک نقاب است. پشت آن، خطایی نهفته که فقط از طریق لاگ قابل مشاهده است.
خطاهای Fatal در PHP: موتور محرک WSOD
برای ریشهیابی WSOD، باید درک دقیقی از رفتار PHP در مواجهه با خطاهای مختلف داشت. PHP چند سطح خطا دارد و هر سطح، رفتار متفاوتی نشان میدهد.
انواع خطای Fatal و رفتار PHP
PHP خطاها را در سطوح مختلف دستهبندی میکند:
| سطح خطا | مقدار | رفتار | نتیجه در وردپرس |
|---|---|---|---|
| E_ERROR | 1 | توقف اجرا | صفحه سفید |
| E_PARSE | 4 | توقف در زمان کامپایل | صفحه سفید |
| E_CORE_ERROR | 16 | توقف هسته PHP | صفحه سفید |
| E_COMPILE_ERROR | 64 | توقف در زمان کامپایل | صفحه سفید |
| E_USER_ERROR | 256 | توقف اجرا | صفحه سفید |
| E_RECOVERABLE_ERROR | 4096 | توقف اگر مدیریت نشود | صفحه سفید |
| E_WARNING | 2 | ادامه اجرا | ممکن است صفحه سفید شود |
| E_NOTICE | 8 | ادامه اجرا | معمولاً مشکلی ایجاد نمیکند |
| E_DEPRECATED | 8192 | ادامه اجرا | معمولاً مشکلی ایجاد نمیکند |
خطاهای سطح E_ERROR، E_PARSE، E_CORE_ERROR، E_COMPILE_ERROR و E_USER_ERROR باعث WSOD میشوند. خطاهای Warning و Notice معمولاً اجرا را متوقف نمیکنند، اما اگر در محیطهای خاصی رخ دهند (مانند زمانی که خروجی قبلاً ارسال شده)، میتوانند به WSOD منجر شوند. برای مطالعه بیشتر درباره این نوع خطاها، مقاله خطای Fatal error در PHP چیست و چگونه آن را رفع کنیم؟ را ببینید.
نقش display_errors و سرکوب خطا
رفتار PHP در مواجهه با خطا، به دو تنظیم کلیدی وابسته است:
display_errors = Off
log_errors = On
error_log = /var/log/php/error.log
اگر display_errors خاموش باشد (که در تولید توصیه میشود)، خطاها به مرورگر نمایش داده نمیشوند اما در error_log ثبت میشوند. اگر log_errors نیز خاموش باشد، خطاها کاملاً ناپدید میشوند و ریشهیابی تقریباً غیرممکن میشود.
در وردپرس، تنظیمات جداگانهای برای کنترل نمایش خطا وجود دارد:
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);
define('SCRIPT_DEBUG', true);
ترکیب این تنظیمات، خطاها را در wp-content/debug.log ثبت میکند، بدون آنکه به کاربر نمایش دهد. برای مطالعه بیشتر، مقاله فعالسازی حالت Debug وردپرس و پیدا کردن خطاها را ببینید.
اجرای زودهنگام و خروج از کنترل error handler
نکته کلیدی که ریشهیابی WSOD را پیچیده میکند، این است که برخی خطاها پیش از فعال شدن error handler وردپرس رخ میدهند. وردپرس در فایل wp-includes/load.php یک error handler سفارشی تنظیم میکند:
function wp_debug_mode() {
if (WP_DEBUG) {
error_reporting(E_ALL);
if (WP_DEBUG_DISPLAY) {
ini_set('display_errors', 1);
} elseif (null !== WP_DEBUG_DISPLAY) {
ini_set('display_errors', 0);
}
if (WP_DEBUG_LOG) {
ini_set('log_errors', 1);
ini_set('error_log', WP_CONTENT_DIR . '/debug.log');
}
} else {
error_reporting(E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_ERROR | E_WARNING | E_PARSE | E_USER_ERROR | E_USER_WARNING | E_RECOVERABLE_ERROR);
}
}
این تابع زمانی اجرا میشود که وردپرس شروع به بارگذاری کرده باشد. اما اگر خطا در فایل wp-config.php، wp-settings.php یا در زمان بارگذاری اولیه یک افزونه رخ دهد (پیش از اجرای کامل وردپرس)، این error handler فعال نشده و خطا سرکوب میشود. نتیجه: WSOD بدون هیچ سرنخی.
چرخه اجرای وردپرس و نقاط وقوع WSOD
وردپرس از زمان ورود درخواست HTTP تا ارسال پاسخ، چند فاز مشخص را طی میکند. WSOD میتواند در هر یک از این فازها رخ دهد و شناخت هر فاز، ریشهیابی را دقیقتر میکند.
فاز Bootstrap و require فایلها
فاز Bootstrap با فایل index.php در ریشه سایت آغاز میشود:
define('WP_USE_THEMES', true);
require __DIR__ . '/wp-blog-header.php';
سپس wp-blog-header.php فایلهای wp-load.php، wp-config.php و wp-settings.php را بارگذاری میکند. در این فاز، خطاهای زیر میتوانند رخ دهند:
- فایل
wp-config.phpناقص یا اشتباه باشد. - فایل هستهای ناقص یا حذف شده باشد.
- ناسازگاری نسخه PHP با کد وردپرس.
- اتمام حافظه در بارگذاری فایلهای حجیم.
خطاهای این فاز بهویژه خطرناک هستند، زیرا error handler وردپرس هنوز فعال نشده و خطا در لاگ PHP ثبت میشود، نه در debug.log وردپرس.
بارگذاری افزونهها و فعالسازی
در فایل wp-settings.php، وردپرس افزونههای فعال را بارگذاری میکند:
foreach (wp_get_active_and_valid_plugins() as $plugin) {
wp_register_plugin_realpath($plugin);
include_once $plugin;
do_action('plugin_loaded', $plugin);
}
هر افزونه یک فایل PHP است که اجرا میشود. اگر این فایل دارای خطای پارس، فراخوانی تابع ناموجود، یا اتمام حافظه باشد، WSOD رخ میدهد. این فاز یکی از پرتکرارترین نقاط وقوع WSOD است، زیرا:
- افزونههای زیادی بهطور ترتیبی بارگذاری میشوند.
- هر افزونه میتواند خطای خود را داشته باشد.
- تداخل بین افزونهها میتواند در این فاز ظاهر شود.
برای مطالعه بیشتر درباره خطاهای افزونه، مقاله خطای افزونه وردپرس: چگونه آن را پیدا و رفع کنیم؟ را ببینید.
راهاندازی قالب و functions.php
پس از افزونهها، وردپرس قالب فعال را بارگذاری میکند:
include_once ABSPATH . WPINC . '/theme.php';
do_action('setup_theme');
require_once ABSPATH . WPINC . '/theme.php';
$GLOBALS['wp_theme'] = wp_get_theme();
// ...
require_once get_template_directory() . '/functions.php';
فایل functions.php قالب، یکی از پرتکرارترین نقاط وقوع WSOD است. خطاهای زیر در این فایل شایع هستند:
- خطای پارس بهدلیل نبود
;یا}. - فراخوانی تابع ناموجود یا منسوخ.
- تعریف دوباره تابع یا کلاس.
- اتمام حافظه در پردازش سنگین.
- کد سفارشی معیوب.
برای مطالعه بیشتر درباره خطاهای قالب، مقاله خطای قالب وردپرس: چگونه آن را پیدا و رفع کنیم؟ را ببینید.
اجرای هوکها و callbackهای سنگین
پس از بارگذاری، وردپرس هوکها را اجرا میکند:
do_action('init');
do_action('wp_loaded');
do_action('template_redirect');
// ...
do_action('wp_head');
do_action('wp_footer');
اگر callbackی که به یک هوک متصل است، خطای Fatal ایجاد کند، WSOD رخ میدهد. این خطا بهویژه در هوکهای زودرس (مانند init و wp_loaded) خطرناک است، زیرا هنوز هیچ خروجی تولید نشده است.
فاز رندر و خروجی HTML
در آخرین فاز، وردپرس قالب را رندر میکند:
include get_template_directory() . '/index.php';
اگر خطا در این فاز رخ دهد و خروجی قبلاً ارسال شده باشد، ممکن است بخشی از صفحه نمایش داده شود. اما اگر خطا پیش از ارسال هرگونه خروجی باشد، WSOD رخ میدهد. خطاهای این فاز شامل:
- فراخوانی تابع ناموجود در فایلهای قالب.
- مشکل در حلقه WordPress (The Loop).
- خرابی داده در دیتابیس که به خطا در پردازش منجر میشود.
- اتمام حافظه در رندر قالبهای سنگین.
دلایل اصلی WSOD در وردپرس
پس از آشنایی با فازهای وقوع، باید دلایل مشخص WSOD را بررسی کرد. در ادامه، پرتکرارترین دلایل با جزئیات فنی تحلیل میشود.
اتمام حافظه (Memory Exhaustion)
اتمام حافظه یکی از شایعترین دلایل WSOD است. PHP دارای محدودیت memory_limit است که معمولاً ۱۲۸ یا ۲۵۶ مگابایت است. اگر یک اسکریپت از این حد فراتر رود، PHP با خطای زیر متوقف میشود:
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 2097152 bytes) in /var/www/html/wp-includes/functions.php on line 1234
این خطا در افزونههای سنگین، قالبهای پیچیده یا در سایتهایی با محتوای حجیم شایع است. برای مطالعه بیشتر، مقاله خطای Memory Limit در وردپرس چیست و چطور رفع میشود؟ را ببینید.
تداخل افزونهها و بارگذاری ترتیبی
افزونهها بهترتیب حروف الفبا در فایل active_plugins بارگذاری میشوند. اگر دو افزونه تابع یا کلاسی با نام یکسان تعریف کنند، خطای زیر رخ میدهد:
Fatal error: Cannot redeclare function my_function() (previously declared in /path/to/plugin1.php:10) in /path/to/plugin2.php on line 20
این خطا شایعترین نوع تداخل افزونه است. برای رفع، باید افزونه مسئول شناسایی و غیرفعال شود. برای مطالعه بیشتر، مقاله رفع خطای تداخل افزونهها در وردپرس را ببینید.
خطای قالب و فایلهای ناقص
قالبها میتوانند در چند سطح WSOD ایجاد کنند:
- فایل ناقص: اگر یک فایل قالب (مانند
header.php) ناقص باشد، خطای پارس رخ میدهد. - تابع منسوخ: اگر قالب از تابعی استفاده کند که در نسخه جدید PHP حذف شده، خطای Fatal رخ میدهد.
- سینتکس نادرست: اگر ویرایشگر یا ابزاری فایل را خراب کند.
- ناسازگاری با نسخه وردپرس: پس از بروزرسانی هسته، قالب ممکن است با API جدید سازگار نباشد.
ناسازگاری با نسخه PHP
ارتقای نسخه PHP میتواند به WSOD منجر شود، بهویژه در ارتقا از PHP 7.x به PHP 8.x. دلایل:
- توابع حذفشده: مانند
create_function()که در PHP 8 حذف شده. - تغییر رفتار توابع: مانند
strlen(null)که در PHP 8 خطای TypeError میدهد. - دقت نوع: PHP 8 سختگیرانهتر در بررسی انواع است.
- خطاهای Deprecated تبدیل به Fatal: برخی خطاهای Deprecated در PHP 8 به Fatal تبدیل شدهاند.
خطای Cannot modify header information
خطای Cannot modify header information - headers already sent زمانی رخ میدهد که کدی سعی کند هدر HTTP ارسال کند، اما قبلاً خروجی HTML ارسال شده است. این خطا معمولاً بهدلیل فاصله، خط خالی یا کاراکتر BOM در ابتدای یک فایل PHP رخ میدهد:
Warning: Cannot modify header information - headers already sent by (output started at /path/to/file.php:1) in /path/to/functions.php on line 100
این خطا ممکن است به WSOD منجر شود اگر مانع ارسال هدرهای ضروری (مانند Location یا Content-Type) شود. برای مطالعه بیشتر، مقاله چگونه خطای Cannot modify header information را رفع کنیم؟ را ببینید.
مشکلات مجوز فایل و مالکیت
اگر PHP نتواند یک فایل را بخواند یا اجرا کند، خطای Fatal رخ میدهد:
Warning: require_once(/path/to/file.php): Failed to open stream: Permission denied
Fatal error: require_once(): Failed opening required '/path/to/file.php'
دلایل:
- مجوز فایل نادرست (مانند ۶۰۰ بهجای ۶۴۴).
- مالکیت اشتباه (کاربر FTP بهجای کاربر وب سرور).
- محدودیتهای SELinux یا AppArmor.
- پوشهای که برای PHP قابل نوشتن نیست.
برای مطالعه بیشتر، مقاله خطای دسترسی به فایلها در وردپرس را ببینید.
بروزرسانی نیمهکاره و فایلهای ناقص
اگر بروزرسانی وردپرس در میانه راه قطع شود، برخی فایلها نسخه جدید و برخی نسخه قدیمی خواهند بود. این ناهماهنگی میتواند به WSOD منجر شود. برای مطالعه بیشتر، مقاله بروزرسانی خودکار وردپرس چرا نیمهکاره میماند را ببینید.
کد سفارشی معیوب در functions.php
افزودن کد سفارشی به functions.php یکی از پرتکرارترین دلایل WSOD است. اشتباهات شایع:
- فراموش کردن
;یا}در انتهای یک خط. - تعریف تابعی که قبلاً تعریف شده.
- فراخوانی تابعی که وجود ندارد.
- استفاده از سینتکس نامناسب (مانند
?بهجای;).
خرابی دیتابیس و جداول
اگر جداول دیتابیس خراب شوند، وردپرس نمیتواند دادهها را بخواند و ممکن است با خطای Fatal متوقف شود:
WordPress database error Table './db/wp_options' is marked as crashed and should be repaired
این خطا معمولاً به خطای اتصال به دیتابیس منجر میشود، اما در برخی موارد میتواند WSOD ایجاد کند. برای مطالعه بیشتر، مقاله خطای اتصال به دیتابیس وردپرس را ببینید.
ابزارهای تشخیص سطح پایین
ریشهیابی WSOD نیازمند ابزارهای مناسب است. در ادامه، ابزارهای کلیدی بررسی میشود.
فعالسازی WP_DEBUG و WP_DEBUG_LOG
اولین گام، فعالسازی حالت دیباگ است. این کار باید در فایل wp-config.php انجام شود:
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);
define('SCRIPT_DEBUG', true);
@ini_set('display_errors', 0);
این تنظیمات، خطاها را در wp-content/debug.log ثبت میکند. پس از فعالسازی، سایت را بارگذاری کنید و لاگ را بررسی کنید:
tail -50 wp-content/debug.log
اگر خطای Fatal در لاگ ظاهر نشد، یعنی خطا پیش از فعال شدن WP_DEBUG رخ داده است. در این حالت، باید لاگ PHP را بررسی کرد.
تحلیل PHP error log و server log
لاگ PHP معمولاً در یکی از مسیرهای زیر است:
/var/log/php/error.log
/var/log/php-fpm/error.log
/var/log/apache2/error.log
/var/log/nginx/error.log
~/logs/error.log # در هاستهای اشتراکی
برای یافتن مسیر دقیق، از یک فایل PHP موقت استفاده کنید:
<?php phpinfo(); ?>
این فایل را در ریشه سایت قرار دهید، با مرورگر باز کنید و به دنبال error_log بگردید. پس از استفاده، فایل را حذف کنید.
پیکربندی error_log در php.ini
اگر مسیر لاگ مشخص نیست، میتوان آن را بهطور صریح تعیین کرد:
# در wp-config.php پیش از require_once ABSPATH . 'wp-settings.php';
@ini_set('log_errors', 1);
@ini_set('error_log', __DIR__ . '/php-error.log');
@ini_set('display_errors', 0);
این تنظیمات تضمین میکند که خطاها در فایل مشخصی ثبت میشوند، حتی اگر خطا در فاز Bootstrap رخ دهد.
Query Monitor و WP-CLI
افزونه Query Monitor یکی از بهترین ابزارهای دیباگ وردپرس است. این افزونه:
- خطاهای PHP را در رابط کاربری نمایش میدهد.
- کوئریهای کند را شناسایی میکند.
- هوکهای اجرا شده را لیست میکند.
- زمان اجرای هر بخش را اندازهگیری میکند.
WP-CLI نیز ابزار مفیدی برای بررسی وضعیت سایت از خط فرمان است:
wp core verify-checksums
wp plugin list
wp theme list
wp db check
برای مطالعه بیشتر، مقاله WP-CLI و مدیریت وردپرس از خط فرمان را ببینید.
ردیابی سطح سیستم با strace و Xdebug
در موارد پیچیده، میتوان از ابزارهای سطح سیستم استفاده کرد:
# ردیابی فراخوانیهای سیستم
strace -f -e trace=open,read,write php /var/www/html/index.php 2>&1 | tail -100
# با Xdebug
php -d xdebug.mode=trace -d xdebug.start_with_request=yes /var/www/html/index.php
این ابزارها نشان میدهند که کد در کدام نقطه متوقف شده و چه فایلی مشکل داشته است. Xdebug بهویژه برای ردیابی عمیق مفید است.
روششناسی جداسازی سیستماتیک
پس از فعالسازی ابزارهای تشخیص، باید مشکل را بهصورت سیستماتیک جداسازی کرد.
غیرفعالسازی افزونهها از فایلسیستم
اگر به پیشخوان دسترسی ندارید، باید افزونهها را از فایلسیستم غیرفعال کنید:
# تغییر نام پوشه افزونهها
mv wp-content/plugins wp-content/plugins.disabled
# ایجاد پوشه خالی جدید
mkdir wp-content/plugins
پس از این تغییر، اگر سایت باز شد، ریشه مشکل در افزونههاست. برای یافتن افزونه مسئول:
# بازگرداندن پوشه اصلی
mv wp-content/plugins.disabled/* wp-content/plugins/
# غیرفعالسازی تکتک افزونهها
mv wp-content/plugins/plugin1 wp-content/plugins/plugin1.disabled
# تست سایت
# اگر مشکل حل شد، plugin1 مسئول است
# در غیر این صورت، بازگردانی و ادامه با plugin2
تعویض قالب به قالب پیشفرض
برای رد کردن احتمال خطای قالب:
# تغییر نام پوشه قالب فعال
mv wp-content/themes/my-theme wp-content/themes/my-theme.disabled
وردپرس بهطور خودکار به قالب پیشفرض (مانند Twenty Twenty-Four) برمیگردد. اگر سایت باز شد، ریشه مشکل در قالب است.
یا از طریق دیتابیس:
UPDATE wp_options SET option_value = 'twentytwentyfour' WHERE option_name = 'template';
UPDATE wp_options SET option_value = 'twentytwentyfour' WHERE option_name = 'stylesheet';
روش جستجوی دودویی برای یافتن افزونه مسئول
در سایتهایی با دهها افزونه، روش دودویی سریعتر است:
- نیمی از افزونهها را غیرفعال کنید.
- سایت را تست کنید.
- اگر مشکل حل شد، ریشه در نیمه غیرفعال است. آن نیمه را نیمه کنید و ادامه دهید.
- اگر مشکل حل نشد، ریشه در نیمه فعال است. آن نیمه را نیمه کنید.
این روش با لگاریتم تعداد افزونهها، افزونه مسئول را پیدا میکند. مثلاً با ۶۴ افزونه، در ۶ مرحله میتوان به نتیجه رسید.
بازگردانی هسته به نسخه پیشین
اگر احتمال میدهید WSOD پس از بروزرسانی هسته رخ داده، میتوانید به نسخه پیشین بازگردید:
# دانلود نسخه قدیمی
wp core download --version=6.4.2 --force
# اجرای بروزرسانی دیتابیس
wp core update-db
این رویکرد موقتی است و باید پس از رفع مشکل، به نسخه جدید بروزرسانی شود.
راهکارهای رفع در سناریوهای مختلف
پس از ریشهیابی، باید مشکل را رفع کرد. راهکارها بسته به ریشه متفاوت هستند.
افزایش memory_limit
# در wp-config.php
define('WP_MEMORY_LIMIT', '512M');
define('WP_MAX_MEMORY_LIMIT', '512M');
# در .htaccess
php_value memory_limit 512M
# در php.ini
memory_limit = 512M
اگر مشکل از حافظه باشد، این تغییرات آن را رفع میکند. اما توجه داشته باشید که افزایش بیرویه حافظه، مشکل اصلی را پنهان میکند. بهتر است ریشه مصرف بالا نیز شناسایی شود.
غیرفعالسازی یا حذف افزونه مشکلساز
wp plugin deactivate problematic-plugin
wp plugin delete problematic-plugin
اگر افزونه ضروری است، باید با توسعهدهنده تماس گرفت یا نسخه جایگزین پیدا کرد.
بازگردانی قالب یا استفاده از Child Theme
اگر قالب مسئول است:
- قالب را به نسخه پیشین بازگردانید.
- اگر نسخه پیشین در دسترس نیست، از Child Theme استفاده کنید.
- در موارد اضطراری، به قالب پیشفرض سوئیچ کنید.
wp theme activate twentytwentyfour
رفع خطای headers already sent
این خطا معمولاً بهدلیل فاصله یا کاراکتر اضافی در ابتدای یک فایل PHP رخ میدهد. بررسی:
# یافتن فاصله یا خط خالی پیش از <?php
grep -rn "^[[:space:]]" wp-content/themes/my-theme/*.php
# یافتن کاراکتر BOM
find . -name "*.php" -exec file {} ; | grep BOM
پس از شناسایی، فایل مورد نظر را اصلاح کنید. ابزارهایی مانند dos2unix میتوانند BOM را حذف کنند:
dos2unix --remove-bom file.php
اصلاح مجوز فایل و مالکیت
# مالکیت صحیح
chown -R www-data:www-data /var/www/html
# مجوز پوشهها
find /var/www/html -type d -exec chmod 755 {} ;
# مجوز فایلها
find /var/www/html -type f -exec chmod 644 {} ;
بازیابی از نسخه پشتیبان
اگر هیچکدام از راهحلها جواب نداد، بازیابی از نسخه پشتیبان آخرین گزینه است:
wp db import backup.sql
tar -xzf backup-files.tar.gz -C /var/www/html/
برای مطالعه بیشتر، مقاله بازیابی سایت از بکاپ (Restore) چگونه انجام میشود؟ را ببینید.
استراتژی پیشگیری بلندمدت
پیشگیری همیشه آسانتر از درمان است. چند اصل کلیدی:
- محیط استیجینگ: هر تغییری ابتدا در استیجینگ تست شود.
- پشتیبان خودکار: از دیتابیس و فایلها بهطور روزانه.
- افزونههای فعال: فقط از افزونههایی که بهطور منظم بروزرسانی میشوند استفاده شود.
- قبل از بروزرسانی: از دیتابیس پشتیبان گرفته شود.
- پایش مستمر: لاگها و وضعیت سایت بهطور دورهای بررسی شوند.
- Child Theme: تغییرات سفارشی در Child Theme اعمال شوند.
- Static Analysis: کد سفارشی با ابزارهایی مانند PHP_CodeSniffer بررسی شود.
- WP_DEBUG_LOG: در محیط استیجینگ فعال باشد.
پرسشهای پرتکرار درباره صفحه سفید وردپرس
در این بخش، به پرسشهای متداول پاسخ داده میشود. این ساختار برای بهینهسازی محتوا برای موتورهای پاسخگو (Answer Engines) نیز مفید است.
صفحه سفید مرگ (WSOD) در وردپرس چیست؟
وضعیتی که در آن سایت هیچ محتوایی نمایش نمیدهد و فقط یک صفحه سفید باقی میماند. علت، خطای Fatal در PHP است که بهدلیل خاموش بودن display_errors نمایش داده نمیشود.
چگونه ریشه صفحه سفید را پیدا کنم؟
با فعالسازی WP_DEBUG و WP_DEBUG_LOG در wp-config.php و بررسی wp-content/debug.log. اگر خطا در لاگ نبود، لاگ PHP سرور را بررسی کنید.
آیا صفحه سفید بهدلیل هک شدن سایت است؟
معمولاً نه، اما در برخی موارد بله. اگر سایت بهطور ناگهانی سفید شده و هیچ تغییری اعمال نشده، احتمال هک وجود دارد. بررسی فایلهای هسته با wp core verify-checksums مفید است.
چگونه صفحه سفید را در حالت اضطراری رفع کنم؟
ابتدا افزونهها را از فایلسیستم غیرفعال کنید (با تغییر نام پوشه plugins). اگر سایت باز شد، افزونه مسئول را با روش دودویی پیدا کنید. اگر باز نشد، قالب را تعویض کنید.
آیا افزایش memory_limit همیشه صفحه سفید را رفع میکند؟
فقط در مواردی که ریشه، اتمام حافظه باشد. اگر ریشه در جای دیگری باشد، افزایش حافظه مشکل را پنهان میکند بدون آنکه رفع شود.
تفاوت WSOD با خطای ۵۰۰ چیست؟
خطای ۵۰۰ یک کد وضعیت HTTP است که سرور در پاسخ به خطا برمیگرداند. WSOD یک وضعیت ظاهری است که مرورگر نمایش میدهد. WSOD معمولاً همراه با کد ۵۰۰ رخ میدهد، اما نه همیشه.
چگونه از صفحه سفید جلوگیری کنم؟
با استفاده از محیط استیجینگ، پشتیبان خودکار، افزونههای معتبر، بروزرسانی تدریجی، و پایش مستمر لاگها.
آیا افزونهها میتوانند باعث صفحه سفید شوند؟
بله، این شایعترین دلیل است. افزونههایی که تابع یا کلاسی با نام تکراری تعریف میکنند، یا از توابع منسوخ استفاده میکنند، میتوانند WSOD ایجاد کنند.
آیا تغییر قالب میتواند صفحه سفید را رفع کند؟
اگر ریشه در قالب باشد، بله. با تعویض قالب به Twenty Twenty-Four، میتوان تشخیص داد که آیا مشکل از قالب است یا افزونه.
آیا فایل wp-config.php میتواند باعث صفحه سفید شود؟
بله. خطای پارس، کاراکتر اضافی، یا مقدار اشتباه در wp-config.php میتواند WSOD ایجاد کند. این خطا در فاز Bootstrap رخ میدهد و در debug.log وردپرس ثبت نمیشود.
چگونه بفهمم مشکل از PHP است یا MySQL؟
با بررسی پیام خطا. خطای MySQL معمولاً با پیام «Error establishing a database connection» همراه است. WSOD معمولاً به خطای PHP اشاره دارد.
آیا صفحه سفید میتواند خودبهخود رفع شود؟
بهندرت. اگر ریشه در یک افزونه باشد که بهطور خودکار بروزرسانی شده، ممکن است پس از بروزرسانی بعدی رفع شود. اما در اکثر موارد، نیازمند مداخله دستی است.
نکات پیشرفته برای مهندسان ارشد
برای مهندسان ارشد و تیمهای DevOps، WSOD یک مسئله چندلایه است. در ادامه، به نکات پیشرفتهای میپردازیم که در پروژههای بزرگ حیاتی میشوند.
پیکربندی error handler سفارشی
در پروژههای حرفهای، میتوان یک error handler سفارشی نصب کرد که خطاها را با جزئیات بیشتر ثبت کند:
set_error_handler(function($errno, $errstr, $errfile, $errline) {
$log = sprintf(
"[%s] Error %d: %s in %s on line %d
Stack trace:
%s
",
date('Y-m-d H:i:s'),
$errno,
$errstr,
$errfile,
$errline,
(new Exception())->getTraceAsString()
);
error_log($log);
if ($errno === E_USER_ERROR) {
exit(1);
}
});
register_shutdown_function(function() {
$error = error_get_last();
if ($error && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR], true)) {
error_log(sprintf(
"FATAL: %s in %s on line %d
",
$error['message'],
$error['file'],
$error['line']
));
}
});
این کد، خطاهای Fatal را حتی در فاز Bootstrap ثبت میکند و stack trace کامل ارائه میدهد.
مقایسه رفتار PHP در نسخههای مختلف
| ویژگی | PHP 7.4 | PHP 8.0 | PHP 8.2 |
|---|---|---|---|
| create_function() | منسوخ | حذفشده | حذفشده |
| each() | منسوخ | حذفشده | حذفشده |
| strlen(null) | بازگشت 0 | TypeError | Deprecated |
| Dynamic properties | مجاز | مجاز | Deprecated |
| Undefined array key | Notice | Warning | Warning |
این تغییرات نشان میدهد که کد قدیمی ممکن است در PHP 8 خطای Fatal بدهد، در حالی که در PHP 7.4 فقط Notice میداد.
Autoloader و خطاهای بارگذاری کلاس
در پروژههایی که از Composer استفاده میکنند، خطای autoload میتواند WSOD ایجاد کند:
Fatal error: Uncaught Error: Class "MyCompany\MyClass" not found in /path/to/file.php:10
راهحل، اجرای مجدد composer dump-autoload یا بررسی نقشه autoload است:
composer dump-autoload --optimize --no-dev
برای مطالعه بیشتر درباره Composer، مقاله Composer برای مدیریت وابستگی وردپرس را ببینید.
پایش خطاهای Fatal با Sentry
سرویس Sentry میتواند خطاهای Fatal را در لحظه ثبت کند:
\Sentry\init([
'dsn' => 'https://...',
'error_types' => E_ALL,
'before_send' => function(\Sentry\Event $event) {
if ($event->getLevel() === 'fatal') {
error_log('Fatal error captured by Sentry');
}
return $event;
},
]);
set_exception_handler(function($exception) {
\Sentry\captureException($exception);
exit(1);
});
برای مطالعه بیشتر، مقاله Sentry Performance برای وردپرس چطور کار میکند؟ را ببینید.
مقایسه استراتژیهای جداسازی
| روش | سرعت | دقت | مناسب برای |
|---|---|---|---|
| WP_DEBUG | سریع | بالا | همه موارد |
| غیرفعالسازی افزونهها | متوسط | بالا | افزونههای محدود |
| روش دودویی | سریع | بالا | افزونههای زیاد |
| تعویض قالب | سریع | بالا | احتمال مشکل قالب |
| WP-CLI | سریع | بالا | همه موارد |
| Xdebug | کند | بسیار بالا | مسائل پیچیده |
Atomic Deployment و بازگشت سریع
در معماریهای مدرن، استفاده از symlink-based deployment امکان بازگشت سریع را فراهم میکند:
# ساختار پوشه
/var/www/releases/20250101_120000/
/var/www/releases/20250101_150000/
/var/www/html -> /var/www/releases/20250101_120000/
# بازگشت سریع به نسخه قبلی
ln -sfn /var/www/releases/20250101_120000 /var/www/html
این رویکرد، زمان بازیابی از چند دقیقه به چند ثانیه کاهش میدهد. برای مطالعه بیشتر درباره CI/CD، مقاله CI/CD برای پروژههای وردپرسی را ببینید.
نکات کلیدی برای پایداری بلندمدت
در پایان، چند نکته کلیدی که باید در خاطر بماند:
- WP_DEBUG_LOG را در استیجینگ فعال نگه دارید: خطاها را قبل از تولید شناسایی کنید.
- error handler سفارشی نصب کنید: برای ثبت خطاهای Bootstrap.
- Child Theme استفاده کنید: تغییرات سفارشی در قالب اصلی اعمال نشود.
- محیط استیجینگ داشته باشید: هر تغییری ابتدا در استیجینگ تست شود.
- پشتیبان خودکار روزانه: از دیتابیس و فایلها.
- افزونههای معتبر: فقط از منابع رسمی نصب شوند.
- Composer برای مدیریت وابستگی: نسخهها دقیقاً مشخص شوند.
- Static Analysis در CI: خطاها قبل از استقرار شناسایی شوند.
- Sentry برای پایش: خطاهای Fatal در لحظه ثبت شوند.
- Atomic Deployment: بازگشت سریع در صورت خطا.
- پایش مستمر: لاگها و معیارها بهطور دورهای بررسی شوند.
- آموزش تیم: همه اعضا با فرآیند ریشهیابی آشنا باشند.
اگر در پروژههای خود با صفحه سفید مرگ مواجه شدهاید، جالب است بدانم کدام ریشه بیشترین زمان را از شما گرفت. تجربه خودتان را در دیدگاهها بنویسید؛ بهخصوص اگر راهحل خلاقانهای برای ریشهیابی سریع پیدا کردهاید که میتواند برای دیگران مفید باشد.