Burhan T. 5 dakikalık okuma
June 3, 2017

PHP dilinin hata yönetim sistemi üzerine eleştirel bir bakış.

Ben şanslıydım. İlk öğrendiğim dil PHP değildi ve onunla programlama dünyasına girmemiştim.

Şimdi arkanıza yaslanın.Birlikte bir kaç şey hayal edelim.

Hayal ettiğimiz kişi 19 yaşında Furkan adında biri olsun. Furkan, PHP dili ile bilgisayar programlama dünyasına adım atıyor ve bu dille çok kısa zamanda harikalar oluşturmaya başlıyor. Nedeni basit; PHP’yi öğrenmek çok kolay ve içerisinde barındırdığı olağanüstü fonksiyonlarla webde yapamayacağınız iş yok. Linux sunucular ucuz ve PHP & MySql uyumu mükemmel. Daha ne isteyeceğiz, değil mi ?

Şimdi gerçek hayata dönüp eleştirilere geçelim. Tecrübelerimi yazarak başlamak istiyorum.

18 yıldır programlama dili ile uğraşıyorum. Bu alanda bir şeyler yapmaya 13 yaşında Turbo Pascal dili ile başladım. Sonra Turbo C, QBasic,Visual Basic, Delphi, dotNET dünyası derken sonra PHP ile de web programlama da soluğu almaya başladım. Ben şanslıydım. İlk öğrendiğim dil PHP değildi ve onunla programlama dünyasına girmemiştim.

Kökenim eskiydi, Pointer nedir biliyordum. Nesneye dayalı programlamanın pointer yumağı bir programlama felsefesi olduğunu iyi kavramıştım. MS-DOS dönemlerindeki 64 KB sınırında **TSR **(Terminate but Stay Resident) tarzı programlar yapmasını öğrenmiştim. Derken günümüze kadar geldik…

Şimdi PHP ile webde her şey yapabiliyorum ve bu dili seviyorum; ama bir şeyler yaparken kızdığım durumlarda oluyor. Bunları sırayla yazayım:

  1. PHP dili, sizin programlama dil mantığını anlamanızı maalesef baltalıyor. Eğer programlama dili öğrenmede yeniyseniz bu kötü. Çünkü programlama mantığını doğru düzgün öğrenemiyorsunuz. Sebebi birden fazla. Hızlıca bahsedeyim;

  2. Tip tanımlı bir dil değil. $veri=’Ahmet’; $sayi=12; de işini gör. Böylece birçok profesyonel dilde bulunan tip kavramından yoksun oluyorsunuz. PHP her şeyi sizin için yapıyor. PHP’yi diğer tip tanımlı dillerden biraz yavaş yapan nedenlerden biri de budur. Çünkü sistem dinamik olarak bu işi çalışma zamanında tespit edip yapıyor. Ama tip tanımlı bir dil olsaydı siz; veri:string; sayı:integer; diye tipini belirtecektiniz. Program tekrardan çalışma anında tipini bulmak için uğraşmayacaktı.

  3. Derlemeden ziyada yorumlayıcı ile çalışan bir dil olduğundan bunun dezavantajından tadıyorsunuz. Hız gibi.

  4. Nesneye Dayalı Programlama yapısını bir Delphi veya C# ile kıyaslarsam çocuk oyuncağı gibi çok basit ve sınırlı kalıyor.

  5. Hata yakalama sistemi çok kötü. Asıl bu yazıyı kaleme alma sebebim PHP’deki hata yakalama ile yaşadığım kötü bir deneyimimdir. Şimdi bu mevzuyu açarak derdimi daha iyi anlatmak istiyorum:

Geçenlerde yazdığım bir programda şöyle bir satır vardı:

    $item = array ( 
        'title' => $node->getElementsByTagName('title')->item(0)->nodeValue,
        'desc' => $node->getElementsByTagName('description')->item(0)->nodeValue,
        'link' => $node->getElementsByTagName('link')->item(0)->nodeValue,
        'date' => $node->getElementsByTagName('pubDate')->item(0)->nodeValue,
        'author' => $node->getElementsByTagName('author')->item(0)->nodeValue,
        'image' => $node->getElementsByTagName('enclosure')->item(0)->getAttribute('url'),
        'id' => randomPassword(),
        );

Voice of Amerika’nın RSS’inden XML formatında en son haberleri çekmekti. Sistem çalışıyordu. Gel gör ki bazı haberlere resim eklemediklerini kötü bir hata tecrübesi ile gördüm. PHP kodum:

