예외 vs 오류?

PHP 매뉴얼에서 누락되어 있는 것 같습니다만, 에러와 예외의 차이점은 무엇입니까?유일하게 알 수 있는 차이점은 오류와 예외가 다르게 처리된다는 것입니다.그러나 예외의 원인 및 오류의 원인은 무엇입니까?



질문에 대한 답변



예외는 발생하며, 이는 잡히도록 의도되어 있습니다.일반적으로 오류는 복구할 수 없습니다.예를 들어, 데이터베이스에 행을 삽입할 코드 블록이 있다고 가정합니다.이 콜이 실패했을 가능성이 있습니다(중복 ID).이 경우는 「Error(오류)」(이 경우는 「Exception(예외가 됩니다.이러한 행을 삽입할 때 다음과 같은 작업을 수행할 수 있습니다.

try {
$row->insert();
$inserted = true; } catch (Exception $e) {
echo "There was an error inserting the row - ".$e->getMessage();
$inserted = false; }
echo "Some more stuff"; 

예외를 ‘잡았기’ 때문에 프로그램 실행이 계속됩니다.예외가 검출되지 않는 한 오류로 간주됩니다.실패 후에도 프로그램 실행을 계속할 수 있습니다.




저는 보통 오류를 받아들이고 예외를 발생시키는 함수를 사용하므로 무슨 일이 일어나도 예외만 처리할 수 있습니다.더 이상 멋지고 깔끔한 시도와 캐치만이 아닙니다.

디버깅 상황에서는 예외 핸들러를 사용하여 asp.net like 페이지를 출력합니다.저는 이것을 길에 게시하고 있지만, 요청 사항이 있으시면 나중에 예시 자료를 게시하겠습니다.

편집:

약속대로 샘플을 만들기 위해 코드를 오려 붙였습니다.

<?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코드를 실행하기 전에.어셈블리 언어 인터럽트의 전통을 따르고 있습니다.BASIC 코드는 다음과 같습니다.

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에는 그에 대한 멋진 클래스가 하나 있습니다.

예외 발생의 큰 장점은 예외에 스택트레이스가 관련되어 있기 때문에 문제가 있는 위치를 쉽게 찾을 수 있다는 것입니다.