Bir fonksiyonu özel değerlerine dönmek zorunda kalmadan başarısızlık rapor böylece bir istisna fikirdir. Siz eski PHP, bir fonksiyonu bunu söyleyebiliriz tek yolu bir sorun false
veya -1
gibi bazı özel değer dönerek vardı. Bu hoş değil. Örneğin,) ben file_get_contents bir varyantını (yazıyorum varsayalım.
Pozitif bir tamsayı tarafından temsil - Tipik dönüş değeri bir kolu olduğunu. Eğer belirtilen dosya bulunamadı veya belirtilen dosya okunabilir değildi: Ancak, ben karşılaşma iki temel sorun vardır. Kolları olumlu çünkü - - bir hata belirtmek için ben negatif bir sayı döndürür olabilir hata belirli bir neden ilişkilendirir. Adlı dosya yoktu ve -2 dosya okunabilir değildi anlamına gelir ki -1 diyelim.
Şimdi bir sorun var -1 ve -2 yapamaz doğal olarak mean anything kodunu okuma birisi. Bunu düzeltmek için biz küresel sabitleri file_not_found ve FILE_NOT_READABLE tanıtmak. Biraz çıkan kodu görelim.
<?php
define('FILE_NOT_FOUND', -1);
define('FILE_NOT_READABLE', -2);
function my_file_get_contents($file) {
// blah blah blah
}
$friendListFile = getDefaultFriendListFile();
$result = my_file_get_contents($friendListFile);
if ($result == FILE_NOT_FOUND) {
deleteFriendListFromMenu();
} elseif ($result == FILE_NOT_READABLE) {
alertUserAboutPermissionProblem();
} else {
useFriendList($result);
}
Biz act accordingly sorun gerçekten ne olabilir, farklı hata kodları alarak. Bu işlevsellik iyi ve güzel olduğunu. Sorun purely kod okur nasıl olduğunu.
$result
bir horrible değişken adıdır. Değişken isimleri $friendListFile
gibi, açıklayıcı ve belirgin olmalıdır. Için gerçek adı $result
, sadece çok uzun, biz iki anlamı olan tek bir değişken yüklenme nasıl examplifies $fileContentsOrErrorCode
hangi olmasıdır. Sen, hiç, aynı veri iki şey demek istiyorum asla. Biz istiyoruz, ayrı bir $errorCode
ve $fileContents
!
Peki bu soruna alabilirim? Bazı PHP kütüphaneleri kullanmış biri değil-gerçekten-bir-bir çözüm bir sorunla karşılaşırsanız eğer onların my_file_get_contents()
gibi fonksiyonlar false
return sahip olmaktır. Sorun aslında biz bunun yerine diyoruz ne oldu disambiguate my_file_get_contents_getError()
. Bu almost çalışır.
define('FILE_OKAY', 0);
define('FILE_NOT_FOUND', -1);
define('FILE_NOT_READABLE', -2);
$my_file_get_contents_error = FILE_OKAY;
function my_file_get_contents_getError() {
// blah blah blah
}
function my_file_get_contents($file) {
global $my_file_get_contents_error;
// blah blah blah
// whoa, an error? return false and store the error code in
// $my_file_get_contents_error
// no error? set $my_file_get_contents_error to FILE_OKAY
}
$friendListFile = getDefaultFriendListFile();
$result = my_file_get_contents($friendListFile);
if (my_file_get_contents_getError() == FILE_NOT_FOUND) {
deleteFriendListFromMenu();
} elseif (my_file_get_contents_getError() == FILE_NOT_READABLE) {
alertUserAboutPermissionProblem();
} elseif (my_file_get_contents_getError() == FILE_OKAY) {
useFriendList($result);
} else {
die('I have no idea what happened. my_file_get_contents_getError() returns '
. my_file_get_contents_getError()
);
}
Bir not olarak, evet, biz bir global değişken ve diğer bu tür ufak tefek kaçınarak çok daha iyi bir iş yapabilirsiniz. Bu fındık-ve-cıvata gösteri düşünün.
Biz still $fileContentsOrFalseIfError
daha $result
bir şey diyemem. Bu sorun sabit olmamıştır.
Ben şimdi önceki örnekte fark olabilir bir sorunu pekiştirmiştir. Bizde ne varsa hata kodlarının tümünü kapsayacak değil mi? Bir programcı -3 kod olması gerektiğine karar verirse biz aslında bunu tespit değildi! Biz $result
emin bir hata kodu değildi yapmak için bir dize ise teslim olabilirdi, ama biz doğru, gerçekten PHP türleri hakkında bakım gerekiyordu değil mi? Şimdi biz my_file_get_contents_getError()
bir başarı kodu dahil etmek hiç sorun değil, ikinci bir dönüş değeri yararlanabilirler.
Ortaya çıkan yepyeni bir problem var. Birini düzeltmek ve eh üç tane daha bulmak? Yeni bir sorun, yalnızca en-son hata kodu muhafaza edilebilir olmasıdır. Bu terribly kırılgan! Başka bir şey aramalar my_file_get_contents()
Eğer hata kodu ile anlaşma önce ise, kendi kod senin üzerine yazılır!
Gah, şimdi biz size my_file_get_contents_getError () dan dönüş değeri ile anlaşma önce aramak için güvenli olmayan fonksiyonların bir listesini tutmak gerekir. Bunu yapmazsanız, size her zaman size ait hata kodu kurtarmak için my_file_get_contents()
hemen sonra my_file_get_contents_getError()
çağrı bir ad-hoc kodlama kongre olarak tutmak zorunda o gizemli yazılır önce.
Bekle! Neden sadece bizim arayanlar için tanımlayıcı dağıtmak değil mi? Kullanmak için my_file_get_contents()
şimdi tüm diğer arayanlar ile disambiguate bazı dizi için create_my_file_get_contents_handle()
sormak gerekir. Şimdi my_file_get_contents($myHandle, $myFile)
arayabilir ve hata kodu sadece sizin için özel bir yerde saklanabilir. Şimdi my_file_get_contents_getError($myHandle)
sen, o özel bir yere ulaşmak için hata kodunu almak ve hiç kimse senin ayak bastı gelmiştir olabilir çağırdığınızda.
Birçok arayanlar varsa Er, ama biz zillions etrafta gereksiz hata kodları sahip istemiyorum. Bu yüzden bazı bellek özgür olabilir biz daha onlar bitince destroy_my_file_get_contents_handle($myHandle)
aramak için kullanıcılara sormak vardı.
Ben bu ey eski PHP mantralar için very tanıdık duygu umuyoruz.
This is all so crazy, just make it simple, please!
language hataları tepki daha iyi bir mekanizma desteklenen eğer ne demek istiyorsunuz? Açıkçası, mevcut araçları ile bazı çözüm oluşturmak için çalışıyoruz, kafa karıştırıcı, iğrenç ve hata eğilimli.
Istisnalarını girin!
<?php
class FileNotFoundException extends Exception {}
class FileNotReadableException extends Exception {}
function my_file_get_contents($file) {
if (!is_file($file)) {
throw new FileNotFoundException($file);
} elseif (!is_readable($file)) {
throw new FileNotReadableException($file);
} else {
// blah blah blah
}
}
$friendListFile = getDefaultFriendListFile();
try {
$fileContents = my_file_get_contents($friendListFile);
useFriendList($fileContents);
} catch (FileNotFoundException $e) {
deleteFriendListFromMenu();
} catch (FileNotReadableException $e) {
alertUserAboutPermissionProblem();
}
Özel dönüş değerleri ve kolları ve kodlama sözleşmeler ani bizim eski baş ağrısı tüm tedavi edilmiştir!
Biz şimdi gerçekten $result
$fileContents
için yeniden adlandırabilirsiniz. my_file_get_contents()
bir sorunu varsa, atama tamamen durduruldu ve biz sağ aşağı uygun catch bloğuna atlayacak. Only if there is no error biz bile $fileContents
bir değer vererek ya da useFriendList()
arama hakkında düşünüyorum.
Artık biz birbirimizin hata kodları ile ilgili adım birden arayanlar tarafından boğulmuş! Hata ortaya çıkarsa my_file_get_contents her () çağrısı, kendi istisnalarını örneğini.
Hafıza problemleri yok! Çöp toplayıcı mutlulukla bunu düşünmeden, artık kullanılan istisna nesneleri temizlemek olacaktır. Ye elle kolu yok hatırlamak zorunda eski kolu sistemini kullanarak diye bellekte sonsuza pusuda var.
Istisnalar birçok diğer faydaları ve özellikleri vardır. Ben şiddetle bu konuda bilgi edinmek için diğer kaynaklara bakarak öneririz. Özellikle ilginç bazı arayan onları nasıl kabarcık kadar yürütme yığın yakalayabilirsiniz kadar. Ayrıca ilginç Eğer, bir özel durum yakalamak sorunu çözmek için deneyin ve sonra durum eğer değil rethrow nasıl olduğunu. Istisnalar nesneler olduğunu unutmayın! Bununla elde edilecek esneklik yükler vardır. Kimse yakalamak olduğunu istisnalar için, istisna işleyici içine bakmak.
Soruyu cevaplamak benim niyet biz istisnaları neden ihtiyaç göstermekti. Bunu yaparak, bunu biz onlarla çözebiliriz ne sorunlar anlaması kolaydır umuyoruz.