PHP ve EZSQL: Pratik veritabanı işlemleri
Barış Atasoy • 3 Ekim 2008 Cum •
PHP, daha ilk zamanlarından bu yana, MySQL veritabanı ve Apache webserver ile ayrılmaz bir üçlü haline geldi. Aslında, özellikle çok iyi GTK entegrasyonu ile masaüstü programcılık alanında da kendisine bir yer edinebilecek olan PHP, daha çok bir web dili olarak öne çıktı ve neredeyse yıllardır hiçbir rakibine geçit vermiyor.
Günümüzün etkileşimli web siteleri düşünüldüğünde, PHP’yi en çok veritabanlarına erişmek,değiştirmek ve bilgi yazmak için kullandığımızı söyleyebiliriz. Bu alanlarda oldukça başarılı ve hızlı olmasına rağmen, bu işleri bizim için çok daha kolay ve derli toplu hale getiren bir araç bulunmakta: EzSQL.
EzSQL, meşhur Wordpress’in de kendi içinde kullandığı bir veritabanı erişim sınıfı. Justin Vincent tarafından kodlanan EzSQL, sadece MySQL için değil, Sqlite, Interbase,Firebird, Postgresql, Microsoft SQL Server ve Oracle8 ve Oracle 9 içinde kullanılabiliyor. Bunun sağladığı avantajlardan biri de, saydığım 3 veritabanı arasında, PHP kodunu değiştirmek zorunda kalmadan değişim yapılabilmesi. Elbette, kullanılan SQL ifadelerinin uyumlu ve standart olması gerekmekte. Sözgelimi, PL/SQL sorgularını doğal olarak MySQL ya da herhangi bir başka ilişkisel veritabanı üzerinde çalıştırmanız mümkün değil.
EzSQL, bunlara ek olarak cache (önbellekleme) işlemini bizim için yapıyor ve SQL sorgularımızdaki hataların daha kolay debug edilebilmesini sağlıyor.
Çalışmalarımızda, aksi ifade edilmedikçe daima MySQL kullanacağız. Bunun en büyük nedeni, MySQL’ı ücretsiz edinebilmeniz ve web üzerinde neredeyse standart veritabanı haline gelmiş olması.
EZSQL SINIFI NASIL KULLANILIR?
Öncelikle, sayfanın altındaki linkten kaynak dosyaları indirin ve XAMPP ya da benzer Apache-MySQL-PHP paketinizde bulunan PHPMySQLAdmin’i açın. Arşivden çıkarttığınız dosyalar arasında bulunan pozitifpc.sql isimli dosya ile veritabanı ve örnek tabloyu yaratın. Bunun için, PHPMyAdmin sayfasında, işaretli yerde pozitifpc isimli bir veritabanı oluşturun. Açılan yeni pencerede SQL sekmesine tıklayarak pozitifpc.sql dosyasının içeriğini metin alanına kopyalayarak, ya da “İçeri Aktar” sekmesine tıklayıp, pozitifpc.sql dosyasını açarak tablo ve verileri veritabanı içine aktarabilirsiniz.
Veritabanı ve örnek tablonuz sorunsuz oluştu ise, çalışmaya başlayabiliriz.
EzSQL sınıfını kullanmak için, veritabanı uygulaması yapacağınız sayfada iki adet dosyayı, include ya da require ile yüklemeniz gerekiyor. Bunu PHP scriptinizin ilk satırında yapmanızı şiddetle öneririm.
Bu dosyalardan birinin adı ez_sql_core.php’dir. Hangi ilişkisel veritabanını kullanacak olursanız olun, scriptiniz bu dosyayı yüklemelidir. Bu dosya ardından, kullandığımız veritabanına uygun olan bir başka dosyayı daha aynı şekilde yüklememiz gerekiyor. Biz örneklerimizde MySQL kullandığımız için, bu dosya ez_sql_mysql.php olacak.
Yani, scriptimizin ilk satırları şu şekilde oluyor:
/* PHP, MySQL ve EzSQL sınıfı Örnek 1 - Barış Atasoy 2008 / Pozitif PC */ require_once "ez_sql_core.php"; require_once "ez_sql_mysql.php"; ?>
Scriptin tamamlanmış hali zaten indirdiğiniz dizinde mevcuttur. Dizini sisteminizin Apache root’u altına atmalısınız. Şu an Windows üzerinde XAMPP kullandığım için, bu dizin ağacı bende C:\xampp\htdocs\ezsql şeklinde.
Neden require yerine require_once kullandık? Çünkü scriptimiz her yüklendiğinde, ez_sql_core.php ve ez_sql_mysql.php daha önce yüklenmişse, tekrar yüklenmesini engellemek istiyoruz.
Burada hemen bir parantez açmak isterim. PHP kodlarını incelediğinizde genelde include kullanıldığını görürsünüz. Her dilin, genelde tecrübeyle kazanılan “doğruları” vardır. Ben include yerine daima require kullanırım. Neden mi? Eğer include kullanırsanız ve belirttiğiniz dosya bulunamazsa, kod sizi uyararak çalışmaya devam eder. Şayet require kullanırsanız, bir uyarı ve arkasından bir de ölümcül hata alırsınız ve scriptin çalıştırılması durur. Normalde uyarıyı farkedip hatayı giderebileceğinizi düşünebilirsiniz ama, öntanımlı PHP ayarları uyarıları göstermemeye ayarlı olabilir! Daha kötüsü, çok uzun bir kodda, bu davranış ini_set ile bir yerlerde değiştiriliyor olabilir. Sonuç olarak böyle bir durumda include kullanırsanız, ve yüklemek istediğiniz dosya yerinde değilse, hata mesajı almazsınız ve script içinde anlayamayacağınız ya da boşu boşuna zaman kaybettiren durumlarla başa çıkmak zorunda kalırsınız.
Daha sonra, EzSQL’a veritabanı adımızı, kullanıcı adı ve şifremizi, son olarak da MySQL veritabanımızın adresini bildirmemiz gerek:
$db = new ezSQL_mysql('root','','pozitifpc','localhost');
Sırası ise: MySQL kullanıcı adı, MySQL kullanıcı şifremiz (bende şifre olmadığı için boş bıraktım), Veritabanı adı ve son olarak da MySQL’ın IP adresi ya da FQDN’i.
Yani, bir veritabanına bağlanıp işlem yapabilmemiz için gereken temel kod, şu biçimde olacaktır:
/* PHP, MySQL ve EzSQL sınıfı Örnek 1 - Barış Atasoy 2008 / Pozitif PC */ require_once "ez_sql_core.php"; require_once "ez_sql_mysql.php"; $db = new ezSQL_mysql('root','','pozitifpc','localhost'); ?>
EzSQL Fonksiyonları
EzSQL içinde veritabanında işlem yapan 4 temel fonksiyon bulunuyor. Diğerlerini yazının sonuna bırakıyorum; çünkü bunlar daha uzman düzeyi özellikler.
Bizim şu anda kullanacaklarımız: get_results, get_var, get_row ve query.
query: Yazdığınız SQL sorgusunu çalıştırır. Tabloya ekleme ya da silme yaparken kullanabileceğimiz tek özellik budur. Select sorgularını da çalıştıracaktır ama sonuçları işlemek zor olduğundan, bunun yerine Select sorgularında get_var,get_results ve get_row’u kullanacağız.
get_var: Eğer veritabanından tek bir alanın tek bir değerini çekecekseniz, get_var basit kullanımlı bir özellik olarak çok işinize yarar.
get_results: Tüm sonuçları bir PHP dizisine atar.
get_row: Veritabanından sadece tek bir satır çekip, ancak tüm sütunların değerlerini elde etmek istiyorsanız bunu kullanacaksınız. get_var ile farkı, get_var’ın sadece bir sütun değerini çekebilmesi ve bunu da bir değişkene atmasıdır.
Şimdi biraz örnek verelim; böylece kullanımı gerçekten çok kolay ve zaman kazandırıcı olan EzSQL sınıfı daha da kolay anlaşılacaktır:
// Tablodaki en büyük yaşlı kişiyi bul ve sadece yaşını $en_buyuk_yas değişkenine yaz $en_buyuk_yas=$db->get_var(“SELECT MAX(yas) FROM yazarlar”); // ID numarası 4 olan yazarın adını,soyadını,yaşını ve yazı sayısını yaz $yazarim = $db->get_row("SELECT ad,soyad,yas,yazisayi FROM yazarlar WHERE ID= 4"); echo “Adı:”.$yazarim>ad."<br>"; echo “Soyadı:”.$yazarim->soyad."<br>"; echo “Yaş:”.$yazarim->yas."<br>"; echo “Yazı Sayısı:”.$yazarim->yazisayi."<br>"; // Aynı örnek; ancak sütunları isimlerini yazarak seçmemize gerek yok $yazarim = $db->get_row("SELECT * FROM yazarlar WHERE ID= 4"); echo “Adı:”.$yazarim->ad."<br>"; echo “Soyadı:”.$yazarim->soyad."<br>"; echo “Yaş:”.$yazarim->yas."<br>"; echo “Yazı Sayısı:”.$yazarim->yazisayi."<br>";
Peki get_row ile birden fazla satır elde ediyorsak ne olur?
Sadece çekilen ilk sonuç gösterilir.
Şöyleki;
$yazarim = $db->get_row("SELECT * FROM yazarlar WHERE yas=30 ORDER BY ID DESC"); echo “Adı:”.$yazarim>ad."<br>"; echo “Soyadı:”.$yazarim->soyad."<br>"; echo “Yaş:”.$yazarim->yas."<br>"; echo “Yazı Sayısı:”.$yazarim->yazisayi."<br>";
Tabloya bakacak olursanız, yaşı 30 olan iki yazar göreceksiniz: Can Kavaklıoğlu ve Serhan Üstünol. Sorgumuzda, “ID numarasına göre azalarak sırala” dedik. Bu durumda, ilk sonucumuz ID numarası 4 olan Can Kavaklıoğlu olacaktır.
Eğer iki yazarın da bilgilerini çekmek istiyorsak, get_results kullanmalıyız:
// Yaşı 30 olan yazarları gösterir. $yazarlar30 = $db->get_results("SELECT * FROM yazarlar WHERE yas=30"); foreach ( $yazarlar30 as $yazarim ) { echo “Adı:”.$yazarim->ad."<br>"; echo “Soyadı:”.$yazarim->soyad."<br>"; echo “Yaş:”.$yazarim->yas."<br>"; echo “Yazı Sayısı:”.$yazarim->yazisayi."<br>"; echo “ ”; }
Query ise genelde Update,Insert ve Delete SQL sorguları ile kullanılır. Ancak, burada size küçük bir ipucu vereyim: Eğer karmaşık bir SQL sorgusu yazıyorsanız, get_row, get_results ile sonuçları basmak hatanın olabileceği adım sayısını artırır. Sadece sorgunuzun verdiği sonuçları görmek isteyebilirsiniz.
Şimdi bir kodlama hatası durumu yaratalım.
Diyelimki, yaşı 30 olan yazarların hepsini veritabanından çekmek istiyorum. Birden fazla sonuç satırı sözkonusu olduğunda, bildiğiniz gibi get_results kullanıyorduk. Ama ben bunu unutup get_var kullandım!
Yazdığım hatalı kod:
$yazar= $db->get_var("SELECT * FROM yazarlar WHERE yas=30 ORDER BY ID DESC"); foreach ( $yazar as $yazarim ) { echo "Adı:".$yazarim->ad."<br>"; echo "Soyadı:".$yazarim->soyad."<br>"; echo "Yaş:".$yazarim->yas."<br>"; echo "Yazı Sayısı:".$yazarim->yazisayi."<br>"; }
Bir uyarı aldım:Warning: Invalid argument supplied for foreach()
Peki, kodum mu hatalı, yoksa yazdığım SQL sorgusu mu yanlış, ya da eşleşen değer döndürmüyor?
Bu durumda, EzSQL’ın iki güzelliği var:debug ve vardump.
Debug ve Vardump fonksiyonları ile hata tespiti
Kodun sonuna şu iki satırı ekleyin:
$db->debug(); $db->vardump($results);
debug() fonksiyonu, sorgunuzun “gerçek” sonucunu gösteriyor. Çıkan tabloya baktığımızda, gerçekten de hedeflediğimiz çıktıyı aldığımızı görüyoruz. Demekki, yazdığımız SQL sorgusu doğru. Bu durumda, sorgu sonucunu işleyerek ekrana basan kodda bir hata olmasından şüpheleniyoruz!
vardump() fonksiyonu ise, çalışan son sorguyu, kullandığımız EzSQL fonksiyonunu ve dönen sonuç sayısını gösteriyor. Aslında debug() fonksiyonundan pek farklı değil ve debug() fonksiyonu daha yararlı sonuçlar veriyor.
vardump’ın daha yararlı bir kullanım alanı var: şayet col_info() fonksiyonu ile kullanırsanız, tablonun alanları ile ilgili bazı yararlı bilgilere ulaşabiliyorsunuz:
$db->vardump($db->col_info);
Bu fonksiyonun çıktısından bir örnek:
[2] => stdClass Object ( [name] => soyad [table] => yazarlar [def] => [max_length] =>11 [not_null] => 1 [primary_key] => 0 [multiple_key] => 0 [unique_key] => 0 [numeric] => 0 [blob] => 0 [type] => string [unsigned] => 0 [zerofill] => 0 )
Tablomdaki “soyad” isimli sütunun -ki bunu [name] değerinden öğreniyorum- barındırdığı en yüksek karakter sayısının [max_lenght] 11 karakter olduğunu (Kavaklıoğlu), bu alanın primary_key olmadığını -değeri 0-, türün string -aslında tam olarak varchar- öğreniyorum.
escape() fonksiyonu ile SQL Injection’a karşı önlem
“Gerçek hayatta” kullanılan bir uygulama geliştirirken güvenliği de düşünmelisiniz.
İlk almanız gereken önlemlerden biri, SQL Injection saldırılarını önlemektir. Güvenlik, son derece geniş, ileri düzey ve apayrı bir konu olduğundan burada ele alacak değilim.
Çok basitçe söylemek gerekirse; escape() fonksiyonu, SQL Injection saldırısında kullanılabilecek bazı karakterlerin ayıklanmasını sağlar.
Örneğin tırnak işaretleri, veritabanına tırnak olarak aktarılmaz; özel bir karakter grubu olarak aktarılır.
Hemen bir örnek verelim:
$hayathikayem = $db->escape($_POST['hayatim']);
Burada, henüz varolmayan bir PHP scriptimizden, $hayatim isimli alanı alıp, zararlı olabilecek karakterleri temizleyerek $hayathikayem degişkenine atadık.
Eğer belli alanları veritabanına kaydedecek ya da güncelleyecekseniz, alanları tablonuza kaydetmeden önce bu fonksiyonla “süzmenizi” şiddetle tavsiye ederim.
Çalıştığımız veritabanını değiştirmek: select() fonksiyonu
Web tabanlı bir uygulamada çok sayıda tablo olması olağandır; ancak birden fazla veritabanı ile çalıştığımız durumlar oldukça nadirdir. Ancak yine de, birden fazla veritabanı ile çalışmamız gereken durumlar olacaktır; örneğin çok sayıda web sitenizin ortak bir kullanıcı veritabanı olabilir.
select() fonksiyonunun kullanımı oldukça basit:
$db->select(“veritabani-adi”);
Sorguları önbelleğe almak
Sık kullandığımız ve sık ya da hiç değişmeyen bazı sorgu sonuçlarını önbelleğe alabiliriz. Bu sayede, özellikle büyük tablo ve veritabanlarında, çalışan sorgu için boşu boşuna MySQL motoru CPU gücü harcanmayacaktır.
MySQL cache nasıl çalışır?
1.Sorgu sonuçlarının kaydedileceği bir dizin oluştururuz.
2.Dizini yazılabilir olarak düzenleriz. Linux sistemler için dizin hakları olarak 775 verebilirsiniz.
3.cache_timeout fonksiyonu ile sonuçların ne kadar süre saklanacağını saat bazında veririz. Genelde PHP’de zaman birimi mikrosaniyedir; ancak bu fonksiyon değerini saat olarak almaktadır.
4.Cache dizinimizin yolunu cache_dir fonksiyonu ile tanımlarız.
5.use_disk_cache=true ile disk önbelleğini aktif hale getiririz.
6.Öntanımlı olarak, EzSQL, sorgu sonuçlarını önbelleğe almaz. Bunun için, cache_queries fonksiyonuna true değerini atayarak önbellekleme fonksiyonunu aktif hale getiririz (cache_queries = true;)
7.Önbelleğe alınması gereken sorguları yazmaya devam ederiz.
8.Eğer önbelleğe alınmaması gereken sorgular varsa -örneğin değeri sık sık değişen bazı sonuç kümeleri- cache_queries = false; ile önbellekleme özelliğini kapatır ve bu sorguları scriptimize ekleriz.
Eğer başarılı olduysanız, tanımladığınız cache dizini altında, yazdığınız sorgu sayısı kadar dosya açılacaktır. Bunlar metin dosyalarıdır; açıp biraz uğraşırsanız aslında formatının oldukça anlaşılır olduğunu fark edebilirsiniz.
Cache dizini olarak verdiğiniz dizinde dosya oluşmuyorsa, kodunuzda bir hata var demektir.
ilk olarak, dosya oluşturmak için yeterli izinlere sahip olup olmadığınızı kontrol etmeli, ardından cache_queries fonksiyonunu doğru yerde kullandığınızdan emin olmalısınız.
EzSQL sitesinde verilen kodu aynen aktarıyorum:
// Cache süresi ne zaman dolacak? $db->cache_timeout = 24; // Verilen değer saat cinsinden! // Cache dizini $db->cache_dir = 'cache'; // (1. Dizini oluşturun) // (2. Linux için 775, Windows içinse dizini yazılabilir duruma getirin) //Disk önbellekleme özelliğini aç $db->use_disk_cache = true; // Önbellekleme özelliğini aç $db->cache_queries = true; $db->get_results("SHOW TABLES"); $db->debug(); $db->get_results("SELECT * FROM User"); $db->debug(); // Buradan sonraki sorgular önbellekleme harici tutulur $db->cache_queries = false; $db->get_results("SELECT * FROM User LIMIT 0,1"); $db->debug();
İlgili Yazılar:
Amarok 2 Beta 2 ve Embeddded MySQL:Özellikle Linux ve KDE'nin vazgeçilmez yazılımlarından olan Amarok 2'nin ikinci beta sürümü yayınlandı. Beta olmasına aldanmayın; çok önemli ve köklü bir değişiklik var: Meşhur müzik çalıcı, artık Sqlite veritabanı yerine...
PHP Dersleri – 2:Değişkenler,sabitler,global ve super globaller:Değişkenler PHP'de temel olarak 6 tür değişken bulunur: string (metin), integer (işaretli tamsayı), float (işaretli kesirli sayı), boolean (TRUE ya da FALSE değeri alır), array (dizi) ve object (sınıflar konusunda...
PHP Dersleri – 1:Geçen dersimizde PHP'nin ne olduğunu, neler yapılabileceğini, MySQL,Apache,PHP entegrasyonunu kısaca ele almıştık. Bu derste, PHP ile ilk deneyimimizi yaşayıp artık ekran üzerinde birşeyler görmeye başlayacağız! Ön Hazırlık Önceki derste de...
PHP Dersleri – 0: PHP, Apache, MySQL nedir?:PHP nedir diye sorulduğunda, web uygulamaları için geliştirilmiş bir dil olduğu yanıtını alırsınız. Bu çok eksik bir tanımlama. Sözgelimi, PHP-GTK ile masaüstü uygulamalar geliştirebilirsiniz. Hatta sistem yönetimi için kullanabilirsiniz. Bazı...
ASP.NET Görsel Başlangıç - 1:Bu ülkede meslek liseleri üzerinden “programcı” yada buna benzer sıfatlarla eğitim gören bir çok insana,hatta bir çok değil de nerdeyse tamamına önce olayın temel mantığının anlaşılması açısından kağıt üzerinde bir...
PYTHON - 2:Geçtiğimiz ay değişkenleri ve operatörleri incelemiş, listeler üzerinde durmamıştık. Bu ay, özellikle ortanın üzerindeki karmaşıklıkta programlarda çok işimize yarayacak olan listeleri inceleyecek ve ardından if,for ve while gibi karar yapılarına...
TYPO 3: TYPO3 açık kaynak kodlu, kurumsal çaplı bir içerik yönetim sistemidir (İYS) (ECMS enterprise content management system). Danimarkalı programcı Kasper Skårhøj tarafından geliştirilmektedir. İlk TYPO3 versiyonu 1998 yılında yayınlanmış, zamanla...
PIC Programlama - 1:Elektronik dünyası, mikroişlemcilerin ve mikrodenetleyicilerin uygulamalarda daha sık yer almaya başlamış olmasıyla , zaten hayli yakın olduğu bilgisayar ve programlama dünyasıyla mevcut bağlarını sıkılaştırmış tır. Daha çok bilgisayarlarda duymaya alışkın...
PYTHON - 1:Günümüzde en hızlı gelişim grafiğine sahip dillerden biri Python. Python; Windows, Linux ve Mac OS gibi değişik platformda çalışabilmenin yanında, cep telefonu gibi mobil cihazlara da girdi. Nitekim Nokia, Symbian...
BASH - 3:3.0 Betiklerin özellikleri Türk Dil Kurumu'nun (TDK) İnternet sitesinde[1] betik (İng: "script") kelimesi "Yazılı olan şey, kitap, mektup, tezkere, pusula" olarak tanımlanmış. Bilgisayar terimi de bu anlamı taşımaktadır. Önceki yazılarda...


