web hata ayıklama (debug) metodolojileri ve teknikleri

Herkes bir yerlerde elbet bir hata ile karşılaşmıştır.

Düşünsenize, o hatayı nasıl giderdiniz? Bir şekilde gidermişsinizdir değil mi?

Hata ayıklamanın da yöntemleri mevcut. Bunları, kendim tecrübe ettiğim kadarını (genelde web ile ilgili) sizlerle paylaşmak istiyorum. Bunlardan bazılarını mecbur yapacağız, bazılarını ise alternatifleri arasından tercih edip yapacağız.

Örnek Senaryo : Sitenizde bir kısmında hata meydana geldiği, bir tuşun işlevini yerine getirmediği belirtilmiş.

Mecburen siteye girip, hatayı kendimiz elde etmeye çalışırız. Bu çok önemlidir. Elde edemiyorsak, hatayı raporlayan kişiyle iletişime geçmemiz gerekiyor.
* Bir log yapısı ile bu hata loglanmış mı diye kontrol ederiz. hata loglanmış ise, logda yeterli bilgi muhtemelen vardır, buna göre aşağıdaki yöntemlere geçeriz.

Hata ayıklama için çalışma Şekilleri

  • Canlıda Çalışma : İnsan mecburda kalınca bazen canlıda çalışması gerekebiliyor diyebilirsiniz. Ancak benim bu konudaki tavrım net, canlıda bir şey çalışacak hale getirmeyin kendinizi. Yine de çalışmanız gerekiyorsa bu noktada, Sitenin hizmetini $_SERVER[“REMOTE_ADDR”] yardımıyla sizin IP niz dışındakilere kapatınız. Sizin IP’niz dışındakilere güncelleme çalışması yapıldığını belirtiniz.
  • Test ortamında çalışma : Gerçek Projenin aynısını kendi bilgisayarınıza veya test ortamınıza aktararak hatayı orada elde edip, düzeltmeye başlayın.
  1. Yayını Durdurun : Eğer hatanın nüksetmesi kritik önem arz ediyorsa, yayını ivedilikle durdurun. Ziyaretçilere bakım çalışması bilgisi verin. Bu müşterilerinize veya ziyaretçilerinize sizin hatadan haberdar olduğunuzu ve üzerinde çalıştığınızı göstererek, size çalışmak için zaman sağlayacaktır.
  2. Mevcut durumu Garanti altına alın : Hem dosyaları hem de veritabanını daha kötü bir senaryo için yedek alın. Yedek aldığınız veriler, önceki yedeklerin üzerine yazmamasına özen gösterin. Sıkışırsanız, veya daha kötü bir senaryo oluşursa en son state’e (hatanın oluştuğu ilk noktaya) geri döneceksiniz.
  3. Hata mesajlarını artırın , kapalıysa açın : Php hata mesajlarını ve Loglama hizmetlerini yazılım katmanından artırabiliyorsanız artırın. Kapalıysa açın.
  4. Sistemi kurtarmayı aşamalandırın : Hatayı tespit ettikten sonra ne yapacağınızı düşünmeniz gerekir. Madde madde bunları çıkarın. Mümkünse her maddeden sonra yedek alıp, durumu garanti altına alın.
  5. Yazılım hizmetlerini durdurun : Örneğin, yazılımınızda bir mail atma servii var. Siz hatayı tespit ederken sistem herkese mail atıyor olabilir. Bunun önüne geçmek için bu tarz hizmetleri durdurun veya sadece kendinizi ilgilendirecek şekilde düzenleyin.
  6. Log ekleyin : Hatayı tespit etmek için loglama yapın, varsa eğer, loglanan veri miktarını artırıp, logu detaylandırın.
  7. Çözümü Uygulayın : Bazı hatalar barizdir. Bazı hatalar ise bazen oluşur ki en beter hatalar bu şekilde ara-sıra oluşan hatalardır. Çözümü uygulayıp durum değerlendirmesi yapın.
  8. Sorunun çözüldüğünü Teyid edip, siteyi ayağa kaldırın : Artık işlemler bittiğinde, hatanın tekrar oluşmaması için tedbirinizi de alın. Ve siteyi tekrar yayına alın.
  9. Fazladan almış olduğunuz yedekler ile ilgilenin. (Dilerseniz silin, dilerseniz bir kaç gün sonra silmek üzere bir cronjob oluşturun)

Symfony2- FOSFacebook – Facebook needs the CURL PHP Extension Hatasi

Symfony2’de FOSFaceBookBundle yüklemesi yaptıktan sonra, herhangi bir konsol komutu çağırmaya çalıştığımda aşağıdaki hatayı alıyordum.

[Exception] Facebook needs the CURL PHP extension.

Biraz araştırdığımda, WAMP gibi 3’ü bir yerde kurulumlarda Apache tarafından kullanılan php.ini dosyası ile konsoldan aşağıdaki şekilde çağırdığımız php komutunun farklı php.ini dosyası kullandığını öğrendim.

php app/console container:debug


Yani wamp’ın menüsünü kullanarak curl uzantısını aktifleştirseniz bile aslında konsoldan çağrılan php programının kullandığı php.ini değişmiyor. WAMP için örnek vermek gerekirse, C:\wamp\bin\php\php5.3.8 klasöründeki php.ini dosyasını şu şekilde düzenlemek gerekiyor:

;extension=php_curl.dll
extension=php_curl.dll

PHP curl ile istek örnegi (php curl example)

