ฉันจะรับข้อความแสดงข้อผิดพลาดที่เป็นประโยชน์ใน PHP ได้อย่างไร


583

บ่อยครั้งที่ฉันจะพยายามเรียกใช้สคริปต์ PHP และกลับไปที่หน้าจอว่างเปล่า ไม่มีข้อความแสดงข้อผิดพลาด; เพียงแค่หน้าจอที่ว่างเปล่า สาเหตุอาจเป็นข้อผิดพลาดทางไวยากรณ์อย่างง่าย (วงเล็บไม่ถูกต้องเครื่องหมายอัฒภาคหายไป) หรือการเรียกใช้ฟังก์ชันที่ล้มเหลวหรืออย่างอื่น

มันยากมากที่จะคิดออกว่าเกิดอะไรขึ้น ฉันสิ้นสุดความคิดเห็นรหัสป้อนคำสั่ง "echo" ทุกที่ ฯลฯ พยายามแคบลงปัญหา แต่ต้องมีวิธีที่ดีกว่าใช่ไหม?

มีวิธีที่จะทำให้ PHP สร้างข้อความแสดงข้อผิดพลาดที่มีประโยชน์อย่าง Java หรือไม่?




4
@ JuannStrauss นั่นคือการทำความเข้าใจมัน และเมื่อคุณในที่สุดก็T_PAAMAYIM_NEKUDOTAYIMเห็นข้อผิดพลาดก็กล่าวว่า หรืออาจจะ"ต้องเป็นตัวอย่างของจำนวนเต็มจำนวนเต็มได้รับ"
Pacerier

1
การสอนเกี่ยวกับเรื่องนี้: code2real.blogspot.com/2015/06/…
นักเรียน

คำตอบ:


498

สำหรับข้อผิดพลาดทางไวยากรณ์คุณต้องเปิดใช้งานการแสดงข้อผิดพลาดใน php.ini โดยค่าเริ่มต้นสิ่งเหล่านี้จะถูกปิดเพราะคุณไม่ต้องการให้ "ลูกค้า" เห็นข้อความแสดงข้อผิดพลาด ตรวจสอบหน้านี้ในเอกสาร PHP สำหรับข้อมูลเกี่ยวกับ 2 คำสั่ง: และerror_reporting น่าจะเป็นสิ่งที่คุณต้องการเปลี่ยน หากคุณไม่สามารถแก้ไข php.ini ได้คุณสามารถเพิ่มบรรทัดต่อไปนี้ลงในไฟล์. htaccess:display_errorsdisplay_errors

php_flag  display_errors        on
php_value error_reporting       2039

คุณอาจต้องการพิจารณาใช้ค่าของ E_ALL (ตามที่ Gumbo กล่าวไว้) สำหรับ PHP เวอร์ชันของคุณerror_reportingเพื่อรับข้อผิดพลาดทั้งหมด ข้อมูลเพิ่มเติม

3 รายการอื่น ๆ : (1) คุณสามารถตรวจสอบไฟล์บันทึกข้อผิดพลาดเนื่องจากจะมีข้อผิดพลาดทั้งหมด (ยกเว้นว่าการบันทึกถูกปิดใช้งาน) (2) การเพิ่ม 2 บรรทัดต่อไปนี้จะช่วยให้คุณดีบักข้อผิดพลาดที่ไม่ใช่ข้อผิดพลาดทางไวยากรณ์:

error_reporting(-1);
ini_set('display_errors', 'On');

(3) อีกตัวเลือกหนึ่งคือการใช้โปรแกรมแก้ไขที่การตรวจสอบข้อผิดพลาดเมื่อคุณพิมพ์เช่นPhpEd PhpEd ยังมาพร้อมกับดีบักเกอร์ซึ่งสามารถให้ข้อมูลรายละเอียดเพิ่มเติมได้ (ดีบักเกอร์ PhpEd คล้ายกับ xdebug และรวมเข้ากับตัวแก้ไขโดยตรงดังนั้นคุณจึงใช้ 1 โปรแกรมเพื่อทำทุกอย่าง)

ลิงค์ของ Cartman นั้นดีมาก: http://www.ibm.com/developerworks/library/os-debug/


25
2039 E_ERROR | E_WARNING | E_PARSE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING | E_USER_ERROR | E_USER_WARNING | E_USER_NOTICEคือค่าของ ดูdocs.php.net/manual/en/errorfunc.constants.php
Gumbo

ฉันชอบตัวเลือกของไฟล์. htaccess ช่วยให้ฉันดีบักในพื้นที่ที่ไม่ได้เป็นส่วนหนึ่งของเว็บไซต์สาธารณะ ขอบคุณมากสำหรับเคล็ดลับนี้!
jacekn

1
ฉันจะเพิ่มข้อผิดพลาดในการเข้าสู่ไฟล์ (และดูที่นี่) เป็นทางออกที่ดีที่สุด อย่าพึ่งพาการแสดงข้อผิดพลาดในหน้า - พวกเขาสามารถทำลายมันได้คุณสามารถลืมเปิดการรายงานข้อผิดพลาดสำหรับไซต์การผลิตและสิ่งนี้จะทำให้คุณเดือดร้อนในอนาคต
Ivan Yarych

455

