Etiket: PHP de try catch kullanımı
PHP de try catch Kullanımı
Gonderen: Ersin tarih: Sep.23, 2009, Kategori: Php Web Programlama
<?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.
*/
// 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.
*/