CURL basit manada bir bot yapmak için kullanılabilir. Veyw webservis altyapısı olmayan yapılar için bir alternatif sağlayabilir.
file_get_contents ile yapacağınız url isteklerinde (bunda allow_url_fopen açık olması lazım) kodunuza herhangi bir timeout koyamadığımız için sıkıntılı bir durum oluşabilir. CPU kullanımımız tehlikeye girebilir. Burada da yine curl, güçlü alternatif olarak karşımıza çıkmaktadır.

Aşağıda basit bir CURL isteği yapabilmek için gerekli kodları göreceksiniz. Bunun ile örneğin www.google.com’u request ederseniz, ilgili sayfanın içeriğini alabileceksiniz.
Yanlarında comment ile açıklamalarını yazdım

$temp = array("a"=>1, "b"=>2);
$postdata = http_build_query($temp);

$ch = curl_init();
curl_setopt($ch, CURLOPT_POST, true); //POST Metodu kullanarak verileri gönder
curl_setopt($ch, CURLOPT_HEADER, false); //Serverdan gelen Header bilgilerini önemseme.
curl_setopt($ch, CURLOPT_URL, "http://www.domain.com"); //Bağlanacağı URL
curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata); //POST verilerinin querystring hali. Gönderime hazır!
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); //Transfer sonuçlarını return et. Onları kullanacağım!
curl_setopt($ch, CURLOPT_TIMEOUT, 20); //20 saniyede işini bitiremezsen timeout ol.
$data = curl_exec($ch);
curl_close($ch);

echo $data;

NOT : php_curl php eklentinizin açık olması gerekiyor. php.ini’de yer alır kendisi. Wamptan sırayla Wamp simgesi -> PHP ->PHP extensions-> php_curl a tıklayarak açabilirsiniz. Ya da php.ini nize ekleyebilirsiniz.

php 5.4 Diziler (Array) – Php Yeni Özellikler

Php 5.4 ün içindeki yeniliklerden biri de dizilerdeki (array’lerdeki) kısaltılmış kullanım özelliğidir. Aşağıda bu kullanım ile ilgili bir örnek verdim.

//Php 5.4'ten önce
< ?php
$array = array(
    "key1" => "value1",
    "key2" => "value2",
);

// PHP 5.4 'ten itibaren
$array = [
    "key1" => "value1",
    "key2" => "value2",
];

Ayrıca geri döndürdüğü (return değeri) array olan fonksiyonlarda da eskiden uğraştığımız ilk önce değişkene atama çilesi, php 5.4 ile bitmiş olacak.
Artık fonksiyon çağırdıktan sonra doğrudan köşeli parantez ile istediğimiz indisi alabiliriz.

Not : Bu durum optimize çalışmayan metodlar, fonksiyonlar yazmanıza sebep olabilir, bu konuda sistemin gereksiz enerji harcamamasına dikkat ediniz.

< ?php
function getArray() {
    return array(1, 2, 3);
}
// php 5.4'ten önce
$tmp = getArray();
$secondElement = $tmp[1];

//PHP 5.4'ten itibaren
$secondElement = getArray()[1];

// veya
list(, $secondElement) = getArray();
?>

php 5.4 Traits – Php Yeni Özellikler

Php 5.4 ile ilgili yeni özelliklerden bir tanesi trait kavramı. trait kavramının bir Türkçe karşılığını bulamadım.

Bir sınıfın birden çok miras alması durumu php’de olmayan bir durum. Bildiğim kadarıyla sadece C++’ta var.

Traitler bizi birden çok miras alma durumlarına benzer ihtiyaçları çözmek için getirilmiş bir yenilik gibi gözüküyor.

Normalde 2 adet farklı sınıfımızın aynı fonksiyonu kullanması gerekiyorsa, o iki sınıfın ata sınıfı olarak tanımlar, o metodu onun içine koyar, 2 farklı sınıfımızı da ondan türeterek bu konuyu halledebilirdik.

Peki ya, zaten extend ettiğimiz bir sınıf var ise, ve de ekleyeceğimiz metod ile alakasız ise o zaman ne yapacağız?

Bu durumda duplicate (tekrarlayan) kod yazmamak için traitleri kullanmamız faydalı olabilir.

Php’nin sitesindeki örneği vereyim.

< ?php
trait ezcReflectionReturnInfo {
    public function getReturnType() { /*1*/ }
    public function getReturnDescription() { /*2*/ }
}

class ezcReflectionMethod extends ReflectionMethod {
    use ezcReflectionReturnInfo;
    /* ..bişeyler bişeyler... */
}

class ezcReflectionFunction extends ReflectionFunction {
    use ezcReflectionReturnInfo;
    /* .. bişeyler bişeyler... */
}
?>

Yukarıda 1 trait , 2 sınıf mevcut. 2 sınıfın extend ettiği bir sınıf daha var. (bu kodda yok) Bu durumda 2 farklı sınıfta, ana sınıfta olmayan yeni metodlar istiyorsam, sınıfın içinde use ecReflectionReturnInfo diyerek bu traiti sınıf içinde kullanılabilir hale getirmiş oluyorum.

Yani bu trait içinde yazılı metodlar sanki sınıfın çinde yazılmış public functionlar olarak davranacaklardır.

O yüzden trait kelimesini Türkçe’ye “sınıfçık” olarak çeviriyorum 🙂

Bu mantıkta traitler içinde değişken, static function, vb.. gibi şeyler tanımlayabiliyoruz. Ayrıca hangisini hangisinin yerine kullanacağının ayarlamalarını da detaylı yapabiliyoruz.

Henüz deneyemediğim ve yazılımda ihtiyaç olarak ne şekilde kullanabilceğimin tam oturmadığı diğer bu konular hakkında okumaya devam etmek için php’nin kendi sitesinden devame edebilirsiniz.

http://tr2.php.net/traits