ต่อไปนี้ช่วยให้เกิดข้อผิดพลาดทั้งหมด:

ini_set('display_startup_errors', 1);
ini_set('display_errors', 1);
error_reporting(-1);

ดูลิงค์ต่อไปนี้


28
ดีที่สุดที่จะทำการเปลี่ยนแปลงเหล่านี้ในระดับไฟล์. ini การเปิดใช้การรายงานข้อผิดพลาดจากภายในสคริปต์นั้นไม่มีประโยชน์เนื่องจากจะไม่ช่วยให้เกิดข้อผิดพลาดทางไวยากรณ์หรือข้อผิดพลาดร้ายแรงอื่น ๆ ที่ฆ่าขั้นตอนการคอมไพล์ สคริปต์ได้รับการฆ่าก่อนที่จะเริ่มดำเนินการและไปถึงการแทนที่การรายงาน
Marc B

คุณถูกต้องแน่นอน ฉันไม่ได้สังเกตว่าการย้ายไปยังเซิร์ฟเวอร์ของคุณเอง
Eljakim

6
เรียกใช้ phpinfo () เพื่อค้นหาไฟล์ php.ini ที่ถูกต้อง ค้นหาบรรทัดไฟล์คอนฟิกูเรชันที่โหลด
borrible

1
หากคุณกำลังมองหาข้อผิดพลาดที่เกิดขึ้นระหว่างขั้นตอนการคอมไพล์ให้ตรวจสอบบันทึก apache ของคุณที่ /var/log/apache2/error.log
csi

1
คำตอบนี้จะล้มเหลวใน php7 เมื่อเปิดใช้งานการพิมพ์อย่างเข้มงวดเนื่องจากพารามิเตอร์ที่สองของini_setเป็นสตริง
PeeHaa

175

รหัสต่อไปนี้ควรแสดงข้อผิดพลาดทั้งหมด:

<?php

// ----------------------------------------------------------------------------------------------------
// - Display Errors
// ----------------------------------------------------------------------------------------------------
ini_set('display_errors', 'On');
ini_set('html_errors', 0);

// ----------------------------------------------------------------------------------------------------
// - Error Reporting
// ----------------------------------------------------------------------------------------------------
error_reporting(-1);

// ----------------------------------------------------------------------------------------------------
// - Shutdown Handler
// ----------------------------------------------------------------------------------------------------
function ShutdownHandler()
{
    if(@is_array($error = @error_get_last()))
    {
        return(@call_user_func_array('ErrorHandler', $error));
    };

    return(TRUE);
};

register_shutdown_function('ShutdownHandler');

// ----------------------------------------------------------------------------------------------------
// - Error Handler
// ----------------------------------------------------------------------------------------------------
function ErrorHandler($type, $message, $file, $line)
{
    $_ERRORS = Array(
        0x0001 => 'E_ERROR',
        0x0002 => 'E_WARNING',
        0x0004 => 'E_PARSE',
        0x0008 => 'E_NOTICE',
        0x0010 => 'E_CORE_ERROR',
        0x0020 => 'E_CORE_WARNING',
        0x0040 => 'E_COMPILE_ERROR',
        0x0080 => 'E_COMPILE_WARNING',
        0x0100 => 'E_USER_ERROR',
        0x0200 => 'E_USER_WARNING',
        0x0400 => 'E_USER_NOTICE',
        0x0800 => 'E_STRICT',
        0x1000 => 'E_RECOVERABLE_ERROR',
        0x2000 => 'E_DEPRECATED',
        0x4000 => 'E_USER_DEPRECATED'
    );

    if(!@is_string($name = @array_search($type, @array_flip($_ERRORS))))
    {
        $name = 'E_UNKNOWN';
    };

    return(print(@sprintf("%s Error in file \xBB%s\xAB at line %d: %s\n", $name, @basename($file), $line, $message)));
};

$old_error_handler = set_error_handler("ErrorHandler");

// other php code

?>

วิธีเดียวในการสร้างหน้าว่างด้วยรหัสนี้คือเมื่อคุณมีข้อผิดพลาดในตัวจัดการการปิดระบบ ฉันคัดลอกและวางสิ่งนี้จาก cms ของฉันโดยไม่ต้องทดสอบ แต่ฉันแน่ใจว่ามันใช้งานได้


4
ฉันได้รับหน้าว่างจากรหัสนั้น คุณหมายถึงอะไรโดย "คุณมีข้อผิดพลาดในตัวจัดการการปิดระบบ" และฉันควรทำอย่างไรเพื่อแก้ปัญหา
เปาโล M

@ เปาโลเขากำลังพูดถึงข้อผิดพลาดในฟังก์ชั่นShutdownHandlerด้านบน โดยทั่วไปนี่เป็นแฮ็คที่หยุดชั่วคราวแทนการจัดการข้อผิดพลาดที่เหมาะสม
Pacerier

ขอบคุณมีประโยชน์ แต่ฉันจะปิดการใช้งานE_NOTICEข้อผิดพลาดในฟังก์ชั่นนี้ได้อย่างไร?
MajAfy

