23 Sep

PHP de try catch Kullanımı

<?php
// bunu belirttik, çünkü tarayıcıda türkçe karakter problemi yaşamak istemiyoruz
header ( 'Content-type:text/html; charset=UTF8' );
/**
 * örneklerimizde kullanacağımız iki tablo
 * bunları siz kendi sunucunuzda çalıştırıp
 * örnekleri uygulamak için kullanabilirsiniz
 */


$_veritabani = 'create database testdb';

$kullaniciTablosu = 'CREATE TABLE `testdb`.`user` (
`id` INTEGER  NOT NULL AUTO_INCREMENT,
`name` VARCHAR(25)  NOT NULL,
`password` VARCHAR(32)  NOT NULL,
PRIMARY KEY (`id`)
)
ENGINE = InnoDB;'
;

$gonderiTablosu = 'CREATE TABLE `testdb`.`user_posts` (
`id` INTEGER  NOT NULL AUTO_INCREMENT,
`user_id` INTEGER  NOT NULL,
`title` VARCHAR(255)  NOT NULL,
`content` TEXT  NOT NULL,
PRIMARY KEY (`id`)
)
ENGINE = InnoDB;'
;

$kullanici = 'kull';
$sifre = 'sifr';
$sorgu1 = 'delete from user where id=2';
$sorgu2 = 'delete from user_posts where user_id=2';
/**
 *
 *try catch , daha önce de kısaca değindiğim gibi bir hata yönetim mekanizmasıdır.
 *Uygulamnımızın kararlılığını arttırmak için hatayı yakalamak ve onu işlemek de önemlidir.
 *Tabi hatayı yakalamak ve işlemek sadece try catch ile olabilen birşey değil,
 * ama neden kullanmalı ona değinmeye çalışacağım.
 *
 * Normal kullanım
 */


$baglanti = mysql_connect ( 'localhost', $kullanici, $sifre );
if ($baglanti)
{
   if (! mysql_select_db ( 'testdb', $baglanti ))
      die ( 'Veritabanı seçemedi' );
} else
{
   die ( 'veritabanına bağlanamadı' );
}
/*
* Yeri gelmişken yazalım. mysql_unbuffered_query fonksiyonu, çalıştıracağınız sorgudan geriye
* veri döndürmeyecekseniz , işinize yarayabilecek bir fonksiyondur. Bu fonksiyon geriye
* bir sonuç kümesi döndürmez , onun yerine sorgunun sağlıklı çalışıp çalışmadığını
* belirten bir boolean değer döndürür.Böylece değer döndürmeyen sorgularınız daha hızlı çalışır.
*/

if (mysql_unbuffered_query ( $sorgu1, $baglanti ))
{
   if (mysql_unbuffered_query ( $sorgu2, $baglanti ))
   {
      echo 'Sorgular başarı ile çalıştırıldı';
   } else
   {
      echo 'sorgu 2 çalışmadı';
   }
} else
{
   echo 'sorgu 1 çalışmadı';
}

mysql_close ( $baglanti );

/**
 * Buraya kadar heşey normal gibi görünüyor. Normal olarak kabul de edebiliriz, kod karmaşasını saymaz isek.
 * Peki gelin bir de böyle deniyelim :
 */


try
{
   $veritabani = new PDO ( 'mysql:dbname=testdb;host=127.0.0.1', $kullanici, $sifre );
   $veritabani->setAttribute ( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
   $veritabani->beginTransaction ();
   try
   {
      if ($veritabani->exec ( $sorgu1 ) == 0)
         
         throw new Exception ( 'birinci sorgu çalışmadı' );
      echo 'sorgu 1 çalıştı <br />;';
      if ($veritabani->exec ( $sorgu2 ) == 0)
         
         throw new Exception ( 'ikinci sorgu çalışmadı' );
      echo 'sorgu 2 çalıştı';
      $veritabani->commit ();
   } catch ( Exception $istisna )
   {
      echo $istisna->getMessage ();
      $veritabani->rollBack ();
   }
} catch ( Exception $baglantiIstistisnasi )
{
   echo 'bağlantı sağlanamadı sebep : <br /><b>' . $baglantiIstistisnasi->getMessage () . '</b>';
}

/**
* Şimdi kod daha sade değil mi ? Gerçi bakıma ihtiyacı olsa da, bir önceki örneğimizden daha anlaşılır ve daha işlevsel.
* Şimdi gelelim işleyişe. Kod try bloğuna girer ve bir istisna (Exceptipon) fırlatıladılmadıkça o blok çalışmasına devam eder.
* Eğer başarılı olmuşsa kendisini takip eden catch bloğunu ( catch() {} ) es geçerek bir alt satıra geçer.
* Ama eğer try bloğu içerisinde bir Exception fırlatılır ise o zaman kod, Exception fırlatılan satırdan sonra (örneğin ilk sorgumuz
* çalışmadığında biz bir istisna fırlatıyoruz, böylece try bloku içerisindeki o satırdan sonraki kodlar çalıştırılmaz)
* catch bloğuna geçer.
*
* Bunu şöyle deneyebilirsiniz, bu örneği alıp kaydedin ve veritabanını oluşturun. Sonra da hiçbir kayıt girmeden örneği çalıştırın.
* Bu durumda size "birinci sorgu çalışmadı" diye bir mesaj verecek. Böylce yukarıda değindiğimiz gibi, try blokundaki kod exception
* fırlatılan satıra kadar çalışır , exception fırlatılırsa exception dan sonraki satır çalışmaz ve catch bloğuna geçer (böylece biz
* birinci sorgu çalıştı mesajını görmeyiz) ve bu blok çalışır.
*
* try catch işleminin sağlıklı yürüyebilmesi için, Exception fırlatan bir mekanizmanın olması gerekir. PHP 5. versiyonundan sonra
* nesne yönemli programlamaya  ağırlık verildiğinden, eski nesnelerin çoğu ile kullanmak mümkün değildir.
* Kimi yeni nesneler ve sizin kendi oluşturacağınız nesneler ile try catch mekanizmasını kullanabilirsiniz.
*
* Bu bölümde son olarak finally e değinmek istiyorum. Diğer dillerde (Java , C# gibi) try catch blokunun son halkası olan finally
* mevcuttur, bu blok ister try bloku çalışsın isterse catch bloku çalışsın buna bakılmaksızın en son ve her halukarda çalıştırılan
* bir bloktur. Ama bu işlev ne yazıkki php de mevcut değil henüz. Bu yüzden kısaca değinip geçiyorum.
*
* Bundan sonraki bölümde bu örneğimizden devam ederek, transaction e değinmeye çalışacağım. Sonrasında Exception nesnesini biraz açmaya
* çalışacağım. Eksik,hatalı veya karmaşık anlatılmış yerler konusunda yorum yazarak uyarır iseniz mutluluk duyarım.
*
* Güzel günler dileği ile.
*/