บางทีฉันอาจจะพลาดที่ไหนสักแห่งในคู่มือ PHP แต่อะไรคือความแตกต่างระหว่างข้อผิดพลาดและข้อยกเว้น? ความแตกต่างเดียวที่ฉันเห็นคือข้อผิดพลาดและข้อยกเว้นจะได้รับการจัดการที่แตกต่างกัน แต่อะไรทำให้เกิดข้อยกเว้นและอะไรทำให้เกิดข้อผิดพลาด?
บางทีฉันอาจจะพลาดที่ไหนสักแห่งในคู่มือ PHP แต่อะไรคือความแตกต่างระหว่างข้อผิดพลาดและข้อยกเว้น? ความแตกต่างเดียวที่ฉันเห็นคือข้อผิดพลาดและข้อยกเว้นจะได้รับการจัดการที่แตกต่างกัน แต่อะไรทำให้เกิดข้อยกเว้นและอะไรทำให้เกิดข้อผิดพลาด?
คำตอบ:
มีการโยนข้อยกเว้น- ตั้งใจให้จับได้ ข้อผิดพลาดมักไม่สามารถกู้คืนได้ ยกตัวอย่างเช่นคุณมีบล็อกโค้ดที่จะแทรกแถวลงในฐานข้อมูล เป็นไปได้ว่าการโทรนี้ล้มเหลว (รหัสซ้ำ) - คุณจะต้องมี "ข้อผิดพลาด" ซึ่งในกรณีนี้คือ "ข้อยกเว้น" เมื่อคุณแทรกแถวเหล่านี้คุณสามารถทำสิ่งนี้ได้
try {
$row->insert();
$inserted = true;
} catch (Exception $e) {
echo "There was an error inserting the row - ".$e->getMessage();
$inserted = false;
}
echo "Some more stuff";
การเรียกใช้โปรแกรมจะดำเนินต่อไป - เนื่องจากคุณ 'จับได้' ข้อยกเว้น ข้อยกเว้นจะถือเป็นข้อผิดพลาดเว้นแต่จะถูกจับได้ จะช่วยให้คุณดำเนินการโปรแกรมต่อไปได้หลังจากที่ล้มเหลวเช่นกัน
Throwable
อินเทอร์เฟซใหม่) ทำให้มีวิธีที่ชัดเจนและชัดเจนมากขึ้นในการแยกแยะและใช้งานจริงอย่างเหมาะสม ปัญหาและข้อความให้คำแนะนำ
Error
VS Exception
ลูกหลานของ
ฉันมักset_error_handler
จะใช้ฟังก์ชันที่รับข้อผิดพลาดและโยนข้อยกเว้นเพื่อไม่ว่าจะเกิดอะไรขึ้นฉันจะมีข้อยกเว้นที่ต้องจัดการ ไม่@file_get_contents
เพียงแค่ลอง / จับที่ดีและเรียบร้อยอีกต่อไป
ในสถานการณ์การดีบักฉันยังมีตัวจัดการข้อยกเว้นที่แสดงผลเหมือนหน้า asp.net ฉันกำลังโพสต์สิ่งนี้บนท้องถนน แต่หากมีการร้องขอฉันจะโพสต์แหล่งข้อมูลตัวอย่างในภายหลัง
แก้ไข:
นอกจากนี้ตามสัญญาฉันได้ตัดและวางโค้ดบางส่วนเข้าด้วยกันเพื่อสร้างตัวอย่าง ฉันได้บันทึกข้อมูลด้านล่างนี้ลงในเวิร์กสเตชันของฉันแล้วคุณไม่สามารถดูผลลัพธ์ได้อีกต่อไปที่นี่ (เนื่องจากลิงก์เสีย)
<?php
define( 'DEBUG', true );
class ErrorOrWarningException extends Exception
{
protected $_Context = null;
public function getContext()
{
return $this->_Context;
}
public function setContext( $value )
{
$this->_Context = $value;
}
public function __construct( $code, $message, $file, $line, $context )
{
parent::__construct( $message, $code );
$this->file = $file;
$this->line = $line;
$this->setContext( $context );
}
}
/**
* Inspire to write perfect code. everything is an exception, even minor warnings.
**/
function error_to_exception( $code, $message, $file, $line, $context )
{
throw new ErrorOrWarningException( $code, $message, $file, $line, $context );
}
set_error_handler( 'error_to_exception' );
function global_exception_handler( $ex )
{
ob_start();
dump_exception( $ex );
$dump = ob_get_clean();
// send email of dump to administrator?...
// if we are in debug mode we are allowed to dump exceptions to the browser.
if ( defined( 'DEBUG' ) && DEBUG == true )
{
echo $dump;
}
else // if we are in production we give our visitor a nice message without all the details.
{
echo file_get_contents( 'static/errors/fatalexception.html' );
}
exit;
}
function dump_exception( Exception $ex )
{
$file = $ex->getFile();
$line = $ex->getLine();
if ( file_exists( $file ) )
{
$lines = file( $file );
}
?><html>
<head>
<title><?= $ex->getMessage(); ?></title>
<style type="text/css">
body {
width : 800px;
margin : auto;
}
ul.code {
border : inset 1px;
}
ul.code li {
white-space: pre ;
list-style-type : none;
font-family : monospace;
}
ul.code li.line {
color : red;
}
table.trace {
width : 100%;
border-collapse : collapse;
border : solid 1px black;
}
table.thead tr {
background : rgb(240,240,240);
}
table.trace tr.odd {
background : white;
}
table.trace tr.even {
background : rgb(250,250,250);
}
table.trace td {
padding : 2px 4px 2px 4px;
}
</style>
</head>
<body>
<h1>Uncaught <?= get_class( $ex ); ?></h1>
<h2><?= $ex->getMessage(); ?></h2>
<p>
An uncaught <?= get_class( $ex ); ?> was thrown on line <?= $line; ?> of file <?= basename( $file ); ?> that prevented further execution of this request.
</p>
<h2>Where it happened:</h2>
<? if ( isset($lines) ) : ?>
<code><?= $file; ?></code>
<ul class="code">
<? for( $i = $line - 3; $i < $line + 3; $i ++ ) : ?>
<? if ( $i > 0 && $i < count( $lines ) ) : ?>
<? if ( $i == $line-1 ) : ?>
<li class="line"><?= str_replace( "\n", "", $lines[$i] ); ?></li>
<? else : ?>
<li><?= str_replace( "\n", "", $lines[$i] ); ?></li>
<? endif; ?>
<? endif; ?>
<? endfor; ?>
</ul>
<? endif; ?>
<? if ( is_array( $ex->getTrace() ) ) : ?>
<h2>Stack trace:</h2>
<table class="trace">
<thead>
<tr>
<td>File</td>
<td>Line</td>
<td>Class</td>
<td>Function</td>
<td>Arguments</td>
</tr>
</thead>
<tbody>
<? foreach ( $ex->getTrace() as $i => $trace ) : ?>
<tr class="<?= $i % 2 == 0 ? 'even' : 'odd'; ?>">
<td><?= isset($trace[ 'file' ]) ? basename($trace[ 'file' ]) : ''; ?></td>
<td><?= isset($trace[ 'line' ]) ? $trace[ 'line' ] : ''; ?></td>
<td><?= isset($trace[ 'class' ]) ? $trace[ 'class' ] : ''; ?></td>
<td><?= isset($trace[ 'function' ]) ? $trace[ 'function' ] : ''; ?></td>
<td>
<? if( isset($trace[ 'args' ]) ) : ?>
<? foreach ( $trace[ 'args' ] as $i => $arg ) : ?>
<span title="<?= var_export( $arg, true ); ?>"><?= gettype( $arg ); ?></span>
<?= $i < count( $trace['args'] ) -1 ? ',' : ''; ?>
<? endforeach; ?>
<? else : ?>
NULL
<? endif; ?>
</td>
</tr>
<? endforeach;?>
</tbody>
</table>
<? else : ?>
<pre><?= $ex->getTraceAsString(); ?></pre>
<? endif; ?>
</body>
</html><? // back in php
}
set_exception_handler( 'global_exception_handler' );
class X
{
function __construct()
{
trigger_error( 'Whoops!', E_USER_NOTICE );
}
}
$x = new X();
throw new Exception( 'Execution will never get here' );
?>
คำตอบสมควรพูดถึงช้างในห้อง
ข้อผิดพลาดเป็นวิธีเก่าในการจัดการเงื่อนไขข้อผิดพลาดในขณะทำงาน โดยปกติรหัสจะโทรไปยังบางสิ่งเช่นset_error_handler
ก่อนที่จะเรียกใช้รหัสบางอย่าง ตามธรรมเนียมการขัดจังหวะภาษาแอสเซมบลี นี่คือลักษณะของรหัสพื้นฐานบางส่วน
on error :divide_error
print 1/0
print "this won't print"
:divide_error
if errcode = X
print "divide by zero error"
มันยากที่จะตรวจสอบให้แน่ใจว่าset_error_handler
จะถูกเรียกด้วยมูลค่าที่ถูกต้อง และที่แย่ไปกว่านั้นคือการโทรไปยังขั้นตอนแยกต่างหากที่จะเปลี่ยนตัวจัดการข้อผิดพลาด นอกจากนี้หลายครั้งการโทรถูกสลับกับการset_error_handler
โทรและตัวจัดการ เป็นเรื่องง่ายที่โค้ดจะหลุดจากการควบคุมได้อย่างรวดเร็ว การจัดการข้อยกเว้นเข้ามาช่วยโดยการจัดรูปแบบไวยากรณ์และความหมายของโค้ดที่ดีที่กำลังทำอยู่
try {
print 1/0;
print "this won't print";
} catch (DivideByZeroException $e) {
print "divide by zero error";
}
ไม่มีฟังก์ชันแยกหรือความเสี่ยงในการเรียกตัวจัดการข้อผิดพลาดที่ไม่ถูกต้อง ตอนนี้รหัสรับประกันว่าจะอยู่ในที่เดียวกัน นอกจากนี้เรายังได้รับข้อความแสดงข้อผิดพลาดที่ดีขึ้น
PHP เคยมีเพียงการจัดการข้อผิดพลาดเมื่อภาษาอื่น ๆ ได้พัฒนาไปสู่รูปแบบการจัดการข้อยกเว้นที่ดีกว่าแล้ว ในที่สุดผู้ผลิต PHP ได้ดำเนินการจัดการข้อยกเว้น แต่มีแนวโน้มว่าจะรองรับโค้ดเก่าพวกเขายังคงจัดการข้อผิดพลาดและให้วิธีการจัดการข้อผิดพลาดดูเหมือนการจัดการข้อยกเว้น ยกเว้นว่าจะไม่มีการรับประกันว่าโค้ดบางตัวอาจไม่รีเซ็ตตัวจัดการข้อผิดพลาดซึ่งเป็นสิ่งที่การจัดการข้อยกเว้นถูกกำหนดไว้อย่างแม่นยำ
คำตอบสุดท้าย
ข้อผิดพลาดที่ถูกเข้ารหัสก่อนที่จะใช้การจัดการข้อยกเว้นยังคงมีข้อผิดพลาดอยู่ ข้อผิดพลาดใหม่น่าจะเป็นข้อยกเว้น แต่ไม่มีการออกแบบหรือตรรกะใดที่เป็นข้อผิดพลาดและเป็นข้อยกเว้น มันขึ้นอยู่กับสิ่งที่มีอยู่ในเวลาที่มีการเข้ารหัสและความชอบของโปรแกรมเมอร์ที่เข้ารหัส
สิ่งหนึ่งที่ต้องเพิ่มที่นี่คือเกี่ยวกับการจัดการข้อยกเว้นและข้อผิดพลาด สำหรับวัตถุประสงค์ของนักพัฒนาแอปพลิเคชันทั้งข้อผิดพลาดและข้อยกเว้นคือ "สิ่งที่ไม่ดี" ที่คุณต้องการบันทึกเพื่อเรียนรู้เกี่ยวกับปัญหาที่แอปพลิเคชันของคุณมี - เพื่อให้ลูกค้าของคุณได้รับประสบการณ์ที่ดีขึ้นในระยะยาว
ดังนั้นจึงควรเขียนตัวจัดการข้อผิดพลาดที่ทำสิ่งเดียวกับสิ่งที่คุณทำสำหรับข้อยกเว้น
ตามที่ระบุไว้ในคำตอบอื่น ๆ การตั้งค่าตัวจัดการข้อผิดพลาดไปยังตัวโยนข้อยกเว้นเป็นวิธีที่ดีที่สุดในการจัดการข้อผิดพลาดใน PHP ฉันใช้การตั้งค่าที่ง่ายกว่าเล็กน้อย:
set_error_handler(function ($errno, $errstr, $errfile, $errline ) {
if (error_reporting()) {
throw new \ErrorException($errstr, 0, $errno, $errfile, $errline);
}
});
โปรดสังเกตerror_reporting()
เช็คเพื่อเก็บไว้@
ผู้ปฏิบัติงานทำงานต่อไป นอกจากนี้ไม่จำเป็นต้องกำหนดข้อยกเว้นที่กำหนดเอง PHP มีคลาสที่ดีสำหรับสิ่งนั้น
ประโยชน์อย่างมากของการโยนข้อยกเว้นคือข้อยกเว้นมีการติดตามสแต็กที่เกี่ยวข้องดังนั้นจึงง่ายต่อการค้นหาว่าปัญหาอยู่ที่ไหน
Re: "แต่ข้อผิดพลาดและข้อยกเว้นต่างกันอย่างไร"
มีคำตอบที่ดีมากมายเกี่ยวกับความแตกต่างที่นี่ ฉันจะเพิ่มในสิ่งที่ยังไม่ได้พูดถึงนั่นคือประสิทธิภาพ โดยเฉพาะอย่างยิ่งนี่คือความแตกต่างระหว่างข้อยกเว้นการขว้างปา / การจัดการและการจัดการรหัสส่งคืน (ไม่ว่าจะสำเร็จหรือผิดพลาด) โดยปกติใน php หมายถึงการส่งคืนfalse
หรือnull
แต่สามารถให้รายละเอียดได้มากขึ้นเช่นเมื่ออัพโหลดไฟล์: http://php.net/manual/en/features.file-upload.errors.phpคุณสามารถส่งคืนอ็อบเจ็กต์ Exception !
ฉันได้แสดงประสิทธิภาพบางอย่างในภาษา / ระบบต่างๆ โดยทั่วไปการจัดการข้อยกเว้นจะช้ากว่าการตรวจสอบรหัสส่งคืนข้อผิดพลาดประมาณ 10,000 เท่า
ดังนั้นหากเป็นไปได้อย่างแน่นอนคุณต้องดำเนินการให้เสร็จสิ้นก่อนที่มันจะเริ่ม - คุณก็โชคไม่ดีเพราะไม่มีการเดินทางข้ามเวลา หากไม่มีการเดินทางข้ามเวลารหัสส่งคืนเป็นตัวเลือกที่เร็วที่สุด
แก้ไข:
PHP ได้รับการปรับให้เหมาะสมอย่างมากสำหรับการจัดการข้อยกเว้น การทดสอบในโลกแห่งความเป็นจริงแสดงให้เห็นว่าการโยนข้อยกเว้นช้ากว่าการส่งคืนค่าเพียง 2-10 เท่า
ฉันคิดว่า anwser ที่คุณกำลังมองหานั่นคือ;
ข้อผิดพลาดเป็นสิ่งมาตรฐานที่คุณคุ้นเคยเช่นการสะท้อนตัวแปร $ ที่ไม่มีอยู่จริง
ข้อยกเว้นมีเฉพาะตั้งแต่ PHP 5 เป็นต้นไปและเกิดขึ้นเมื่อจัดการกับวัตถุ
เพื่อให้ง่าย:
ข้อยกเว้นคือข้อผิดพลาดที่คุณได้รับเมื่อจัดการกับวัตถุ คำสั่ง try / catch ช่วยให้คุณสามารถทำบางสิ่งเกี่ยวกับพวกเขาได้และใช้เหมือนกับคำสั่ง if / else ลองทำสิ่งนี้หากปัญหาไม่สำคัญให้ทำเช่นนี้
หากคุณไม่ "จับ" ข้อยกเว้นก็จะกลายเป็นข้อผิดพลาดมาตรฐาน
ข้อผิดพลาดคือข้อผิดพลาดพื้นฐานของ php ซึ่งมักจะหยุดสคริปต์ของคุณ
Try / catch มักใช้สำหรับสร้างการเชื่อมต่อฐานข้อมูลเช่น PDO ซึ่งเป็นเรื่องปกติหากคุณต้องการเปลี่ยนเส้นทางสคริปต์หรือทำอย่างอื่นหากการเชื่อมต่อไม่ทำงาน แต่ถ้าคุณแค่ต้องการแสดงข้อความแสดงข้อผิดพลาดและหยุดสคริปต์คุณก็ไม่จำเป็นต้องใช้ข้อยกเว้นที่ไม่ถูกตรวจจับจะกลายเป็นข้อผิดพลาดร้ายแรง หรือคุณสามารถใช้การตั้งค่าการจัดการข้อผิดพลาดทั่วทั้งไซต์ได้เช่นกัน
หวังว่าจะช่วยได้
ใน PHP 7.1 และใหม่กว่าบล็อกcatchอาจระบุข้อยกเว้นหลายข้อโดยใช้อักขระไปป์ (|) สิ่งนี้มีประโยชน์เมื่อมีการจัดการข้อยกเว้นที่แตกต่างจากลำดับชั้นของคลาสที่เหมือนกัน
try {
// do something
} catch (Error | Exception $e) {
echo $e->getMessage();
}
ข้อยกเว้นถูกโยนรหัสโดยเจตนาโดยใช้การโยนข้อผิดพลาด ... ไม่มาก
ข้อผิดพลาดเกิดจากสิ่งที่ไม่ได้รับการจัดการโดยทั่วไป (ข้อผิดพลาด IO ข้อผิดพลาด TCP / IP ข้อผิดพลาดอ้างอิง null)
ฉันตั้งใจจะให้คุณพูดคุยเกี่ยวกับการควบคุมข้อผิดพลาดที่ผิดปกติที่สุด
ฉันสร้างตัวจัดการข้อผิดพลาดที่ดีมากในภาษาเมื่อหลายปีก่อนและแม้ว่าบางชื่อจะเปลี่ยนไป แต่หลักการของการประมวลผลข้อผิดพลาดก็เหมือนกันในปัจจุบัน ฉันมีระบบปฏิบัติการมัลติทาสกิ้งที่สร้างขึ้นเองและต้องสามารถกู้คืนจากข้อผิดพลาดของข้อมูลในทุกระดับโดยไม่มีหน่วยความจำรั่วไหลการเติบโตของสแต็กหรือล่ม ดังนั้นสิ่งที่ตามมาคือความเข้าใจของฉันว่าข้อผิดพลาดและข้อยกเว้นต้องดำเนินการอย่างไรและแตกต่างกันอย่างไร ฉันจะบอกว่าฉันไม่มีความเข้าใจว่าภายในของ try catch ทำงานอย่างไรดังนั้นฉันจึงคาดเดาถึงมาตรการบางอย่าง
สิ่งแรกที่เกิดขึ้นภายใต้ฝาครอบสำหรับการประมวลผลข้อผิดพลาดคือการกระโดดจากสถานะโปรแกรมหนึ่งไปยังอีกสถานะหนึ่ง เป็นอย่างไรบ้าง? ฉันจะไปที่นั่น
ในอดีตข้อผิดพลาดเก่ากว่าและง่ายกว่าและข้อยกเว้นใหม่กว่าและซับซ้อนและมีความสามารถมากกว่าเล็กน้อย ข้อผิดพลาดทำงานได้ดีจนกว่าคุณจะต้องแจ้งให้ทราบซึ่งเท่ากับการส่งปัญหาที่ยากให้กับหัวหน้างานของคุณ
ข้อผิดพลาดอาจเป็นตัวเลขเช่นหมายเลขข้อผิดพลาดและบางครั้งอาจมีสตริงที่เกี่ยวข้องอย่างน้อยหนึ่งสตริง ตัวอย่างเช่นหากเกิดข้อผิดพลาดในการอ่านไฟล์คุณอาจสามารถรายงานได้ว่ามันคืออะไรและอาจล้มเหลวอย่างสง่างาม (เฮย์มันเป็นขั้นตอนที่เพิ่มขึ้นจากการพังทลายเหมือนในสมัยก่อน)
สิ่งที่ไม่ได้กล่าวถึงบ่อยครั้งเกี่ยวกับข้อยกเว้นคือข้อยกเว้นคือวัตถุที่อยู่บนสแตกข้อยกเว้นพิเศษ มันเหมือนกับการส่งคืนสแต็กสำหรับโฟลว์โปรแกรม แต่มันมีสถานะส่งคืนสำหรับการลองผิดพลาดและการจับ (ฉันเคยเรียกพวกเขาว่า ePush และ ePop และ? Abort เป็นการโยนแบบมีเงื่อนไขซึ่งจะทำให้ ePop และฟื้นตัวไปสู่ระดับนั้นในขณะที่ Abort เป็นตายเต็มหรือออก)
ที่ด้านล่างของสแต็กคือข้อมูลเกี่ยวกับผู้เรียกเริ่มต้นซึ่งเป็นออบเจ็กต์ที่รู้เกี่ยวกับสถานะเมื่อเริ่มการทดลองภายนอกซึ่งมักจะเป็นตอนที่โปรแกรมของคุณเริ่มทำงาน ด้านบนหรือชั้นถัดไปบนสแต็กโดยที่เป็นเด็กและเป็นผู้ปกครองเป็นวัตถุยกเว้นของบล็อก try / catch ชั้นในถัดไป
ถ้าคุณลองใส่ลองคุณกำลังซ้อนลองด้านในที่ด้านบนของลองด้านนอก เมื่อเกิดข้อผิดพลาดในการลองด้านในและตัวจับด้านในไม่สามารถจัดการได้หรือข้อผิดพลาดถูกโยนไปยังการลองด้านนอกจากนั้นการควบคุมจะถูกส่งไปยังบล็อกการจับด้านนอก (อ็อบเจ็กต์) เพื่อดูว่าสามารถจัดการกับข้อผิดพลาดได้หรือไม่เช่น หัวหน้างานของคุณ
ดังนั้นสิ่งที่สแต็กข้อผิดพลาดนี้ทำจริงๆคือสามารถทำเครื่องหมายและเรียกคืนผังโปรแกรมและสถานะของระบบได้กล่าวอีกนัยหนึ่งก็คือจะช่วยให้โปรแกรมไม่ขัดข้องในการส่งคืนสแต็กและทำให้สิ่งอื่น ๆ (ข้อมูล) ยุ่งเหยิงเมื่อมีสิ่งผิดปกติเกิดขึ้น ดังนั้นจึงยังช่วยประหยัดสถานะของทรัพยากรอื่น ๆ เช่นพูลการจัดสรรหน่วยความจำและสามารถล้างข้อมูลได้เมื่อจับเสร็จ โดยทั่วไปสิ่งนี้อาจเป็นเรื่องที่ซับซ้อนมากและนั่นคือสาเหตุที่การจัดการข้อยกเว้นมักจะช้า โดยทั่วไปค่อนข้างจำเป็นต้องเข้าไปในบล็อกข้อยกเว้นเหล่านี้
ดังนั้นการเรียงลำดับของบล็อก try / catch จะตั้งค่าสถานะให้สามารถกลับไปเป็นได้หากสิ่งอื่น ๆ ทั้งหมดยุ่งเหยิง มันเหมือนพ่อแม่ เมื่อชีวิตของเรายุ่งเหยิงเราสามารถกลับไปนั่งตักพ่อแม่ได้และพวกเขาจะทำให้ทุกอย่างกลับมาเหมือนเดิม
หวังว่าฉันจะไม่ทำให้คุณผิดหวัง
คุณสามารถเพิ่มความคิดเห็นนี้
function doSomething()
{
/** @noinspection PhpUnhandledExceptionInspection */
throw new Exception();
}
เมื่อกำหนด set_error_handler () แล้วตัวจัดการข้อผิดพลาดจะคล้ายกับ Exception's ดูรหัสด้านล่าง:
<?php
function handleErrors( $e_code ) {
echo "error code: " . $e_code . "<br>";
}
set_error_handler( "handleErrors" );
trigger_error( "trigger a fatal error", E_USER_ERROR);
echo "after error."; //it would run if set_error_handler is defined, otherwise, it wouldn't show
?>
Errors are generally unrecoverable
<- อันนี้ไม่จริงเลยE_ERROR
และE_PARSE
เป็นข้อผิดพลาดที่ไม่สามารถกู้คืนได้ที่พบบ่อยที่สุดสองข้อ (มีอีกสองข้อ) แต่ข้อผิดพลาดส่วนใหญ่ที่คุณจะเห็นใน dev นั้นสามารถกู้คืนได้ (E_NOTICE
,E_WARNING
และคณะ) น่าเสียดายที่การจัดการข้อผิดพลาดของ PHP เป็นเรื่องที่ยุ่งเหยิง - ทุกสิ่งทำให้เกิดข้อผิดพลาดโดยไม่จำเป็น (เช่นฟังก์ชันระบบไฟล์ส่วนใหญ่เป็นต้น) โดยทั่วไปข้อยกเว้นคือ "วิธี OOP" แต่น่าเสียดายที่ OOP API ดั้งเดิมของ PHP บางตัวใช้ข้อผิดพลาดแทนข้อยกเว้น :-(