นี่เป็นวิธีการแก้ปัญหาที่ถูกต้อง แต่ควรระมัดระวังในการเปิดเผยข้อมูลเมื่อเกิดข้อผิดพลาด ... (ต้องการบันทึกแทนการสะท้อนต่อผู้ใช้)
Sam Jason Braddock

1
ฉันใช้สิ่งนี้เมื่อ Symfony ไม่สามารถตรวจจับข้อผิดพลาดร้ายแรงได้อย่างถูกต้อง
ขด

61

ข้อผิดพลาดและคำเตือนมักจะปรากฏใน....\logs\php_error.logหรือ....\logs\apache_error.logขึ้นอยู่กับการตั้งค่า php.ini ของคุณ

ข้อผิดพลาดที่มีประโยชน์มักจะถูกส่งไปยังเบราว์เซอร์ด้วยเช่นกัน แต่เนื่องจากมันไม่ถูกต้อง html จึงไม่แสดง

ดังนั้น"tail -f"ไฟล์บันทึกของคุณและเมื่อคุณได้รับหน้าจอว่างให้ใช้ตัวเลือกเมนู" ดู "->" แหล่งที่มา "IEs เพื่อดูผลลัพธ์ดิบ


13
น่าเศร้าที่แหล่งดูหน้าเว็บไม่แสดงอะไรเลย
Matthew Scharley

2
ข้อผิดพลาดในการแยกวิเคราะห์ควรมองเห็นได้ในบันทึกข้อผิดพลาดของ Apache ไม่ว่าคุณจะตั้งค่าใดไว้ที่อื่น หากคุณไม่สามารถควบคุมเซิร์ฟเวอร์การรับบันทึกข้อผิดพลาด apache อาจเป็นเรื่องยาก แต่ฉันขอแนะนำให้คุณพูดคุยกับผู้ให้บริการของคุณและมีวิธีเปิดเผยบันทึกข้อผิดพลาดให้คุณ นอกจากนั้นฉันสามารถแนะนำสิ่งอื่น ๆ ได้ - vet รหัสของคุณสำหรับการแยกวิเคราะห์ข้อผิดพลาดในเซิร์ฟเวอร์การพัฒนาท้องถิ่นของคุณก่อนที่คุณจะปรับใช้กับการผลิต นอกจากนี้การตรวจสอบ IDE เช่น PDT ของ Eclipse อาจช่วยได้มาก
Guss

5
กลับมาที่นี่เมื่อเร็ว ๆ นี้ฉันมีปัญหาล้นสแต็คที่ไม่ได้สร้างข้อผิดพลาดใด ๆ แม้ในบันทึกและไม่ได้ประจักษ์เองจนฉันติดตั้ง xdebug ลงในเซิร์ฟเวอร์ Gah
Matthew Scharley

หากคุณไม่สามารถแก้ไข php.ini สร้าง htaccess ไฟล์ที่มีphp_flag display_errors 1อยู่ในนั้น
Tom

59

คุณสามารถรวมบรรทัดต่อไปนี้ในไฟล์ที่คุณต้องการตรวจแก้จุดบกพร่อง:

error_reporting(E_ALL);
ini_set('display_errors', '1');

สิ่งนี้จะแทนที่การตั้งค่าเริ่มต้นใน php.ini ซึ่งทำให้ PHP รายงานข้อผิดพลาดในบันทึก


2
นั่นเป็นเรื่องจริง ในกรณีนี้ค่าจะต้องตั้งค่าใน ini โดยตรง - สำหรับสภาพแวดล้อมการพัฒนาที่บริสุทธิ์นี้อาจจะดีกว่า
Tomalak

53

การกำหนดค่า PHP

2 รายการในphp.iniกำหนดผลลัพธ์ของข้อผิดพลาด:

  1. display_errors
  2. error_reporting

ในการผลิต , display_errorsมักจะมีการตั้งค่าOff(ซึ่งเป็นสิ่งที่ดีเพราะการแสดงผลผิดพลาดในสถานที่ผลิตโดยทั่วไปจะไม่เป็นที่น่าพอใจ!)

อย่างไรก็ตามในการพัฒนามันควรจะตั้งค่าเพื่อOnให้ข้อผิดพลาดปรากฏขึ้น ตรวจสอบ !

error_reporting(ตั้งแต่ PHP 5.3) ถูกตั้งค่าเริ่มต้นเป็นE_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED(หมายถึงทุกอย่างจะถูกแสดงยกเว้นประกาศมาตรฐานที่เข้มงวดและประกาศเลิกใช้) เมื่อสงสัยตั้งค่าให้E_ALLเพื่อแสดงทุกข้อผิดพลาด ตรวจสอบ !

โอ้โหโอ้! ไม่ตรวจสอบ! ฉันเปลี่ยน php.ini ไม่ได้!

นั่นเป็นความอัปยศ โดยทั่วไปแล้วโฮสต์ที่ใช้ร่วมกันจะไม่อนุญาตให้มีการเปลี่ยนแปลงไฟล์ php.ini ดังนั้นตัวเลือกนั้นจะไม่สามารถใช้งานได้อย่างน่าเศร้า แต่อย่ากลัวเลย! เรามีตัวเลือกอื่น ๆ !

การกำหนดค่ารันไทม์