'image' => $node->getElementsByTagName('enclosure')->item(0)->getAttribute('url'),

yukarıdaki satıdan sonra çalışmıyordu. Dedim ki PHP’de bir hata yakalama yaparak ipleri elimize alalım. Düz bir mantıkla şöyle bir şeyler yaptım:

try
{
    $image = $node->getElementsByTagName('enclosure')->item(0)->getAttribute('url');
}
catch(Exception $e)
{
    $image='';
}

çalıştırdım. Sonuç ? Hüsran. Çalışmadı. PHP Manual dökümantasyona başvurdum. Oradaki bilgileri okudum.

Şöyle yapmalıymışım:

try
{
$image = $node->getElementsByTagName('enclosure')->item(0)->getAttribute('url');
 if ($image ===null) {
        throw new Exception('error');

}
catch(Exception $e)
{
    $image='';
}

Ulan ne gerek var o zaman try catch bloğuna. Direkt:

$image = $node->getElementsByTagName('enclosure')->item(0)->getAttribute('url');
 if ($image ===null) {
$image='';
}

yapar ve kurtulurdum. Yook oda olmadı. Çatır çatır hata vermeye devam etti. PHP’de sevdiğim bir özellik vardır. “@” işareti. Bunla hataları es geçebiliyorsun. Onunla deneyerek yapayım dedim:

$image = @$node->getElementsByTagName('enclosure')->item(0)->getAttribute('url');
 if ($image ===null) {
$image='';
}

Amacım yine programalama mantığı açısından eğer bir hata ile karşılaşılırsa es geç ve null değer ata mantığıydı. Ne oldu biliyor musunuz? Ekrana hata yazmadı ama program düzgün sonlanmadığı için javascript komutlarım çalışmıyordu. Çok sinirlenmiştim. Tekrar stackoverflow ile php user manual’ı arasında mekik dokuyarak hatayı bulmaya devam ettim. Sonra şöyle bir şey yaptım. >getAttribute(‘url’); özelliğini kaldırıp deneyeyim bakayım ve:

$image = @$node->getElementsByTagName('enclosure')->item(0);
 if ($image ===null) {
$image='';
}

program çalışmaya başladı. Vayyy ! PHP ile boktan bir hatayı kontrol altına almayı başardım; ama neden ilk yaptığım koddakinde olmadı da en son yaptığımda olduğunu anlayamadım. Merakımdan araştırmaya devam dedim. Sorunumu çözmüştüm ama merak işte…

Ve şöyle bir şey öğrendim. try catch ile sadece exception tarzı hataları yakalayabiliyormuşum. Fatal error dedikleri öldürücü hatalar burada işlemiyormuş; ama halen 2 sinde de nesne olmamasına rağmen birinde ölümcül hata verip diğerinde vermediğini çözemedim. Belki bir bug bile olabilir diye geçti içimden.

Yuh dedim be ! Ya kardeş, bunun fatalı, exceptionu olur mu ? Eğer bu durumu Delphi ile yapsaydım şöyle:

try
//kodun da hata çıkarsa
except

// burada yazanı işlet.
end;

Ne durumda olursa olsun çatır çatır çalışırdı. En öldürücü hataları bile çok rahat kontrol edebilirdik. Hatta:

Try
  Try
    ...
  Except
    ...
  End;
Finally
  ...  // ne olursa ol, program sonlanırken muhakkak burada yazılan kodu çalıştır.
End;

şu try finally end ile hafızada oluşacak açıkları şıp diye engelleyebilirdim. Bir nesne var ve o nesnenin bir özelliğinde ölümcül hata verdi. finally bloğu ile program sonlanırken veya ben kapatırken o nesneyi hafızadan silebilirdim…

PHP’de bu güzelim özellikleri gözüm aradı ama yok. Bunun yerine işi dolandırıp öyle dolambaçlı özellikler koymuşlar ki neymiş program sonlanırken bir nesneyi hafızada tetiklemesi için kaydettirebilirmişim. Şöyle:

register_shutdown_function( "hata_yakala" );

function hata_yakala() {
// kodları yaz..
  }

Beyler bu kabul edilemez bir durum. Buradan şu sonucu çıkartabilirim ki PHP’de hata kontrollerinin kolay ve daha efektif olması için PHP Zend’in daha çok fırın ekmek yemesi lazım…


Etiketler: