วิธีหยุดสคริปต์โดยอัตโนมัติและเปลี่ยนเส้นทางไปยังหน้าแสดงข้อผิดพลาด หากข้อผิดพลาด/คำเตือน/การแจ้งเตือนไม่ถูกตรวจจับ

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


บางครั้งข้อผิดพลาดที่ไม่คาดคิดก็แก้ไขได้ยาก เนื่องจากรายงานข้อผิดพลาดถูกพิมพ์ภายในองค์ประกอบ HTML แปลกๆ เช่น div ที่ซ่อนอยู่หรือองค์ประกอบตัวเลือก

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


person Marco Sulla    schedule 13.06.2013    source แหล่งที่มา
comment
@JamesDonnelly: มันไม่ซ้ำกันเพราะฉันต้องการทำผิดพลาด   -  person Marco Sulla    schedule 13.06.2013
comment
@MladenB.: โดยพื้นฐานแล้วฉันต้องแปลงข้อผิดพลาดเป็นข้อยกเว้นโดยใช้ตัวอย่างนี้: php.net/manual/en/ และสร้างตัวจัดการข้อยกเว้นของตัวเองใช่ไหม ฉันจะหารหัสของตัวจัดการข้อยกเว้นเริ่มต้นได้ที่ไหน   -  person Marco Sulla    schedule 13.06.2013


คำตอบ (3)


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

set_error_handler(function ($errno, $errstr, $errfile, $errline) {
    throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
});

คุณอาจตัดสินใจได้ว่าข้อผิดพลาดใดที่จะทิ้งข้อยกเว้น และข้อผิดพลาดใดที่จะเพิกเฉย ตัวอย่างเช่น คุณอาจต้องการเพิกเฉยหรือเพียงแค่บันทึก E_NOTICE ด้วยบล็อก try..catch ส่วนกลางหรือ ตัวจัดการข้อยกเว้นแบบกำหนดเอง คุณสามารถดำเนินการได้แล้ว ตัดสินใจได้อย่างง่ายดายมากว่าจะทำอย่างไรในกรณีที่เกิดข้อผิดพลาด

person deceze♦    schedule 13.06.2013
comment
... นอกจากนี้ คุณควรรู้เกี่ยวกับชุดฟังก์ชัน ob_*: php.net /manual/en/ref.outcontrol.php . บัฟเฟอร์เอาต์พุตไซต์ของคุณและล้างข้อมูลเฉพาะเมื่อไม่มีข้อผิดพลาดเกิดขึ้น หากเกิดข้อผิดพลาด ให้แสดงหน้าข้อผิดพลาดและทิ้งเอาต์พุตไซต์ดั้งเดิม - person hek2mgl; 13.06.2013
comment
@ hek2mgl: ฉันไม่รู้ว่าฉันสามารถสรุปสิ่งที่คุณแนะนำได้ไหม ฉันต้องการปิดสิ่งนี้อย่างง่ายดายเมื่อไซต์เริ่มใช้งานจริง - person Marco Sulla; 13.06.2013
comment
ฉันแก้ไขมันได้โดยไม่ต้องเขียนตัวจัดการข้อผิดพลาดใหม่ทั้งหมด ดูคำตอบของฉัน :) - person Marco Sulla; 13.06.2013

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

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

display_errors = "0"

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

โปรดคำนึงถึงคำสั่ง "php.ini" ต่อไปนี้:

log_errors = "1"

ข้างต้นจะมีข้อผิดพลาดในบันทึก PHP ในไฟล์หรือการใช้สิ่งอำนวยความสะดวกในการบันทึกข้อผิดพลาดของเว็บเซิร์ฟเวอร์ ขึ้นอยู่กับวิธีการเรียกใช้ PHP ในระบบ UNIX ไฟล์บันทึกซึ่งแสดงรายการข้อผิดพลาดและรายละเอียดจะอยู่ใน "/var/log/www/" เป็นต้น

อ่านเอกสาร PHP เกี่ยวกับการจัดการข้อผิดพลาดและการรายงานให้ดี โดยเริ่มจากหน้าต่อไปนี้:

http://www.php.net/manual/en/book.errorfunc.php

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

person amn    schedule 13.06.2013
comment
ฉันชอบที่จะแสดงข้อผิดพลาดในระหว่างการพัฒนา เนื่องจากการดีบักทำได้รวดเร็วกว่า ฉันจะบันทึกข้อผิดพลาดเมื่อไซต์เริ่มใช้งานจริง - person Marco Sulla; 13.06.2013
comment
ทำไมจะไม่ได้ล่ะ @ลูคัส อย่างไรก็ตาม ฉันพบว่าการแสดงข้อผิดพลาดในระหว่างการพัฒนาอาจรบกวนการแก้ไขจุดบกพร่องได้ เนื่องจากมีความเป็นไปได้ที่ข้อผิดพลาดอาจคืบคลานเข้ามาในรูปแบบองค์ประกอบที่ไม่สามารถมองเห็นได้ นอกจากนี้ คำเตือนและข้อมูลสำคัญอื่นๆ อาจไปอยู่ในไฟล์บันทึกที่คุณไม่ต้องสนใจที่จะดูจนกว่าคุณจะตัดสินใจเผยแพร่ เช่นเดียวกับรหัสข้อผิดพลาดเซิร์ฟเวอร์ 500 รหัส - สคริปต์ของคุณจะสร้างเอาต์พุต แต่ PHP อาจเปลี่ยนรหัสข้อผิดพลาดในการตอบสนอง ซึ่งอาจทำให้หน้าเว็บของคุณเสียหายหากสิ่งเหล่านี้ให้บริการเช่นไคลเอนต์ Adobe Flash Player หรือผู้ใช้บริการเว็บ - person amn; 13.06.2013

ขอบคุณ @MladenB และหลอกลวง ฉันก็แก้ไขปัญหาของฉันแล้ว นี่คือวิธีที่ฉันเขียนโค้ดโซลูชัน:

ในไฟล์ config.php เพื่อรวมไว้ในสคริปต์ของคุณ (ควรย้ายฟังก์ชันไปยังไฟล์ไลบรารีส่วนตัวจะดีกว่า):

<?php

function my_error_handler($errno, $errstr, $errfile, $errline)
{
    throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}

function my_exception_handler($e)
{
    /**
     *  Exception handler that pass the error object to an error page.
     *  This is to avoid bad displaying or hiding of error reports.
     *  
     *  @param $e Exception  The exception to manage
     */

    if (session_status() !== PHP_SESSION_ACTIVE)
    {
        session_start();
    }

    session_register_shutdown();

    $_SESSION['error'] = $e;

    header('Location: error.php');
    exit();
}

set_error_handler('my_error_handler');
set_exception_handler('my_exception_handler');

ใน error.php:

<?php

session_start();
session_register_shutdown();

$e = $_SESSION['error'];

echo '<h2>Stack trace</h2>';
echo var_dump($e->getTrace());

throw $e;
person Community    schedule 13.06.2013