ในสคริปต์ที่ต้องการเราสามารถเปลี่ยนรายการ php.ini ใน runtime! ความหมายมันจะทำงานเมื่อสคริปต์รัน! หวาน!

error_reporting(E_ALL);
ini_set("display_errors", "On");

สองบรรทัดนี้จะมีผลเช่นเดียวกับการแก้ไขรายการ php.ini ดังกล่าว! ! น่ากลัว

ฉันยังได้รับหน้าว่าง / ข้อผิดพลาด 500 ข้อ!

นั่นหมายความว่าสคริปต์ยังไม่ได้ทำงาน! มักเกิดขึ้นเมื่อคุณมีข้อผิดพลาดทางไวยากรณ์!

ด้วยข้อผิดพลาดทางไวยากรณ์สคริปต์ไม่ได้ไปรันไทม์ มันล้มเหลวในเวลารวบรวมหมายความว่ามันจะใช้ค่าใน php.ini ซึ่งถ้าคุณไม่ได้เปลี่ยนอาจไม่อนุญาตให้แสดงข้อผิดพลาด

บันทึกข้อผิดพลาด

นอกจากนี้ PHP โดยค่าเริ่มต้นบันทึกข้อผิดพลาด ในพื้นที่สาธารณะนั้นอาจอยู่ในโฟลเดอร์เฉพาะหรือในโฟลเดอร์เดียวกับสคริปต์ที่ละเมิด

หากคุณมีสิทธิ์เข้าถึง php.ini คุณสามารถค้นหาได้จากerror_logรายการ


30

มีส่วนขยายที่มีประโยชน์จริง ๆ เรียกว่า " xdebug " ซึ่งจะทำให้รายงานของคุณดีขึ้นมากเช่นกัน


2
อันที่จริงนี่เป็นเครื่องมือดีบั๊กที่มีประโยชน์มาก - ทำให้ข้อความแสดงข้อผิดพลาดมีความละเอียดมากยิ่งขึ้นด้วยการติดตามสแต็กเต็มรูปแบบและการทิ้งตัวแปรและทุกอย่าง
hbw

2
ใช่. จากนั้นใช้บางอย่างเช่นปลั๊กอิน VimDebugger เพื่อดูรหัสของคุณและค้นหาตำแหน่งที่ผิดพลาด
Sander Marechal

1
NetBeans กับ xdebug ที่นี่ มันยอดเยี่ยมมาก ฉันใหม่กับ PHP (โดยปกติคือ ASP.NET) และเคยออกงบ echo มาก่อน
บาง Canuck

30

ฉันมักจะใช้ไวยากรณ์นี้ที่ด้านบนสุดของสคริปต์ PHP

ini_set('error_reporting', E_ALL);
ini_set('display_errors', 'On');  //On or Off

3
ฉันขอโทษ แต่ -1 ที่ไม่ได้อ่านคำตอบอื่น ๆ ที่โพสต์แล้ว สิ่งนี้ได้รับการดูแลใน. htaccess ดังกล่าวแล้วหลายครั้ง
Matthew Scharley

12
ปกติ "ฟรีโฮสติ้ง" จะไม่สนใจ. htaccess
FDisk

27

สำหรับการแก้ไขปัญหาอย่างรวดเร็วโดยทั่วไปฉันมักแนะนำที่นี่ใน SO:

error_reporting(~0); ini_set('display_errors', 1);

ที่จะถูกวางไว้ที่จุดเริ่มต้นของสคริปต์ที่อยู่ภายใต้การแก้ไขปัญหา สิ่งนี้ไม่สมบูรณ์แบบตัวแปรที่สมบูรณ์แบบคือคุณยังเปิดใช้งานในphp.iniและที่คุณบันทึกข้อผิดพลาดใน PHP เพื่อตรวจจับข้อผิดพลาดทางไวยากรณ์และการเริ่มต้น

การตั้งค่าที่แสดงไว้ที่นี่จะแสดงข้อผิดพลาดประกาศและคำเตือนรวมถึงข้อ จำกัด ทั้งหมดไม่ว่าจะใช้เวอร์ชัน PHP เวอร์ชันใด

สิ่งต่อไปที่ควรพิจารณา:

  • ติดตั้งXdebugและเปิดใช้งานการดีบักแบบรีโมทด้วย IDE ของคุณ

ดูเช่นกัน:


27

เป็นไปได้ที่จะลงทะเบียนเบ็ดเพื่อทำให้ข้อผิดพลาดหรือการเตือนครั้งสุดท้ายปรากฏให้เห็น

function shutdown(){
  var_dump(error_get_last());
}

register_shutdown_function('shutdown');

การเพิ่มรหัสนี้ไปยังจุดเริ่มต้นของคุณ index.php จะช่วยให้คุณแก้ปัญหาได้


1
นี่คือทองคำบริสุทธิ์สำหรับผู้ที่ติดอยู่ในเว็บโฮสติ้งที่ไม่มีข้อผิดพลาด แต่อนุญาตให้เข้าสู่ระบบได้เป็นศูนย์
Rafael Mena Barreto

18

นี่เป็นปัญหาของการโหลดกับการกำหนดค่ารันไทม์

สิ่งสำคัญคือต้องทราบว่ามีข้อผิดพลาดทางไวยากรณ์หรือข้อผิดพลาดในการแยกวิเคราะห์เกิดขึ้นในระหว่างการคอมไพล์หรือขั้นตอนการแยกวิเคราะห์ซึ่งหมายความว่า PHP จะประกันตัวก่อนที่จะมีโอกาสรันโค้ดใด ๆ ของคุณ ดังนั้นหากคุณกำลังปรับเปลี่ยนการdisplay_errorsกำหนดค่าของ PHP ในระหว่างรันไทม์ (ซึ่งรวมถึงสิ่งใด ๆ จากการใช้ini_setในรหัสของคุณเป็นการใช้. htaccess ซึ่งเป็นไฟล์การกำหนดค่ารันไทม์) ดังนั้นเฉพาะการตั้งค่าการโหลดที่โหลดเริ่มต้นเท่านั้น

วิธีหลีกเลี่ยง WSOD ในการพัฒนาอยู่เสมอ

เพื่อหลีกเลี่ยงการ WSOD ที่คุณต้องการเพื่อให้แน่ใจว่าคุณแฟ้มการกำหนดค่าโหลดมีdisplay_errorsในและerror_reportingชุด-1( นี้เป็น E_ALL เทียบเท่าเพราะมันช่วยให้มั่นใจบิตทั้งหมดจะถูกเปิดโดยไม่คำนึงถึงรุ่นของ PHP คุณกำลังใช้งาน ) อย่า hardcode ค่าคงที่ของ E_ALL เนื่องจากค่านั้นอาจเปลี่ยนแปลงได้ระหว่าง PHP เวอร์ชันต่างๆ

การกำหนดค่าที่โหลดเป็นphp.iniไฟล์ที่โหลดหรือไฟล์ของคุณapache.confหรือhttpd.confไฟล์ virtualhost ไฟล์เหล่านั้นจะถูกอ่านเพียงครั้งเดียวในช่วงเริ่มต้น (เมื่อคุณเริ่ม apache httpd หรือ php-fpm เป็นครั้งแรก) และถูกแทนที่โดยการเปลี่ยนแปลงการกำหนดค่ารันไทม์เท่านั้น ตรวจสอบให้แน่ใจว่าdisplay_errors = 1และerror_reporting = -1ในไฟล์กำหนดค่าที่โหลดแล้วของคุณรับรองว่าคุณจะไม่เห็นWSODโดยไม่คำนึงถึงข้อผิดพลาดทางไวยากรณ์หรือการแยกวิเคราะห์ที่เกิดขึ้นก่อนที่จะมีการเปลี่ยนแปลงรันไทม์เช่นini_set('display_errors', 1);หรือerror_reporting(E_ALL);อาจเกิดขึ้น

วิธีค้นหาไฟล์การกำหนดค่าที่โหลด (php.ini) ของคุณ

หากต้องการค้นหาไฟล์การกำหนดค่าที่โหลดของคุณเพียงสร้างไฟล์ PHP ใหม่ด้วยรหัสต่อไปนี้เท่านั้น ...

<?php
phpinfo();

จากนั้นชี้เบราว์เซอร์ของคุณไปที่นั่นแล้วดูที่Loaded Configuration Fileและไฟล์. ini เพิ่มเติมแยกวิเคราะห์ซึ่งมักจะอยู่ด้านบนของคุณphpinfo()และจะรวมเส้นทางที่แน่นอนไปยังไฟล์กำหนดค่าที่โหลดไว้ทั้งหมด

ถ้าคุณเห็น(none)แทนของไฟล์นั่นหมายความว่าคุณไม่ได้มี php.ini ในการกำหนดค่าไฟล์ (php.ini) เส้นทาง ดังนั้นคุณสามารถดาวน์โหลดสต็อก php.ini ที่มาพร้อมกับ PHP จากที่นี่และคัดลอกไปยังพา ธ ไฟล์การกำหนดค่าของคุณเป็น php.ini จากนั้นตรวจสอบให้แน่ใจว่าผู้ใช้ php ของคุณมีสิทธิ์เพียงพอที่จะอ่านจากไฟล์นั้น คุณจะต้องรีสตาร์ท httpd หรือ php-fpm เพื่อโหลดมันจำไว้ว่านี่คือไฟล์ php.ini สำหรับการพัฒนาที่มาพร้อมกับซอร์ส PHP ดังนั้นโปรดอย่าใช้มันในการผลิต!


อย่าทำอย่างนี้ในการผลิต

นี่เป็นวิธีที่ดีที่สุดในการหลีกเลี่ยง WSOD ในการพัฒนา ใครก็ตามที่แนะนำให้คุณใส่ini_set('display_errors', 1);หรือerror_reporting(E_ALL);ที่ด้านบนสุดของสคริปต์ PHP หรือใช้. htaccess เหมือนที่คุณทำที่นี่จะไม่ช่วยให้คุณหลีกเลี่ยง WSOD เมื่อเกิดข้อผิดพลาดทางไวยากรณ์หรือการแยกวิเคราะห์ (เช่นในกรณีของคุณที่นี่) ได้display_errorsปิด

