راهنمای جامع رفع خطاهای رایج وردپرس
راهنمای عملی عیبیابی خطاهای رایج وردپرس؛ از صفحه سفید و خطای ۵۰۰ تا تعارض افزونه و خطای دیتابیس، با روش ششگامی و پیشگیری.
هر سایتی که با وردپرس کار میکند، دیر یا زود با خطا مواجه میشود؛ این را با اطمینان میگویم چون در سالها کار حرفهای روی پروژههای وردپرسی، تقریباً هیچ سایتی را ندیدهام که ماهها بدون خطا کار کند. تفاوت سایت حرفهای با سایت آماتور در «نداشتن خطا» نیست؛ در «سرعت تشخیص و رفعِ امنِ خطا» است. کسی که میداند وقتی صفحه سفید شد اول کجا را نگاه کند، ده دقیقهای مسئله را حل میکند؛ کسی که نمیداند، ممکن است با یک تصمیم شتابزده، دیتابیس را هم از دست بدهد.
در این راهنما، همان الگویی را که در پروژههای واقعی برای عیبیابی استفاده میکنم، گامبهگام باز میکنم. فرض این است که با وردپرس و ساختار پایهاش آشنایی دارید؛ اگر تازهکار هستید، اول آن مقاله را بخوانید و بعد به سراغ خطاها بیایید.
چرا وردپرس خطا میدهد؟
وردپرس یک سیستم لایهای است: هسته، قالب، افزونهها، سرور، دیتابیس و نسخهٔ PHP. خطا زمانی رخ میدهد که یکی از این لایهها از انتظار لایهٔ دیگر خارج شود. تجربهام میگوید بیش از هشتاد درصد خطاهای وردپرسی در سه دسته خلاصه میشوند: تعارض افزونه، ناسازگاری با نسخهٔ PHP، و مشکل سرور یا دیتابیس. باقی موارد معمولاً به کد سفارشی یا قالب برمیگردد.
نکتهای که خیلی از تازهکارها نمیدانند: علامت و علت متفاوتاند. آنچه کاربر روی صفحه میبیند (صفحه سفید، خطای ۵۰۰) علامت است؛ علت واقعی معمولاً در لاگ سرور یا wp-content/debug.log نوشته شده. اگر بتوانید بین «علامت» و «علت» تمایز بگذارید، سرعت عیبیابیتان چند برابر میشود. برای درک لایهای که هر افزونه در آن قرار میگیرد، افزونه وردپرس چیست را از ابتدا مرور کنید؛ همان ساختار، کلید فهم بیشتر خطاهاست.
در وردپرس، خطا معمولاً از جایی میآید که آخرین بار به آن دست زدهاید؛ اگر مطمئن نیستید کجا بوده، آخرین تغییر مهم را در ذهن مرور کنید.
روش عیبیابی: شش گام
قبل از ورود به هر خطای خاص، این چارچوب را بپذیرید. من در هر پروژه از همین شش گام استفاده میکنم و چون ذهنم روی چارچوب ثابت است، وقت کمتری را صرف حدسزدن میکنم:
- علامت (Symptom): دقیقاً چه چیزی میبینید؟ متن خطا، صفحه سفید، ریدایرکت، پیام مرورگر.
- علت ریشهای (Root Cause): چه چیزی باعث شد؟ نسخهٔ PHP، افزونه، قالب، دیتابیس، سرور.
- تشخیص (Diagnosis): با کدام آزمون میتوانید علت را تأیید یا رد کنید؟
- رفع (Fix): حداقلیترین اقدام امن که مسئله را حل کند.
- راستیآزمایی (Verification): چطور مطمئن شوید حل شده و مسئله برنمیگردد؟
- پیشگیری (Prevention): چه تغییری در روند کار یا تنظیمات جلوی تکرار را میگیرد؟
اگر این چارچوب را حفظ کنید، حتی خطایی که تا حالا ندیدهاید هم به مسئلهای قابل مدیریت تبدیل میشود. حالا برویم سراغ خودِ خطاها.
صفحه سفید (White Screen of Death)
شناختهشدهترین خطای وردپرس: صفحه کاملاً سفید بالا میآید، نه متن خطایی نشان داده میشود نه چیزی در view source. علت اصلی، خطای Fatal در PHP است که بهخاطر تنظیمات display_errors پنهان شده. تجربهام میگوید در بیش از نیمی از موارد، مقصر یک افزونه یا خطای Parse در functions.php است.
تشخیص: از طریق FTP یا File Manager، نام پوشهٔ wp-content/plugins را به plugins-off تغییر دهید. اگر سایت برگشت، مقصر یک افزونه است. سپس نام را برگردانید و افزونهها را یکییکی از پیشخوان فعال کنید تا مقصر پیدا شود.
رفع: اگر مقصر افزونه بود، همان را حذف یا جایگزین کنید. اگر مقصر قالب بود، با تغییر نام پوشهٔ قالب فعال به یک قالب پیشفرض مثل Twenty Twenty-Four سوئیچ کنید. اگر هیچکدام نبود، به سراغ فایل functions.php بروید و آخرین کد اضافهشده را برگردانید.
راستیآزمایی: بعد از هر تغییر، صفحه را در مرورگر ناشناس ریلود کنید (کش مرورگر را دور بزنید) و لاگ سرور را هم چک کنید.
پیشگیری: از این به بعد قبل از هر تغییر در فایلهای قالب، چایلد تم بسازید تا هستهٔ قالب دستنخورده بماند.
خطای ۵۰۰ داخلی سرور
خطای ۵۰۰ معمولاً پیام واضحی در front-end نشان نمیدهد و فقط میگوید «Internal Server Error». برخلاف صفحه سفید که صرفاً PHP است، ۵۰۰ میتواند از لایههای سرور هم بیاید: فایل .htaccess خراب، مجوز فایل اشتباه، یا حافظهٔ سرور پر شده.
تشخیص ترتیبی: اول فایل .htaccess را از ریشهٔ سایت دانلود و پاک کنید (وردپرس آن را در صورت نیاز بازمیسازد). اگر سایت بالا آمد، مقصر همان فایل بوده. اگر نه، به سراغ لاگ سرور در cPanel یا DirectAdmin بروید و آخرین خطای PHP را پیدا کنید. اگر لاگ در دسترس نیست، WP_DEBUG را در wp-config.php روشن کنید.
رفع: در بیشتر موارد، خطای ۵۰۰ با یکی از این سه راه حل میشود: بازگرداندن .htaccess پیشفرض، افزایش memory_limit در php.ini، یا رفع خطای Parse در یک افزونه. اگر خطا در زمان آپلود تصویر یا فایل رخ میدهد، احتمالاً مجوز پوشهٔ wp-content/uploads اشتباه است (باید 755 برای پوشهها و 644 برای فایلها).
خطای اتصال به دیتابیس
پیام «Error establishing a database connection» یعنی وردپرس نمیتواند به MySQL وصل شود. سه علت اصلی دارد: اطلاعات ورود در wp-config.php اشتباه شده، سرور دیتابیس خوابیده، یا دیتابیس توسط هاست بسته شده (مثلاً بهخاطر مصرف منابع).
تشخیص: اول از cPanel یا phpMyAdmin چک کنید دیتابیس و کاربر دیتابیس وجود دارند و کاربر به دیتابیس متصل است. بعد فایل wp-config.php را باز کنید و مقادیر DB_NAME، DB_USER، DB_PASSWORD و DB_HOST را با اطلاعات پنل هاست تطبیق دهید. اگر همه درست بود، از هاست بپرسید آیا سرور MySQL مشکل دارد یا دیتابیستان بهخاطر مصرف CPU تعلیق شده.
نکتهٔ مهم: اگر با تغییری که خودتان اعمال کردهاید این خطا ظاهر شده (مثل مهاجرت به هاست جدید)، پیش از هر کاری از دیتابیس فعلی بکاپ بگیرید. راهنمای کاملش در چگونه از سایت وردپرسی بکاپ بگیریم آمده.
خطای Memory Limit
خطای «Allowed memory size exhausted» یعنی PHP به سقف حافظهٔ اختصاصی رسیده. این خطا بیشتر در پیشخوان، هنگام ذخیرهٔ نوشتههای بزرگ، آپلود تصاویر با ابعاد بالا، یا اجرای افزونههای سنگین مثل بکاپگیر رخ میدهد.
رفع امن: ابتدا از هاست بخواهید مقدار memory_limit را به حداقل 256M افزایش دهد. اگر دسترسی به php.ini دارید، مقدار را آنجا تغییر دهید. اگر ندارید، در wp-config.php پیش از خط /* That's all, stop editing! */ این خط را اضافه کنید:
define( 'WP_MEMORY_LIMIT', '256M' );
define( 'WP_MAX_MEMORY_LIMIT', '512M' );
اما این راهحل، علامت را میپوشاند نه علت را. اگر روی هاست اشتراکی با منابع محدود هستید، افزایش حافظه ممکن است فقط تا زمان مصرف بعدی جواب بدهد. راهکار بلندمدت، انتقال به هاست با منابع بیشتر یا بهینهسازی افزونههای سنگین است. برای درک اینکه چرا افزونهها حافظه را میخورند، تأثیر افزونهها بر سرعت سایت را بخوانید.
خطای Parse error در functions.php
یادم میآید یک بار نصف شب از مشتری پیامی گرفتم که «سایت بعد از یک ویرایش کوچک سفید شد». علت، یک ; گمشده در آخر یک تابع در functions.php بود. خطای Parse PHP معمولاً با جزئیات مفید ظاهر میشود:
Parse error: syntax error, unexpected 'end of file' in .../functions.php on line 245
رفع امن: اگر ویرایشگر آنلاین قالب (Appearance ← Theme File Editor) را باز میکنید و سایت قفل شد، اول از طریق FTP به فایل دسترسی بگیرید. اگر از چایلد تم استفاده نمیکردید، این لحظه دقیقاً همان لحظهای است که دردش را میفهمید. اگر نمیتوانید خط را پیدا کنید، از نسخهٔ سالم قبلی فایل بازگردانی کنید. یک روش سادهٔ تست: خطی که احتمال میدهید مشکل دارد را با // کامنت کنید و ریلود کنید؛ اگر خطا رفت، مقصر همان خط بوده.
هیچوقت کد را مستقیم در فایل قالب والد ویرایش نکنید. اگر این کار را کردهاید، همین امروز به چایلد تم منتقلش کنید.
تعارض افزونهها
بزرگترین دستهٔ خطاهای وردپرسی. دو افزونه که هرکدام جدا سالماند، ممکن است وقتی با هم کار میکنند یکی از این علائم را بسازند: صفحه سفید، بخشی از صفحه غیب شود، فرمها کار نکنند، سرعت بیدلیل افت کند، یا متاباکسها از پیشخوان حذف شوند.
روش تشخیص قطعی: همهٔ افزونهها را غیرفعال کنید (از پیشخوان یا با تغییر نام پوشه). سایت را ریلود کنید. اگر سالم بود، افزونهها را دستهای فعال کنید و بعد از هر دسته، سایت را تست کنید. دستهای که مشکل را برگرداند، مقصر است. سپس در همان دسته، تکتک افزونهها را فعال کنید تا مقصر نهایی مشخص شود.
رفع: سه گزینه دارید: بهروزرسانی افزونه (ممکن است در نسخهٔ جدید رفع شده باشد)، جایگزینی با افزونهای دیگر، یا حذف افزونهٔ کماهمیتتر. اگر افزونهٔ کلیدی است و باید بماند، با توسعهدهنده تماس بگیرید و تعارض را گزارش دهید.
نکتهٔ بلندمدت: تعداد افزونههای فعال را کم نگه دارید. هر افزونهٔ اضافی، یک احتمال تعارض جدید است. برای اینکه بدانید چرا برخی افزونهها سایت را کند میکنند بدون اینکه خطا بدهند، تأثیر افزونهها بر سرعت سایت را از دست ندهید.
تعارض و خرابی قالب
قالبها هم میتوانند عامل خطا باشند. شایعترین سناریوها: آپدیت قالب با کد سفارشی شما تعارض پیدا کرده؛ قالب با نسخهٔ جدید PHP یا وردپرس سازگار نیست؛ یا فایلهای قالب ناقص آپلود شدهاند. پیامهایی مثل «The package could not be installed. The theme is missing the style.css stylesheet» نشانهٔ آخرین مورد است.
تشخیص: یک قالب پیشفرض (مثل Twenty Twenty-Four) را موقتاً فعال کنید. اگر خطا رفت، مقصر قالب فعلی بوده. اگر ماند، به سراغ افزونهها یا هسته بروید.
رفع: اگر قالب اصلی مشکل دارد، نسخهٔ قبلی را از بکاپ بازگردانید. اگر قالب سفارشی است و خطا در functions.php، از طریق FTP دسترسی بگیرید. اگر خطا بعد از تعویض قالب ظاهر شد، احتمالاً سفارشیسازیهای قبلی از بین رفتهاند — مقالهٔ تغییر امن قالب وردپرس همین سناریو را مرحلهبهمرحله پوشش میدهد.
یک نکتهٔ مهم دیگر: قالبهای قدیمی که با استانداردهای مدرن وردپرس ساخته نشدهاند، گاهی کد ناامن یا کند تولید میکنند. راهنمای تشخیص قالب استاندارد معیارهای قابلسنجش را دارد. اگر قالب فعلیتان کند و مشکلساز است، چرا بعضی قالبها سایت را کند میکنند راهنمای تشخیص ریشهای است.
خطای ۴۰۴ و حلقه ریدایرکت
خطای ۴۰۴ در وردپرس دو گونه است: یا یک صفحهٔ خاص پیدا نمیشود (که با ریدایرکت درست میشود)، یا کل سایت ۴۰۴ میدهد (که معمولاً بهخاطر بازنویسی پیوندهای یکتا یا فایل .htaccess است). حلقهٔ ریدایرکت هم معمولاً نتیجهٔ تنظیمات اشتباه HTTPS، افزونههای ریدایرکت متناقض، یا siteurl نادرست در دیتابیس است.
تشخیص: برای ۴۰۴ کل سایت: در پیشخوان به «تنظیمات ← پیوندهای یکتا» بروید و بدون تغییر، ذخیره کنید. این کار فایل .htaccess را بازنویسی میکند و در بیش از نیمی از موارد، ۴۰۴ سراسری را حل میکند. برای حلقه ریدایرکت: افزونههای ریدایرکت را غیرفعال کنید و یکبار سایت را تست کنید. اگر حل شد، یک ریدایرکت متناقض داشتهاید. اگر ماند، مقدار siteurl و home را در جدول wp_options چک کنید.
رفع بلندمدت: برای مدیریت ریدایرکتهای ۳۰۱، از یک افزونهٔ معتبر استفاده کنید و قبل از هر تغییر ساختار URL، نقشهٔ ریدایرکتها را آماده کنید. این موضوع در سئو تکنیکال با جزئیات باز شده است.
خطای SSL و HTTPS
خطای «Your connection is not private» یا وجود محتوای ترکیبی (Mixed Content) یعنی مرورگر نمیتواند ارتباط امن را تأیید کند. سه علت اصلی: گواهی SSL منقضی شده، لینکهای داخلی سایت هنوز http:// هستند، یا سرور در سرو گواهی مشکل دارد.
رفع: در cPanel تاریخ انقضای گواهی را چک کنید و در صورت لزوم تمدید یا گواهی جدید نصب کنید. اگر گواهی سالم است ولی محتوای ترکیبی دارید، از یک افزونهٔ ریدایرکت یا افزونهٔ «SSL Insecure Content Fixer» برای جایگزینی خودکار لینکهای http با https استفاده کنید. بعد از رفع، سایت را با ابزارهایی مثل Why No Padlock تست کنید تا هیچ منبع ناامنی نمانده باشد.
WP_DEBUG و ابزارهای عیبیابی
اگر قرار است یک عادت را از این مقاله با خودتان ببرید، این است: قبل از هر عیبیابی، لاگ را روشن کنید. در wp-config.php این خطوط را اضافه کنید:
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );
define( 'SCRIPT_DEBUG', true );
با این تنظیمات، خطاها در فایل wp-content/debug.log نوشته میشوند و روی صفحه نمایش داده نمیشوند (امن برای سایت زنده). بعد از عیبیابی، WP_DEBUG را حتماً خاموش کنید — روشن ماندن آن روی سایت زنده، هم کارایی را کم میکند هم اطلاعات حساس را لو میدهد.
ابزارهای مکمل که در پروژهها استفاده میکنم: افزونهٔ Query Monitor برای دیدن کوئریهای کند و خطاهای PHP؛ افزونهٔ Health Check برای تشخیص تعارض در حالت ایزوله (بدون اثر روی کاربران واقعی)؛ و ابزار curl یا httpie برای تست سریع هدرهای HTTP از خط فرمان.
یک جدول کوچک برای تشخیص سریع که همیشه همراهم است:
| علامت | علت احتمالی اول | اولین قدم |
|---|---|---|
| صفحه سفید | خطای Fatal در افزونه یا functions.php | غیرفعالسازی افزونهها |
| خطای ۵۰۰ | htaccess خراب یا حافظه پر | حذف .htaccess |
| Database connection | اطلاعات wp-config یا سرور DB | چک پنل هاست |
| Memory exhausted | افزونه سنگین یا محتوای بزرگ | افزایش memory_limit |
| حلقه ریدایرکت | تنظیمات HTTPS یا افزونه ریدایرکت | غیرفعالسازی افزونه ریدایرکت |
ایمنی پیش از عیبیابی
قبل از هر تغییر مهم روی سایت زنده، این سه کار را انجام دهید وگرنه ریسک فاجعه دارید:
- بکاپ کامل (فایل + دیتابیس) و ذخیره در بیرون هاست. بکاپی که تست بازگردانی نشده باشد، بکاپ نیست. مسیر امن در چگونه از سایت وردپرسی بکاپ بگیریم قدمبهقدم آمده است.
- محیط استیجینگ برای تست. اگر هاست شما استیجینگ ندارد، از یک نصب لوکال استفاده کنید.
- حالت تعمیرات در وردپرس، اگر ممکن است خرابی موقت روی سایت زنده اعمال شود.
یک جملهٔ صادقانه: در پروژههایی که کارفرما اصرار داشت «همین الان روی سایت زنده درستش کن»، در نیمی از موارد اوضاع بدتر شد. عیبیابی روی زنده، شبیه جراحی در خیابان است؛ اگر مجبورید، فقط بهشرط تجهیزات کامل انجامش دهید.
عیبیابی خوب، عیبیابی سریع نیست؛ عیبیابی بدون برگشتِ مسئله است.
اشتباهات رایج در عیبیابی
| اشتباه | چرا بد است | جایگزین درست |
|---|---|---|
| ویرایش مستقیم فایلهای قالب والد | با آپدیت قالب از بین میرود | استفاده از چایلد تم |
| خاموشکردن نمایش خطاها بدون لاگ | علت را پنهان میکند | فعالسازی WP_DEBUG_LOG |
| حذف بیمطالعهٔ افزونهها | دادهها و تنظیمات از دست میرود | غیرفعالسازی قبل از حذف |
| عیبیابی روی سایت زنده بدون بکاپ | یک اشتباه میتواند سایت را نابود کند | استیجینگ یا بکاپ کامل |
| حدس زدن علت بدون خواندن لاگ | وقتگیر و کمدقت | شروع از لاگ، نه از حدس |
یک اشتباه ظریف دیگر که زیاد دیدهام: بعد از هر بار «رفع»، کاربر صفحه را در همان مرورگر باز میکند و چون کش مرورگر پاک نشده، تصور میکند مشکل رفع نشده. همیشه سایت را در حالت ناشناس یا با Ctrl+Shift+R تست کنید. اگر سایتتان روی CDN هم هست، کش CDN را هم باید پاک کنید. حجم زیاد مشکلاتی که بهعنوان «باگ» گزارش میشود، در واقع فقط کش کهنه است.
و آخرین توصیه: اگر خطا در زمان اوج ترافیک رخ داد و سایت خوابید، قبل از هر کار، افزونههای امنیتی خود را چک کنید. بعضی مواقع «خطا» در واقع حمله یا تلاش نفوذ است، نه باگ. اگر لاگ سرور پر از درخواستهای مشکوک از IPهای متعدد بود، وارد مسیر دیگری شدهاید که رفع خطا در آن، بخشی از پاسخ به یک حمله است.
دیدگاه مهندسی پیشرفته
برای مهندسینی که با وردپرس بهعنوان یک پلتفرم تولیدی کار میکنند، خطا نباید یک رویداد باشد؛ باید یک سیگنال در سیستمِ مشاهدهپذیری. سه اصل که در پروژههای بزرگ رعایت میکنم:
یک — خطا را در لبه بگیر، نه در هسته. بهجای اینکه بگذارید یک خطای PHP در functions.php کل سایت را در زمان رندر بترکاند، لایهٔ mu-plugins داشته باشید که با set_error_handler و set_exception_handler خطاهای کشنده را در یک فایل لاگ ساختیافته (مثلاً JSON با timestamp، request-id و URL) بنویسد. این کار در محیطهای multi-tenant حیاتی است؛ چون یک افزونهٔ بدرفتار نباید تجربهٔ کل سایت را خراب کند.
دو — تولید را از تجربه جدا کن. در معماری مدرن، نباید «نمایش خطا به کاربر» و «ثبت خطا برای توسعهدهنده» بههم گره بخورند. WP_DEBUG_DISPLAY باید همیشه در تولید false باشد؛ خطا در لاگ مینشیند، به کاربر پیام ژنریک نشان داده میشود، و پایش بیرونی (مثل Sentry یا New Relic) روی همان لاگ سوار میشود. این تفکیک، امنیت را هم بالا میبرد: هیچ مسیر کد اطلاعات حساس را در پاسخ HTTP لو نمیدهد.
سه — شکست را پیشبینی کن، نه فقط رفع. مفهوم «Chaos Engineering» که در سیستمهای توزیعشده جا افتاده، در وردپرس هم قابل استفاده است: در استیجینگ، عمداً یک افزونه را غیرفعال کنید، سقف حافظه را نصف کنید، یا تأخیر شبکه را شبیهسازی کنید و ببینید سایت چطور رفتار میکند. سایتی که «توسط تیم فنی سالم به نظر میرسد» با سایتی که «در برابر شکست لایهای مقاوم است» دو چیز متفاوتاند. تجربهام میگوید هر ماه یک ساعت صرف این تمرین، در بلندمدت بیشتر از هر بکاپی سایت را نجات میدهد.
از منظر معماری، عمیقترین درس این است: وردپرس، در ذات خود یک برنامهٔ تکپردازشی است که در محیطی اشتراکی اجرا میشود. هر خطا، در واقع یک «انحراف از قرارداد» است بین آنچه هستهٔ وردپرس فرض کرده و آنچه افزونه یا کد شما فرض کرده. تشخیص درست، پیدا کردن همان قراردادِ شکسته است — نه فقط حذف علامت. مهندسینی که این نگاه را داشته باشند، بهجای «افزونهای که خطا میدهد»، «افزونهای که قرارداد X را نقض میکند» میبینند و آنوقت رفع، هدفمند و پایدار میشود.
جمعبندی
خطاهای وردپرس ترسناک نیستند اگر با روش سراغشان بروید: علامت را از علت جدا کنید، لاگ را روشن کنید، بکاپ داشته باشید، و در یک محیط جدا تست کنید. بیشتر خطاهایی که در نگاه اول «عجیب» به نظر میرسند، در یکی از این پنج دسته مینشینند: تعارض افزونه، ناسازگاری قالب، نسخهٔ PHP، محدودیت سرور، یا خطای پیکربندی دیتابیس. وقتی این طبقهبندی را در ذهن داشته باشید، هیچ خطایی شما را غافلگیر نمیکند.
اگر مسیر مطالعه را ادامه میدهید، بعد از این مقاله دو گام منطقی دارید: اول درک ریشهای سرعت سایت (چون نیمی از «کندیها» هم خودشان نوعی خطا هستند و در افزایش سرعت وردپرس توضیح دادهام)، دوم شناخت Core Web Vitals که در سایتهای درستکار، معیار دائمی کیفیت است — Core Web Vitals چیست دقیقاً همان بحث است. اگر مسئلهتان سرعت نبود بلکه هاست کند بود، هاست چیست و چگونه انتخابش کنیم نقطهٔ شروع درست است.
اگر خطای عجیبی را پشت سر گذاشتهاید که در هیچکدام از دستههای این مقاله جا نمیگیرد، برای من جالب است بدانم چه بود و چطور پیدایش کردید. تجربهتان را در دیدگاهها بنویسید — بهخصوص اگر مسیر تشخیصی متفاوتی رفتهاید؛ همان جزئیات، برای خوانندهی بعدی که همان خطا را گرفته، از هر راهنمای عمومی ارزشمندتر است. 🔧