Menu

הצגת שגיאות ב-PHP: display_errors ו-E_ALL

כדי להציג את כל שגיאות PHP, שימו ini_set('display_errors', '1'); ו-error_reporting(E_ALL); בראש הסקריפט, או הגדירו display_errors = On ו-error_reporting = E_ALL ב-php.ini. בסביבת ייצור, רשמו שגיאות ללוג במקום להציג אותן.

בדף הזה יש עורכים שאפשר להריץ - לערוך, להריץ ולראות את הפלט מיד.

כדי להציג שגיאות PHP, שימו את השורות האלה בראש הסקריפט: ini_set('display_errors', '1'); ו-error_reporting(E_ALL);. הראשונה גורמת ל-PHP להדפיס הודעות שגיאה, והשנייה גורמת לה לדווח על כל סוג של שגיאה, כולל אזהרות והודעות deprecation.

<?php
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
error_reporting(E_ALL);

כשזה במקום, טעות כמו קריאת משתנה שלא הוגדר מעולם מדפיסה הודעה עם הקובץ ומספר השורה במקום להיכשל בשקט:

Warning: Undefined variable $total in /home/index.php on line 7

error_reporting() שנקראת בלי ארגומנט מחזירה את ההגדרה הנוכחית כמספר. לחצו על Run כדי לקבוע רמה ולפענח אותה בחזרה לשמות:

כל סוג שגיאה הוא ביט אחד, ולכן E_ALL & ~E_DEPRECATED פירושו "הכול חוץ מ-deprecations". שנו את השורה הראשונה ל-error_reporting(E_ERROR | E_WARNING); והריצו שוב.

הצגת שגיאות ב-php.ini

הגדרה בתוך הסקריפט חלה רק אחרי שהסקריפט מתחיל לרוץ. כדי להציג שגיאות בכל סקריפט, כולל שגיאות תחביר, שנו את php.ini (מצאו אותו עם php --ini):

; Development
display_errors = On
display_startup_errors = On
error_reporting = E_ALL

הפעילו מחדש את Apache או את PHP-FPM אחרי העריכה. השרת המובנה php -S ושורת הפקודה קוראים את הקובץ בכל הפעלה. באחסון משותף בלי גישה ל-php.ini, Apache עם mod_php מקבל גם שורות ב-.htaccess:

php_flag display_errors on
php_value error_reporting -1

-1 מדליק את כל הביטים, וזה אותו דבר כמו E_ALL.

רמות השגיאה

קבועמה מפעיל אותועוצר את הסקריפט
E_ERRORשגיאת זמן ריצה פטאלית, כמו חוסר בזיכרוןכן
E_PARSEשגיאת תחביר בקובץכן
E_WARNINGמשתנה או מפתח מערך לא מוגדרים, קובץ חסר ב-includeלא
E_NOTICEבעיות קטנות (מעטות נשארו ב-PHP 8)לא
E_DEPRECATEDקוד שגרסת PHP עתידית תדחהלא
E_USER_*שגיאות שאתם מעלים עם trigger_error()רק E_USER_ERROR
E_ALLכל הרמות, כולל שגיאות ליבה והידור שלא מופיעות כאן

PHP 8.0 הפכה הרבה אזהרות ישנות לחריגות: חלוקה באפס עם / והעברת טיפוס שגוי לפונקציה מובנית זורקות עכשיו תת מחלקה של Error, בדיוק כמו קריאה לפונקציה לא מוגדרת מאז PHP 7. אפשר לתפוס את שלושתן:

חריגות מוסברות בtry ו-catch. אזהרות, notices ו-deprecations עדיין עוברות דרך מערכת דיווח השגיאות שמתוארת כאן.

רישום שגיאות ללוג במקום להציג אותן

באתר חי, מבקרים לעולם לא צריכים לראות הודעות שגיאה: הן חושפות נתיבים, SQL וקוד. כתבו אותן לקובץ לוג במקום:

; Production
display_errors = Off
log_errors = On
error_log = /var/log/php/app-errors.log
error_reporting = E_ALL

השאירו error_reporting = E_ALL בייצור. הורדת הרמה לא גורמת לשגיאות להיעלם, היא רק מונעת מכם לשמוע עליהן. ההודעות שלכם יכולות להגיע לאותו לוג עם error_log():

<?php
error_log("Payment failed for order 1042");