คนจำนวนมาก (และการติดตั้งสต็อกของ PHP) จะใช้ไฟล์ที่display_errorsใช้งานจริงซึ่งปิดไว้ตามค่าเริ่มต้นซึ่งโดยทั่วไปแล้วจะทำให้เกิดความยุ่งยากเช่นเดียวกับที่คุณเคยประสบมา เนื่องจาก PHP ปิดใช้งานแล้วเมื่อเริ่มทำงานจากนั้นจึงพบข้อผิดพลาดทางไวยากรณ์หรือการแยกวิเคราะห์และไม่มีการออกผลลัพธ์ คุณคาดหวังว่าini_set('display_errors',1);สคริปต์ PHP ที่อยู่ด้านบนของคุณควรหลีกเลี่ยงสิ่งนั้น แต่จะไม่สำคัญว่า PHP จะแยกรหัสของคุณไม่ได้หรือไม่เพราะมันจะไม่ไปถึงรันไทม์


17

หากคุณเท่ห์สุด ๆ คุณอาจลอง:

$test_server = $_SERVER['SERVER_NAME'] == "127.0.0.1" || $_SERVER['SERVER_NAME'] == "localhost" || substr($_SERVER['SERVER_NAME'],0,3) == "192";

ini_set('display_errors',$test_server);
error_reporting(E_ALL|E_STRICT);

สิ่งนี้จะแสดงข้อผิดพลาดเฉพาะเมื่อคุณเรียกใช้ในเครื่อง นอกจากนี้ยังให้ตัวแปร test_server ให้คุณใช้ในที่อื่น ๆ ตามความเหมาะสม

ข้อผิดพลาดใด ๆ ที่เกิดขึ้นก่อนที่สคริปต์จะไม่ถูกตรวจจับ แต่สำหรับข้อผิดพลาด 99% ที่ฉันทำนั่นไม่ใช่ปัญหา


2
หากคุณแยกความแตกต่างระหว่างสภาพแวดล้อมท้องถิ่นและสภาพแวดล้อมการผลิตคุณควรเปิดใช้งานหรือปิดใช้งานข้อผิดพลาดทั่วโลก (ใน php.ini ของคุณ) และไม่ใช่ในรหัสที่อาจเป็นรหัสการผลิต หากคุณต้องการดีบักเว็บไซต์ที่ใช้งานจริงในสภาพแวดล้อมการผลิตและต้องการให้คุณสามารถดูข้อผิดพลาดได้ให้ใช้$_SERVER['REMOTE_HOST']เพื่อตรวจสอบว่าลูกค้านั้นดีหรือไม่
Jaap Haagmans

17

ที่ด้านบนของหน้าให้เลือกพารามิเตอร์

error_reporting(E_ERROR | E_WARNING | E_PARSE);

16

หากต้องการยืนยันสิ่งนี้และทำให้เป็นความลับคุณสามารถแก้ไขไฟล์ php.ini ของคุณได้ โดยปกติจะถูกเก็บไว้ใน/etc/php.iniหรือ/etc/php/php.iniแต่ท้องถิ่นphp.iniอาจเขียนทับได้มากกว่านั้นขึ้นอยู่กับแนวทางการตั้งค่าของผู้ให้บริการโฮสต์ของคุณ ตรวจสอบphpinfo()ไฟล์Loaded Configuration Fileที่ด้านบนเพื่อให้แน่ใจว่าไฟล์ใดที่ถูกโหลดครั้งล่าสุด

ค้นหา display_errors ในไฟล์นั้น ควรมีเพียง 3 อินสแตนซ์ซึ่ง 2 ความคิดเห็น

เปลี่ยนบรรทัดที่ไม่ใส่เครื่องหมายเป็น:

display_errors = stdout

16

Dunno ช่วยได้ แต่นี่เป็นส่วนหนึ่งของไฟล์ปรับแต่งมาตรฐานของฉันสำหรับโครงการ php ฉันมักจะไม่พึ่งพา apache configs มากเกินไปแม้แต่บนเซิร์ฟเวอร์ของฉันเอง

ฉันไม่เคยมีปัญหาข้อผิดพลาดที่หายไปดังนั้นบางสิ่งที่นี่อาจทำให้คุณมีความคิด

แก้ไขเพื่อแสดง APPLICATON_LIVE

/*
APPLICATION_LIVE will be used in process to tell if we are in a development or production environment.  It's generally set as early as possible (often the first code to run), before any config, url routing, etc.
*/

if ( preg_match( "%^(www.)?livedomain.com$%", $_SERVER["HTTP_HOST"]) ) {
    define('APPLICATION_LIVE', true);
} elseif ( preg_match( "%^(www.)?devdomain.net$%", $_SERVER["HTTP_HOST"]) ) {
    define('APPLICATION_LIVE', false);
} else {
    die("INVALID HOST REQUEST (".$_SERVER["HTTP_HOST"].")");
    // Log or take other appropriate action.
}


/*
--------------------------------------------------------------------
DEFAULT ERROR HANDLING
--------------------------------------------------------------------
Default error logging.  Some of these may be changed later based on APPLICATION_LIVE.
*/
error_reporting(E_ALL & ~E_STRICT);
ini_set ( "display_errors", "0");
ini_set ( "display_startup_errors", "0");
ini_set ( "log_errors", 1);
ini_set ( "log_errors_max_len", 0);
ini_set ( "error_log", APPLICATION_ROOT."logs/php_error_log.txt");
ini_set ( "display_errors", "0");
ini_set ( "display_startup_errors", "0");

