September, 2009 Arþivi

“call-time pass-by-reference” is deprecated çözümü

Gonderen: Ersin tarih: Sep.24, 2009, Kategori: İpucu

Bu da PHP4 den PHP5 e geçerken karşılaşılması muhtemel bir problemdir . PHP5 de nesneyi parametre olarak göndermek yeterli, PHP5 de nesne her zaman referans olarak gönderildiği için PHP4 deki gibi & işaretini kullanmanıza gerek yok.

function ipucu(&$a){
echo $a->test();
}

yukarıdaki kullanım PHP5 de “call-time pass-by-reference” is deprecated görmenize sebep olur. DoÄŸru kullanımı aÅŸağıdaki gibidir :

function ipucu($a){
echo $a->test();
}

Yorum yap : devami...

“headers already sent” problemi çözümü

Gonderen: Ersin tarih: Sep.24, 2009, Kategori: İpucu

Çok karşılaşılan, artık birçoğumuzun kanıksadığı bir olgu. Çözümü :

Yol 1:
php.ini de
output_buffering=off
anahtarını bulup
output_buffering=on
olarka değiştirip kaydedin ve sunucunuzu yeniden başlatın.

Yol 2:
kodlarınızın başına (daha ekrana herhangi bir çıktı, boşuk dahil; vermeden) ob_start();

yazmanız sorununuzu çözecektir

Yorum yap : devami...

MySQL de transaction kullanımı

Gonderen: Ersin tarih: Sep.24, 2009, Kategori: MySQL, Php Web Programlama

Bir önceki yazıda bulunan örnek ile devam edeceğim için, ilk önce bu örnekteki kodları edinip çalıştırmanız gerekli.

Transction, kelime anlamı ile işlem demektir. Fakat bu kelime anlamının haricinde, veritabanına doğru gerçekleştirilen işlemlerin, veritabanına kalıcı olarak işlenip işlenmemesini yöneten muazzam bir sistemdir. Ve kullandığınızda göreceksiniz ki çok hayat kurtaran bir sistemdir . MySQL 4.0 ve yukarısı InnoDB ve BDB saklama motorları transaction desteklemektedir.

Örneğimizde bir kullanıcı tablomuz var ve bir de gönderi tablomuz. Şöyle bir senaryo çizelim:
Bir kullanıcımızı silmek istiyoruz ve haliyle bu kullanıcının girdiği bütün gönderileri de silmek istiyoruz. Bunu basit bir sorgu ile kolayca gerçekleştirebiliriz:

baglan();
kullaniciSil($kullaniciId);
baglantiyiKapat();

Durum kabaca bundan ibaret. Ama ya işler ters gittiğinde. Kullanıcıyı sildik, ama bir terslik oldu, tam kullanıcı gönderileri silinirken hata oluştu ve gönderileri silemedik. O zaman ne yapacağız ? Gönderi tablosunda kullanıcısı olmayan gönderileri bulup silmek için bir işlem daha yaptırabiliriz. Ama bu ne performans açısından kabul edilebilir, ne de uygulamanın sağlamlığı ve kararlılığı açısından. İşte burada devreye transaction giriyor , tabi bu yapıyı kullanmanın en iyi yolunun PDO dan geçtiğini söylemek gerekir. Dönelim örneğimize:

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>
'
;
}

Normal şartlar altında, aksini belirmedikçe PDO bütün sorgularınızı otomatikman veritabanına iletir. beginTransaction () metodu ile PDO ya işlemlerin sonuçlandırılması için bizim onayımızı almasını söylüyoruz. Daha sonra try bloğu sağlıklı çalışır ise commit() metodu ile PDO ya işlemlerimizin istediğimiz gibi gittiğini ve işlemleri sonuçlandırmasını söylüyoruz. Eğer catch bloğuna düşer ise, ters giden birşeyler olduğunu bildiğimiz için rollBack() metodu ile yaptığımız bütün işlemlerin geri alınmasını söylüyoruz.
Bunu en iyi şöyle test edebilirsiniz. Örnekteki veritabanı ve tabloları oluşturun. User tablosuna veri girin ve user_posts tablosuna hiçbirşey girmeyin. $sorgu1 deki yere kullanıcının id sini doğru girin ve $sorgu2 ye dokunmadan örneği çalıştırın, bakın bakalım ne olmuş.
Şimdi normal şartlar altında,kullanıcı olduğu için kullanıcının silinmesi gerekirdi, kullanıcı gönderilerinin silinmesi için verdiğimiz kullanıcı id si yanlış olduğu için silinecek herhangi birşey olmayacaktı. Kullanıcı uçmuş gitmiş ama kullanıcı gönderileri öyle kalacak idi. Ama kalmayacak, sorgu çalıştıktan sonra gidip tabloya baktığınızda şaşırmayın, bir hata yapmadınız. Kullanıcı orda duruyor ,silinmedi.
Çünkü try bloğumuz sonuna kadar çalışmadı, kullanıcı gönderisini silemediği için istisna fırlattı ve bu yüzden catch blokuna düştü, burda da işlem ters gittiği için yapılan işlemler geri alındı. İşte hayat kurtaran bu güzell işlevi kullanmak bu kadar kolay.

Güzel günler dileği ile, hoşça kalın.

Yorum yap :, , devami...

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.
*/
Yorum yap :, , devami...

Birşey mi aradın ?

Sitede arama yapmak icin asagidaki formu kullanin:

Hala aradigini bulamadin mi ? Gönderiye bir yorum bırak, ya da benim ile iletişime geç, elimden geldiğince yardimci olurum!

Tavsiye olunur!

Tavsiye baglantilar