אחר כך עקבו אחרי הקובץ בזמן הבדיקות: tail -f /var/log/php/app-errors.log.

הפיכת אזהרות לחריגות עם set_error_handler

set_error_handler מחליפה את הטיפול הרגיל של PHP באזהרות, notices ו-deprecations בפונקציה משלכם. דפוס נפוץ ממיר כל אחת מהן ל-ErrorException, כך שמפתח מערך שנשכח עוצר את הקוד כמו כל חריגה אחרת ואפשר לתפוס אותו:

ה-handler מקבל את רמת השגיאה כארגומנט הראשון, כך שהוא יכול לטפל ברמות שונות בצורה שונה. הזה רק רושם deprecations ללוג והופך את כל השאר לחריגה:

שגיאות פטאליות ושגיאות תחביר אף פעם לא מגיעות ל-handler, כי הסקריפט לא יכול להמשיך אחריהן. כדי לרשום אותן, רשמו פונקציית shutdown שקוראת את error_get_last().

קריאת השגיאה האחרונה עם error_get_last

חלק מהפונקציות מחזירות false ומדווחות על הסיבה רק כאזהרה, למשל file_get_contents על קובץ חסר. error_get_last() מחזירה את האזהרה הזו כמערך, וזה שימושי כשרוצים להציג הודעה משלכם:

האופרטור @ לפני הקריאה משתיק את ההודעה עבור הביטוי הזה בלבד. השתמשו בו במשורה ורק כשאתם בודקים את התוצאה מיד אחר כך, כמו כאן; @ לבדו רק מסתיר באגים.

טעות נפוצה: הצגת השגיאות פעילה, אבל הדף עדיין ריק

אם הוספתם ini_set('display_errors', '1') ועדיין רואים דף לבן, השגיאה היא כנראה שגיאת תחביר. PHP מנתחת את כל הקובץ לפני שהיא מריצה את השורה הראשונה, כך ש-; או } חסרים עוצרים הכול לפני ש-ini_set רצה. בדקו את הקובץ מהטרמינל, שתמיד מדפיס את ההודעה:

php -l index.php
Errors parsing index.php
PHP Parse error:  syntax error, unexpected token "," in index.php on line 2

מספר השורה מצביע על המקום שבו PHP הרימה ידיים, ולעיתים קרובות זו השורה שאחרי הטעות האמיתית. תקנו, הריצו שוב php -l עד שיופיע No syntax errors detected, ואז טענו מחדש את הדף.

שאלות נפוצות

איך מציגים את כל השגיאות ב-PHP?

הוסיפו ini_set('display_errors', '1'); ini_set('display_startup_errors', '1'); error_reporting(E_ALL); בראש הסקריפט ממש, או הגדירו display_errors = On ו-error_reporting = E_ALL ב-php.ini והפעילו מחדש את שרת הווב או את PHP-FPM.

למה דף ה-PHP שלי מציג מסך לבן ריק?

שגיאה פטאלית עצרה את הסקריפט בזמן ש-display_errors כבויה, ולכן שום דבר לא הודפס. הפעילו את הצגת השגיאות (או קראו את לוג השגיאות, למשל עם tail -f על הקובץ ש-error_log מצביע עליו) כדי לראות את ההודעה ואת מספר השורה.

למה ini_set('display_errors', 1) לא מציגה את שגיאת התחביר שלי?

שגיאת תחביר עוצרת את PHP לפני שאף שורה בקובץ רצה, כך שהקריאה ל-ini_set אף פעם לא מתבצעת. הגדירו את display_errors ב-php.ini, או שימו את ini_set בקובץ קטן שעושה include לקובץ השבור.

האם display_errors צריכה להיות פעילה בסביבת ייצור?

לא. הודעות שגיאה חושפות למבקרים נתיבי קבצים ופרטי קוד. בייצור השתמשו ב-display_errors = Off, ב-log_errors = On ובנתיב error_log, והשאירו error_reporting = E_ALL כדי שבעיות עדיין יירשמו.

מה עושה error_reporting(0)?

היא מכבה את הדיווח על כל סוגי השגיאות עד סוף הסקריפט, כך שאזהרות ואפילו שגיאות פטאליות לא מציגות שום הודעה. היא מסתירה בעיות במקום לתקן אותן; עדיף לרשום שגיאות ללוג מאשר להשתיק אותן.

איור של שפות התכנות ב-Coddy

ללמוד תכנות עם Coddy

להתחיל