if ( ! APPLICATION_LIVE ) {
    // A few changes to error handling for development.
    // We will want errors to be visible during development.
    ini_set ( "display_errors", "1");
    ini_set ( "display_startup_errors", "1");
    ini_set ( "html_errors", "1");
    ini_set ( "docref_root", "http://www.php.net/");
    ini_set ( "error_prepend_string", "<div style='color:red; font-family:verdana; border:1px solid red; padding:5px;'>");
    ini_set ( "error_append_string", "</div>");
}

@Eli นี้มีรันไทม์ค่าใช้จ่าย แต่ต่อคำขอหน้า
Pacerier

ขึ้น 1 สำหรับแนวคิดที่มองข้ามการตั้งค่าการดีบัก แต่มีการกำหนดค่าเซิร์ฟเวอร์ดีในขณะที่คุณกำลังปรับใช้หรือบำรุงรักษา (ภายใต้การพัฒนา)
เพียงแค่

15
error_reporting(E_ALL | E_STRICT);
ini_set('display_errors', 1);
ini_set('html_errors', 1);

นอกจากนี้คุณจะได้รับข้อมูลรายละเอียดเพิ่มเติมกับxdebug


Xdebug สามารถเปิดใช้งานได้จาก php.ini
jewelhuq

15

ฉันแนะนำNette Tracyสำหรับการแสดงภาพข้อผิดพลาดและข้อยกเว้นใน PHP ที่ดีขึ้น:

ภาพหน้าจอของ Nette Tracy


3
เทรซี่ดูแลเกี่ยวกับการตั้งค่าที่เหมาะสมของข้อผิดพลาดในการแสดงผลและตัวเลือกการรายงานข้อผิดพลาดเพื่อให้ผลลัพธ์ในสถานการณ์ดังที่อธิบายไว้ในโพสต์ต้นฉบับ ... ดังนั้นเครื่องมือนี้มีประโยชน์อย่างยิ่งสำหรับการถามผู้ถาม "
ม.ค. Drábek



9

คุณสามารถลงทะเบียนตัวจัดการข้อผิดพลาดของคุณเองใน PHP การดัมพ์ข้อผิดพลาดทั้งหมดไปยังไฟล์อาจช่วยคุณในกรณีที่คลุมเครือเหล่านี้ตัวอย่างเช่น โปรดทราบว่าฟังก์ชั่นของคุณจะถูกเรียกใช้ไม่ว่าerror_reportingปัจจุบันของคุณจะถูกตั้งค่าเป็น ตัวอย่างพื้นฐานมาก:

function dump_error_to_file($errno, $errstr) {
    file_put_contents('/tmp/php-errors', date('Y-m-d H:i:s - ') . $errstr, FILE_APPEND);
}
set_error_handler('dump_error_to_file');

7

สองบรรทัดสำคัญที่คุณต้องได้รับจากข้อผิดพลาดที่เป็นประโยชน์ของ PHP คือ:

ini_set('display_errors',1);
 error_reporting(E_ALL);

ดังที่ผู้ให้ข้อมูลรายอื่นชี้ไว้จะถูกปิดโดยค่าเริ่มต้นด้วยเหตุผลด้านความปลอดภัย ในฐานะที่เป็นเคล็ดลับที่มีประโยชน์ - เมื่อคุณตั้งค่าไซต์ของคุณการสลับไปยังสภาพแวดล้อมที่แตกต่างกันของคุณนั้นเป็นประโยชน์อย่างยิ่ง สิ่งนี้สามารถทำได้ด้วยรหัสต่อไปนี้ (โดยเฉพาะในไฟล์ index.php หรือ config ของคุณเพื่อให้สามารถใช้งานได้ตั้งแต่เริ่มต้น):

switch($_SERVER['SERVER_NAME'])
{
    // local
    case 'yourdomain.dev':
    // dev
    case 'dev.yourdomain.com':
        ini_set('display_errors',1);
        error_reporting(E_ALL);
    break;
    //live
    case 'yourdomain.com':
        //...
    break;
}

6

FirePHPมีประโยชน์เช่นกัน


ฉันควรทราบว่า FirePHP เป็นโครงการที่ตายแล้วเนื่องจาก FireBug ถูกรวมเข้ากับ Firefox Console ChromePHPเป็นผู้สืบทอดที่นั่น แต่ไม่ใช่ทั้งหมด
Machavity

6

เปิด php.ini ของคุณตรวจสอบให้แน่ใจว่าได้ตั้งค่าเป็น:

display_errors = On

รีสตาร์ทเซิร์ฟเวอร์ของคุณ


6

คุณอาจต้องการลอง PHPStorm เป็นเครื่องมือแก้ไขรหัสของคุณ มันจะพบ PHP และข้อผิดพลาดทางไวยากรณ์อื่น ๆ มากมายในขณะที่คุณพิมพ์ในโปรแกรมแก้ไข


6

หากคุณเป็นผู้ใช้อูบุนตูให้ไปที่เทอร์มินัลของคุณแล้วรันคำสั่งนี้

sudo tail -50f /var/log/apache2/error.log

