Belki bir yerde PHP kılavuzda özlüyorum, ama tam olarak bir hata ve bir özel durum arasındaki fark nedir? Görebildiğim tek fark, hataları ve istisnalar farklı şekilde ele olmasıdır. Ama ne bir özel neden ve ne bir hata neden olur?
İstisnalar vardır thrown - onlar yakalanmış olması amaçlanmıştır. Hatalar genellikle kurtarılamaz. Örneğin Diyelim - Bir veritabanına bir satır eklemek olacak bir kod bloğu var. Bu çağrı (ID yinelenen) başarısız olması mümkün - Bu durumda bir "durum" bir "Hata" yapmak isteyecektir. Eğer bu satırları takarken, böyle bir şey yapabilirsiniz
try {
$row->insert();
$inserted = true;
} catch (Exception $e) {
echo "There was an error inserting the row - ".$e->getMessage();
$inserted = false;
}
echo "Some more stuff";
Program yürütme devam edecek - Eğer istisna 'yakalandı' çünkü. Yakalandığı sürece bir istisna bir hata olarak kabul edilecektir. Bu da başarısız sonra programın yürütülmesine devam etmek için izin verecektir.
Ben genellikle set_error_handler
hatayı alır ve ben sadece uğraşmak istisnalar gerekir ne olursa olsun, böylece bir istisna atar bir işleve. Artık @file_get_contents
sadece güzel ve temiz try / catch.
Ayıklama durumlarda ben de sayfa gibi bir asp.net çıkaran bir istisna işleyicisi var. Ben yolda bu ilanıyla ama istenirse daha sonra örnek kaynağı yayınlayacağız.
edit:
Söz eklenmesi gibi, kesip bir örnek yapmak için bir araya kodumu bazıları yapıştırılan ettik. Ben benim iş istasyonu üzerinde dosyaya aşağıda ayırdım you can see the results here.
<?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' );
?>
Burada eklemek için bir şey taşıma istisnalar ve hatalar hakkında. Müşterilerinizin uzun vadede daha iyi bir deneyime sahip - böylece uygulama geliştiricisi amaçla, hem de hataları ve istisnalar size uygulama olan sorunları hakkında bilgi kaydetmek istiyorum "kötü şeyler" vardır.
Bu yüzden özel durumlar için ne gibi aynı şeyi yapar bir hata işleyicisi yazmak mantıklı.
Re: "but what exactly is the difference between an error and an exception?"
Burada farklar hakkında iyi yanıtlar bir yeri vardır. Performans - Ben henüz konuştuk olmamıştır şey ekleyeceğiz. Özellikle, bu atma / elleçleme istisnalar ve bir dönüş kodu (başarı ya da bazı hata ya) işleme arasındaki fark içindir. Genellikle, php, bu false
veya null
dönmek anlamına gelir, ama onlar gibi dosya yükleme gibi daha ayrıntılı olabilir: http://php.net/manual/en/features.file-upload.errors.php Hatta bir durum nesneyi geri dönebilir !
Farklı dilleri / sistemlerinde bir kaç performans çalışır yaptık. Genel olarak konuşursak, istisna işleme bir hata dönüş kodu kontrol etmekten yaklaşık 10.000 x yavaştır.
Kesinlikle, olumlu bile başlamadan yürütülmesini bitirmek gerekiyorsa Yani, - zamanda yolculuk yok, çünkü iyi, şans bitti. Zaman yolculuğu olmadan, dönüş kodları mevcut en hızlı seçenektir.
Edit:
PHP çok istisna işleme için optimize edilmiştir. Gerçek dünya testleri bir istisna atma bir değer döndürmek yerine sadece 2-10x daha yavaş olduğunu göstermektedir.
Ben aradığınız anwser olduğunu düşünüyorum;
Errors are the standard stuff you're used to, like echoing a $variable that doesnt exist.
Exceptions are only from PHP 5 onwards and come when dealing with objects.
Bunu basit tutmak için:
Exceptions are the errors you get when dealing with objects. The try/catch statement lets you do something about them though, and is used much like the if/else statement. Try to do this, if problem, doesnt matter, do this.
Eğer "catch" bir istisna yok ise, o zaman bir standart hata dönüşür.
Hatalar genellikle komut durdurmak php TEMEL hatalardır.
Deneyin / catch sık sık komut yönlendirmek veya bağlantı işe yaramazsa başka bir şey yapmak istiyorsanız, gayet PDO gibi veritabanı bağlantıları oluşturmak için kullanılır. Sadece hata iletisi görüntüler ve komut durdurmak istiyorsanız Ama o zaman ihtiyacım yok, yakalanmamış istisna bir ölümcül hata dönüşür. Yoksa siz de bir site çapında hata işleme ayarını kullanabilirsiniz.
Umut olur
Set_error_handler () tanımlandıktan sonra, hata işleyicisi İstisna ait benzer. Aşağıdaki kod bakın:
<?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
?>
Sana hata kontrolü, en alışılmadık bir tartışma vermek niyetinde.
Ben bir dil yıl önce içine çok iyi bir hata işleyicisi inşa ve bazı isimleri değişmiş olsa da, hata işleme ilkeleri bugün aynıdır. Ben bir özel inşa multi-tasking işletim sistemi vardı ve hiçbir hafıza sızıntıları, yığın büyüme ya da çöker ile her düzeyde veri hataları kurtarmak mümkün olması gerekiyordu. Peki aşağıdaki benim hataları ve istisnalar çalışması gerektiğini nasıl anlaşılması ve nasıl farklı olduğunu. Ben sadece try catch iç yapıları nasıl bir anlayış yok diyecek, bu nedenle bazı ölçüye tahmin ediyorum.
Hata işleme için yorganın altında olur ilk şey, başka bir program durumunda atlıyor. Bu nasıl yapılır? Ben o kadar alırsınız.
Tarihsel hatalar eski ve basit, ve istisnalar yeni ve biraz daha karmaşık ve yetenekli. Eğer yönetici için zor bir sorun dağıtıp eşdeğerdir kabarcık onları, ihtiyacınız kadar hataları iyi çalışır.
Hatalar hata numaraları gibi, sayılar olmak ve bazen bir veya daha fazla ilişkili dizeleri olabilir. Bir dosya okuma hatası oluşursa, örneğin olduğunu ve muhtemelen incelikle başarısız ne bildirmek mümkün olabilir. (Hay, sadece eski günlerdeki gibi çökmesini bir adım.)
Ne sık sık istisnalar hakkında dedi değil istisnalar özel bir istisna yığın üzerinde katmanlı nesneler olmasıdır. Bu program akışı için bir dönüş yığını gibi, ama sadece hata Trys ve yakalar için bir dönüş durumunu tutar. (Ben ePush ve epoP onları aramak için kullanılan ve? DÜÞ tam bir kalıp veya çıkış iken, epoP ve bu seviyeye kurtarmak olacak bir koşullu atmak oldu.)
Yığının altındaki ilk arayan, dış deneyin program başladı çoğu zaman, hangi başlatıldığında durumu hakkında bildiği nesne hakkında bilgiler. Kadar çocuklar olmak ve aşağı veliler olmak yığına sonraki katman, bir sonraki iç try / catch bloğunun istisna nesne olduğunu, ya üstüne.
Eğer bir deneyin içinde bir denemeye koydu Eğer dış denemede üstüne iç deneyin istifleme. Bir hata iç deneyin ve ya iç yakalamak idare edemez ya da hata dış denemede atılır ortaya çıktığında, daha sonra kontrol o hatayı işleyebilir görmek için dış catch bloğu (nesne) geçirilir, yani Gözetmen.
Peki bu hata yığını gerçekten yok başka deyişle program akışı ve sistem durumunu, işaretlemek ve geri edebilmek için, bu terslik bir program diğerleri (veri) için geri dönüş yığını ve pisliği şeyler çökmesine değil sağlar. Bu yüzden de bellek ayırma havuzları gibi diğer kaynakların durumunu kaydeder ve yakalamak bittiğinde bu yüzden onları temizleyebilirsiniz. Genel olarak, bu çok karmaşık bir şey olabilir, ve istisna işleme genellikle yavaş neden olmasıdır. Genel olarak devlet biraz bu durum bloklar halinde gitmek gerekiyor.
Yani bir try / catch bloğu nevi her şeyin berbat alırsa dönmek edebilmek için bir durumunu ayarlar. Bu bir ebeveyn gibi. Hayatımızı berbat olsun biz geri bizim ebeveynin kucağına düşebilir ve hepsi doğru tekrar yapacaktır.
Sizi hayal kırıklığına uğratmadı umuyoruz.
The answer deserves talking about the elephant in the room
Hatalar çalışma zamanında bir hata durumunu ele eski yoludur. Tipik kod bazı kod yürütmeden önce set_error_handler
gibi bir şey için bir çağrı yapmak istiyorum. Assembly dili kesmeleri geleneği izleyerek. İşte bazı BASIC kodu nasıl görüneceğini olduğunu.
on error :divide_error
print 1/0
print "this won't print"
:divide_error
if errcode = X
print "divide by zero error"
Bu set_error_handler
doğru değeri ile çağrılır olacağını emin olmak zordu. Ve daha da kötüsü, bir çağrı hata işleyicisi değiştirmek istiyorsunuz, ayrı bir prosedüre yapılabilir. Ayrıca birçok kez çağrılar set_error_handler
aramalar ve işleyicileri ile serpiştirilmiş edildi. Kod hızla kontrolden çıkmak için kolay oldu. İstisna işleme sözdizimi ve iyi kod gerçekten ne yaptığını anlamlandırmasını formalizing kurtarmak için geldi.
try {
print 1/0;
print "this won't print";
} catch (DivideByZeroException $e) {
print "divide by zero error";
}
Ayrı işlevi veya yanlış hata işleyicisi çağrılarak riski. Kodu artık aynı yerde olduğu garantilidir. Ayrıca biz daha iyi hata iletileri alıyorum.
Diğer birçok dilde zaten tercih istisna işleme modeline evrimleşmiş zaman PHP, hata kaldırmaz sadece kullandı. Sonunda PHP yapımcıları durum işleme uygulanmaktadır. Ama eski kod destek olasılıkla, onlar hata işleme tutulur ve hata işleme istisna işleme gibi görünmesi için bir yol sağladı. Bunun dışında, bazı kod tam olarak ne istisna işleme sağlamak içindir edildi hata işleyicisi sıfırlamak değil hiçbir garantisi yoktur.
Final answer
Istisna işleme uygulanan önce kodlanmıştır hataları, büyük olasılıkla hala hatalar vardır. Yeni hatalar büyük olasılıkla istisnalar vardır. Ama hataları olduğu ve istisnalar olan hiçbir tasarım veya mantığı yoktur. Bu sadece kodlanmış anda mevcut idi ne dayanır ve programcı onu tercih kodlama oluyor.