โดยที่จะแสดงข้อผิดพลาด 50 รายการล่าสุด มีไฟล์ข้อผิดพลาดerror.logสำหรับ apache2 ซึ่งบันทึกข้อผิดพลาดทั้งหมด


5

หากต้องการเปิดการรายงานข้อผิดพลาดแบบเต็มให้เพิ่มสิ่งนี้ในสคริปต์ของคุณ:

error_reporting(E_ALL);

นี่เป็นสาเหตุที่ทำให้มีคำเตือนน้อยที่สุดที่จะปรากฏขึ้น และในกรณี:

ini_set('display_errors', '1');

จะบังคับให้แสดงข้อผิดพลาด สิ่งนี้ควรปิดในเซิร์ฟเวอร์ที่ใช้งานจริง แต่ไม่ใช่เมื่อคุณกำลังพัฒนา


เช่นเดียวกับคำตอบของ Tomalak สิ่งนี้ไม่ได้ผลกับข้อผิดพลาดทางไวยากรณ์
Darryl Hein

5

“ ข้อผิดพลาด” เป็นสิ่งที่มีประโยชน์ที่สุดสำหรับนักพัฒนาในการรู้ข้อผิดพลาดและแก้ไขเพื่อให้ระบบทำงานได้อย่างสมบูรณ์แบบ

PHP มีวิธีที่ดีกว่าในการรู้สาเหตุของนักพัฒนาและที่รหัสของพวกเขาได้รับข้อผิดพลาดดังนั้นโดยการรู้ว่านักพัฒนาข้อผิดพลาดสามารถทำให้โค้ดของพวกเขาดีขึ้นได้หลายวิธี

วิธีที่ดีที่สุดในการเขียนสองบรรทัดต่อไปนี้ที่ด้านบนสุดของสคริปต์เพื่อรับข้อความแสดงข้อผิดพลาดทั้งหมด:

error_reporting(E_ALL);
ini_set("display_errors", 1);

อีกวิธีในการใช้เครื่องมือดีบักเกอร์เช่นxdebugใน IDE ของคุณ


4

คุณสามารถเปิดใช้งานการรายงานข้อผิดพลาดเต็มรูปแบบ (รวมถึงประกาศและข้อความที่เข้มงวด) บางคนพบว่า verbose เกินไป แต่ก็ควรลองดู ตั้งerror_reportingเป็นE_ALL | E_STRICTphp.ini ของคุณ

error_reporting = E_ALL | E_STRICT

E_STRICT จะแจ้งให้คุณทราบเกี่ยวกับฟังก์ชั่นที่เลิกใช้แล้วและให้คำแนะนำเกี่ยวกับวิธีที่ดีที่สุดในการทำงานบางอย่าง

หากคุณไม่ต้องการให้มีการแจ้งเตือน แต่คุณพบว่าข้อความประเภทอื่นมีประโยชน์ให้ลองยกเว้นการแจ้งเตือน:

error_reporting = (E_ALL | E_STRICT) & ~E_NOTICE

ตรวจสอบให้แน่ใจว่าdisplay_errorsเปิดใช้งานใน php.ini ด้วย หากเวอร์ชัน PHP ของคุณเก่ากว่า 5.2.4 ให้ตั้งค่าเป็นOn:

display_errors = "On"

หากเวอร์ชันของคุณคือ 5.2.4 หรือใหม่กว่าให้ใช้:

display_errors = "stderr"

4

นอกเหนือจาก error_reporting และการตั้งค่า display_errors ini คุณสามารถรับข้อผิดพลาด SYNTAX จากไฟล์บันทึกของเว็บเซิร์ฟเวอร์ เมื่อฉันพัฒนา PHP ฉันโหลดเว็บเซิร์ฟเวอร์ของระบบพัฒนาลงในโปรแกรมแก้ไขของฉัน เมื่อใดก็ตามที่ฉันทดสอบหน้าเว็บและรับหน้าจอว่างเปล่าล็อกไฟล์จะค้างและตัวแก้ไขของฉันถามว่าฉันต้องการโหลดซ้ำหรือไม่ เมื่อฉันฉันข้ามไปด้านล่างและมีข้อผิดพลาดทางไวยากรณ์ ตัวอย่างเช่น:

[Sun Apr 19 19:09:11 2009] [error] [client 127.0.0.1] PHP Parse error:  syntax error, unexpected T_ENCAPSED_AND_WHITESPACE, expecting T_STRING or T_VARIABLE or T_NUM_STRING in D:\\webroot\\test\\test.php on line 9

3

สำหรับผู้ที่ใช้ Nginx <?php echo 123;และมีหน้าจอสีขาวแม้สำหรับไฟล์ที่มี ในกรณีของฉันฉันไม่มีตัวเลือกที่จำเป็นสำหรับ PHP ในไฟล์ config nginx นี้:

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

ตัวเลือกนี้ไม่ได้อยู่ในไฟล์ fastcgi_params ดังนั้น PHP จึงไม่ทำงานและไม่มีข้อผิดพลาดในบันทึก


ฉันมีปัญหาเดียวกันและเนื่องจากไฟล์กำหนดค่าเริ่มต้นของ Nginx หายไปจากบรรทัดนั้น
เซเลม
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.