Sayfalar

Oracle ve PHP'yi Beraber Kullanmak

Eger sizde benim gibi PHP'yi ilk kararli surumlerinden beri kulllaniyor ve uzerinde gun gectikce uzmanlasiyorsunuz demektir.Ilk kez Apache ile uyumlu bir sekilde Linux uzerinde MySQL veritabanini kullanacak sekilde calsmasini saglamak tam 3 gunumu almisti...

Linkler :

http://www.apache.org/
http://www.mysql.com/
http://www.linux.com/
http://www.php.net/
http://www.oracle.com/

Veritabani Tasarimi :

http://hotwired.lycos.com/webmonkey/backend/databases/tutorials/tutorial3.html

Su andaki bilgi birikimi ve tecrubelerimize ragmen kabul etmeliyiz ki bilgisayar gibi hassas cihazlari programlayanlarda "insan" ve insanlar cok sik hata yaparlar...

Yukaridaki dusunceden hareket edersek bize "degerli verilerimizi" koruyacak bazi mekanizmalarin olmasi gerektigini daha cabuk anlariz.

Iste bu noktada cok hizli calisan ve mukemmele yakin hasssaiyeti ile hepimizin gozbebegi MySQL'in imdadimiza yetisitigini pek soyleyemeyiz.MySQL ilk yaratildiginda web icin hizli calisacak bir program olarak dizayn edilmisti.Iste bu nedenlelerle bazi "kurumsal" fonksiyonlari icinde hic bir zaman barindirmadi.Bunlara ornek olarak "database transactions" verilebilir.Aslinda genel olarak bakildiginda bu ozelliklere cogu web sitesinin ihtiyaci da yoktur.

Bazi programlama hatalarini duzeltecek ve veri butunlugune zarar vermeyecek kadar zeki ve guclu veritabani programlarina ihtiyaciniz varsa onerebilecegimiz en gelismis ve kararli urun Oracle olacaktir.Insanlarin boyle gelismis veritabanlari yerine MySQL'i secmesinin baslica nedeni (genele bakildiginda) fiyati olacaktir.MySQL kendine has bir lisansi olan ve cogu zaman ucretsiz olarak kullanabileceginiz kucuk ama cok hizli bir veritabani motorudur.Hem internet uzerinde bu veritabani icin yazilmis egitim makalelerini bulmakda (oracle dusunuldugunde) cok zor degildir.

http://hotwired.lycos.com/webmonkey/programming/php/tutorials/tutorial4.html

Oracle lisanslari onbinlerce dolarla ifade edilmektedir.ustelik Oracle egitimi MySQL ile kiyaslandiginda hem daha zor hemde ucretsiz olarak bulunabilcek kaynaklarin darligi nedeniyle size ek butce yuku getirebilecek yapidadir.

Oracle her zaman icin "gelistirme" yapmak amaciyla bir makineye "ucretsiz" olarak kurulup kullanilabilir.Bu konuda daha detayli bilgiyi sitesinden elde edebilirsiniz :

http://www.oracle.com/

Oracle Yazilimini Elde Etmek

Eger hizli (gercekten hizli) bir internet baglantiniz varsa hemen simdi oracle web sitesinden ucretsiz olarak indirip kullanmaya baslayabilirsiniz.Toplam dosya buyuklugu 600M+ seklindedir...

Bir diger yol ise oracle e-is sitesinden bu yazilimi sipraris etmektir.Boyle bir durumda hem yukleme hemde CD ucretini odemeniz gereklidir.(40 $)

Oracle'in Yuklenmesi

Bu konuda degisik sitelerden yardim alabilirsiniz.Tamamen ingilizce olarak hazirlanmis bu sitelere linkleri sitemizin "linkler" bolumunden "oracle" alt kategorisini secerek ulasabilirsiniz.Size kolaylik olmasi amaciyla bu konuda hazirlanmis "How-to" yani "Nasil" dokumanin adresini asagiya ekledik :

http://www.linuxdoc.org/HOWTO/Oracle-8-HOWTO.html

PHP'nin ayarlanmasi

Aslinda konumuz Oracle-PHP ikilisinin nasil calistigini anlatmak oldugu icin bazi ince yukleme noktalarina deginmek istedim.Ilk olarak sizlere tavsiyem PHP'yi kaynak kodundan ve ./configure komutu ile ayarlayarak derlemenizdir.Bunu nasil yapacaginiz konusunda sitemizde birden fazla kaynak yer almaktadir...

"./configure" islemi kaynak kodunu derlemeye hazirlamak icin kullanilir.Kaynak koduna hangi modullerin eklenecegini veya cikaralacagini basitce komut satirindan asagidaki gibi girebilirsiniz :

(Once PHP kaynak kodunun oldugu dizine gecmeyi unutmayniz.)

./configure --with-mysql=/[mysql icin yolu giriniz] --with-apxs=/[apxs icin yolu giriniz]

Yukarida anlatilan sekilde istediginiz parametreleri girdikten sonra oracle destegini PHP'ye eklemek icin asagidaki parametreyide gormeyi unutmayiniz :

--with-oci8=[DIR]

DIR yazan yere ORACLE_HOME degiskeni ile belirlenen Oracle yukleme klasorunun yolunu girmeniz gereklidir.Boylece PHP yi derleyecek olan programlar sisteminizde Oracle ve kutuphanlerleinin hangi dizinde kurulu oldugu bilebileceklerdir...

Ornek :

./configure --with-mysql=/usr/mysql --with-apxs=/usr/httpd --with-oci8=/usr/local/oracle/product/8.1.7

Oracle icin bir test veritabani yaratip makalenin ilerleyen kisimlarindaki tablo orneklerini yapabilirsiniz.Yanliz acmis oldugunuz kullanici hesabinin veritabani yaratma,veri secme ve veri ekleme izinlerine sahip olduguna emin olunuz.

Ornek bir Oracle 8i tablosunun yaratilmasi

Bir cok sirket kendi calisanlari ile ilgili bilgileri veritabaninda saklar.Bunu yapabilmek icin once tum calisanalri ile ilgili verilerin tutulacagi bir tabloyu yaratmak zorundadir.

Bizde ilk is olarak bir calisanlar tablosu yaratmakla ise baslayalim,

Komut satirindan "sqlplus" komutunu giriniz :

# sqlplus

Sisteme kullanici adiniz ve sifreniz ile giris yaptiktan sonra asagidaki SQL sorgusunu veritabani uzerinde uygulayiniz :

SQL> CREATE TABLE calisanlar(
calisan_id_no NUMBER(4) NOT NULL,
iadi_tx VARCHAR2(64) NOT NULL,
sadi_tx VARCHAR2(64) NOT NULL,
telefon_tx VARCHAR2(14),
eposta_tx VARCHAR2(255),
guncel_dt DATE NOT NULL,
yaratma_dt DATE NOT NULL,
PRIMARY KEY(calisan_id_no)

Bu sorguyu veritabaninda uygularsaniz asagidaki gibi bir cikti alirsiniz :

SQL> CREATE TABLE calisanlar(
2 calisan_id_no NUMBER(4) NOT NULL,
3 adi_tx VARCHAR2(64) NOT NULL,
4 sadi_tx VARCHAR2(64) NOT NULL,
5 telefon_tx VARCHAR2(14),
6 eposta_tx VARCHAR2(255),
7 guncel_dt DATE NOT NULL,
8 yaratma_dt DATE NOT NULL,
9 PRIMARY KEY(calisan_id_no)
10 );

Table created.

Veritabani tablomuz boylece yaratilmis oldu.Simdi bu tabloya eklenecek her bir veri satirinin digerinden farkli olmasini saglamak icin bir "sequence" yani "siralama" yaratalim.


MySQL kullanmaya aliskin olanlar bunu yapabilmek icin "AUTO_INCREMENT" olarak bilinen "tablo alani" ozelligiyle amaca cok cabuk ulasildigini hatirlayacaklardir.Oracle'da durum biraz daha degisiktir.Bunu yapabilmak icin bir ek SQL sorgusuna daha gerek duyarsiniz. Oracle'da "SEQUENCE" komutu ile bir alanda,yeni veri eklendiginde otomatik olarak bir onceki degerin bir ust sayisal degeri alinarak, tablonun o alanina eklenmesi saglanir :

SQL> CREATE SEQUENCE calisan_id_no START WITH 1
INCREMENT BY 1 MAXVALUE 9999;

Yukaridaki komut ile baslangci olarak 1 secildigi,her yeni veri seti eklendiginde bu alana (calisan_id_no) eklenecek degerin 1 artirlicagi, bu alndaki degerin 9999 degerini gecemeyecegi belirlenmektedir :

Bu sorguyu veritabaninda uygularsaniz asagidaki gibi bir cikti alirsiniz :

SQL> CREATE SEQUENCE calisan_id_no START WITH 1
2 INCREMENT BY 1 MAXVALUE 9999;

Sequence created.

PHP'nin Oracle Fonksiyonlari

Burada ele alacagimiz Php fonksiyonlari en cok kullanilan Oracle baglanti fonksiyonlaridir.En genis bilgiye ve fonksiyonlarin tamamina (kullanici notlari ile beraber) asagidaki linkten ulasabilirsiniz :

http://www.php.net/manual/en/ref.oci8.php

OCILogon ()
Veritabani ile iletisime gecer ve baglantiyi kurar.Bu baglanti referans gosterilerek diger fonksiyonlarin calismasi saglanir.Bazi fonksiyonlarda boyle bir baglantinin halihazirda kurulu olmasi gerekliligi vardir.

OCIParse ()
Bu fonksiyon herhangi bir sorguyu,veritabani uzerinde uygulanmadan once hazirlamak icin kullanilir.

OCIBindByName ()
OCIParse () ile kullanilarak,kullanici tanimli data'nin sorgunun bir parcasi olmasi saglanir.Bir baglac olarak dusunulebilir...

OCIExecute ()
Hazirlanmis bir sorguyu veritabaninda uygulamak icin kullanilir.

OCIError ()
Herhangi bir sorgumuzda olusan hatalarimizi bilgilendirmek icin kullanilir.

OCIFetchInto ()
Veritabanindan donen sonuclari donguye sokmak icin kullanilir.

OCICommit ()
Bu fonksiyon ile veritabaninda tum yaptigimiz islemlerin kalici olarak gerceklesmesi saglanir.Yaptiginiz tum degisiklikleri veritabanina kayit eder.

OCIRollback ()
Bu fonksiyon ile veritabani bir onceki haline dondurulur.

Veritabanina Baglanmak

Veritabanina baglanti yapabilmek icin OCILogon () fonksiyonu kullanilir.Bu fonksiyon toplam uc parametre alir :

kullaniciadi
sifre
veritabani

<?php
$db = " (DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521))
(CONNECT_DATA = (SID = ORCL))
)";
$iDBConn = OCILogon("scott","tiger",$db);
?>

NOT : Yukaridaki kod icerisinde dort noktayi ozellikle kendinize gore ayarlamalisiniz :

"scott" yazan yere kendi kullanici adinizi yazin.
"tiger" yazan yere kendi sifrenizi yazin.
HOST = 127.0.0.1 (Veritabaninin uzerinde calistigi makinenin IP adresi)
SID = ORCL (Baglanilacak olan veritabaninin SID degeri,yani Veritabani ismi...)

Bu dort degeri kendi kullaniciadiniz,sifreniz,IP adresiniz ve Veritabani isminiz ile degistiriniz.

Simdi yukaridaki bilgiler ile veritabanina baglanti yapacak kisimi yazabiliriz.

Bazen kullanicilar boyle bir kodun ardindan hata mesajlari alirlar.Buna en temel neden ORACLE_HOME cevre degiskeninin sistem genelinde tanimlanmamis olmasidir.Simdi asagidaki gibi bir kod ile bu degiskenin yaratilip tum sistem programlari tarafindan (elbette PHP'de buna dahil) kullanilmasini saglayabilirsiniz.

<?php
putenv("ORACLE_HOME=/usr/local/oracle/product/8.1.7");
?>

Tabii ki yukaridaki yolu kendi sisteminize gore oracle'i hanig klasore kurduysaniz onu girmelisiniz...

Tabloya yeni bir kayit girilmesi

Simdi de "calisanlar" tablosuna yeni kayit eklemeye calisalim :


<?php
//
// Calisanlar tablosuna eklenecek veriler...
//
$strAdi = 'Serkan Hadi';
$strSoyadi = 'CEYLANI';
$strTelefon = '813.222.22.22';
$strEposta = 'serkan@turk-php.com';
?>

Verileri tamamladigimiza gore bu veriyi alip veritabanina ekleyecek sorguyu olusturabiliriz :

<?php
//
// Sorguyu hazirliyoruz...
//
$qsvCalisanEkle = "

INSERT INTO calisanlar
(calisan_id_no,adi_tx,sadi_tx,
telefon_tx,eposta_tx,guncel_dt,yaratma_dt)
VALUES (calisan_id_no.nextval,:adi_tx, :sadi_tx, :telefon_tx, :eposta_tx, SYSDATE, SYSDATE)";
?>

Yukarida gorulen kod icerisinde size yabanci gelebilecek tek nokta VALUES icinde kulanilan ":adi_tx" turundeki programlamadir.Burada yapilan aslinda cok basit bir referans verme islemidir.Daha onceden veriyi isleyip ardindan da burada ":adi_tx" gecen yere ornegin yerlestirilmesini saglayacagiz.(Bu konuya yazinin ilerleyen kesimlerinde deginecegiz.Simdilik ne oldugunu kafanizda canlandirmakla yetinin...Ingilizcede bu notasyona ve yapilan isleme "placeholder" denilmektedir.Oraya gelecek kullanici-tanimli veriyi isledikten sonra oraya yazmak icin kullanilmaktadir.)

calisan_id_no.nextval notasyonu ile tabloda o alanda kayitli degerden sonra (SEQUENCE komutunda belirtilen arttirma sayisi kadar yani INCREMENT BY olarak verilen deger kadar) gelecek deger yaziliyor.

SYSDATE ile tarih alanina sistem tarihi yaziliyor.Burada herhangi bir "placeholder" kullanmadim cunku oraya yazilan veri direkt sistemden geliyor ve benim bir kontrol yapmama bu nedenle gerek yok.

Sorguyu tamamladigimiza gore OCIParse () fonksiyonu ile "uygulama islemine hazirlanmasini" saglayabiliriz :

<?php
$iSorguIfadesi = @OCIParse($iDBConn, $qsvCalisanEkle);
?>

OCIParse () fonksiyonu bir "sorgu tanimlayicisi" yani ingilizcesi "statement identifier" olarak ifade edilen bir sonuc dondurur.Biz bu sonucu asagidaki gibi inceleyip sorgunun veritabani uzerinde uygulanmasina veya OCIRollback () fonksiyonu ile veritabaninin ilk haline dondurulmesine karar verebiliriz.Kisaca anlatilmak istenen, sorgunun icinde bir hata olup olmadigini ve sorgu ile ilgili veritabanindan donen sonucu asagidaki gibi irdeleyebiliyoruz :

<?php
//
// SQL Ifadesi gecerli mi?
//
$arrError = OCIError($iSorguIfadesi);
if ($arrError['code'])
{
print $arrError['message'];
OCIRollback($iDBConn);
exit;
}
?>

ONEMLI : Burada deginilmesi gereken en onemli nokta OCIRollback () fonksiyonu ile veritabani ilk haline getirilse de INCREMENT BY ifadesi ile otomatik olarak arttirilan tablo alanina sorgu sirasinda atanan deger asla geriye donderilmez.Yani tabloda o alanda 3 degeri varken sizin sorgunuzdan sonra o alana otomatik olarak 4 atanmis ise OCIRollback () ile geriye dondugunuzde o alan icin tekrar sorgulama yaparsaniz bu sefer size ornegin 5 degerinin atandigini goreceksiniz...


Simdi referans olarak verdigimiz alanlara gelecek verileri olusturalim.Bu islemi OCIBindByName () fonksiyonu ile yapiyoruz :

<?php
//
//Referans olarak verilen yerler icin verileri olustur.
//
@OCIBindByName($iSorguIfadesi, ':calisan_id_no', &$iCalisanNo, 4);
@OCIBindByName($iSorguIfadesi, ':adi_tx', &$strAdi, 64);
@OCIBindByName($iSorguIfadesi, ':sadi_tx', &$strSoyadi, 64);
@OCIBindByName($iSorguIfadesi, ':telefon_tx', &$strTelefon, 14);
@OCIBindByName($iSorguIfadesi, ':eposta_tx', &$strEposta, 255);
?>

Burada iki onemli noktaya deginilmesi gerekiyor.Birincisi bu yontem ile fazladan addslashes () kullanimina gerek kalmiyor (verinin icindeki tirnak isaretleri ve benzeri zararli datayi elimine etmek icin kullanilan fonksiyon), ikincisi ise eger islenen veri "bos" degere sahipse onu NULL olarak veritabanina yazabilmesidir...

En son olarak OCIExecute () fonksiyonu ile sorgunun veritabani uzerinde uygulanmasini sagliyoruz.(Tabii ki yukarida gorulen sekilde butun degiskenler referans edildikleri yere baglandiktan sonra)

Fonksiyonun kullaniminda onemli olan nokta OCI_DEFAULT parametresi ile Oracle'a auto-commit,yani sorgu basarili sekilde uygulanirsa otomatik olarak degisiklikleri kaydetmesi ozelliginin kapatilmasinin soylenmesidir.Her ne kadar yararli gibi gorunsede bazen coklu tablolar uzerinde yapilan UPDATE islemlerinde bu ozelligin kapatilmasi verinin zarar gormesini onleyecektir.Eger sorgu basarili sekilde uygulanirsa OCICommit () fonksiyonunu cagirarak sorgunun sonuclarinin veritabani uzerinde kayit edilmesini saglayabilecegiz...

<?php
//
// Sorguyu veritabani uzerinde uygula....
//
@OCIExecute($iSorguIfadesi, OCI_DEFAULT);
//Hata olusmadigindan emin olalim...
$arrError = OCIError($iSorguIfadesi);
if ($arrError['code'])
{
print $arrError['message'];
OCIRollback($iDBConn);
exit;
}
OCICommit($iDBConn);
?>

Veritabanindan Verileri Dondurup HTML Formatinda Goruntulemek

Yukarida anlatilan sekilde oldugu gibi veritabanindan veri dondururkende ayni siralama izlenir.Once sorgu hazirlanir,ardindan bu sorgu denetlenir,eger hata bulunmaz ise veritabani uzerinde uygulanir,uygulama islemi sorunsuz olarak tamamlanirsa degisiklikler veritabanina kayit edilir...

SELECT sorgularinin yapisi geregi herhangi bir sekilde veritabanindaki veri bir sekilde degisiklikge ugramaz.Yanlizca veri istenilen sekil ve format istegi yapan cihaz,program vb. araclara dondurulur.

Boylece yukarida anlatilan adimlardan OCIBindByName (), OCIRollback (), ve OCICommit () fonksiyonlarinin kullanildigi bolumlerin uygulanmasina gerek kalmaz.

<?php
//
// Veriyi dondurmek icin sorguyu hazirlayalim...
//
$qsvCalisanGoruntule = "
SELECT calisan_id_no,
adi_tx,
sadi_tx,
telefon_tx,
eposta_tx,
FROM calisanlar
ORDER BY sadi_tx ASC,
adi_tx ASC ";
$iSorguIfadesi = @OCIParse($iDBConn, $qsvCalisanGoruntule);
@OCIExecute($iSorguIfadesi, OCI_COMMIT_ON_SUCCESS);
//
//Sorguyu kontrol et
//
$arrError = OCIError($iSorguIfadesi);
if ($arrError['code'])
{
print $arrError['message'];
exit;
}
?>
<table border="1" width="600">
<tr>
<td>ID</td>
<td>SOYADI</td>
<td>EPOSTA</td>
<td>TELEFON</td>
</tr>
<?php
//
//Kayitlarimizi bir dongu icerisine sokup her satirda
// bir tane olacak sekilde gosterelim.
//OCI_ASSOC ile OCIFetchInto ile donen degerlerin,dizi icerisinde tablonun alan adi ile //anahtarlanmasini istiyoruz.Normalde index kullanilarak sonuclar dondurulur.
//
while (OCIFetchInto($iSorguIfadesi, &$arrCalisan, OCI_ASSOC))
{
?>
<tr>
<td><?= $arrCalisan['CALISAN_ID_NO'] ?></td>
<td><?= $arrCalisan['ADI_TX'] ?></td>
<td><?= $arrCalisan['SADI_TX'] ?></td>
<td><a href="mailto:<?= $arrCalisan['EPOSTA_TX'] ?>">
<?= $arrCalisan['EPOSTA_TX'] ?></a></td>
<td><?= $arrCalisan['TELEFON_TX'] ?></td>
</tr>
<? } ?>
</table>
</body>
</html>

Evet buraya kadar olan tum aciklamalarimizda ORACLE veritabani icin tablonun yaratilmasi,verinin eklenmesi ve bu eklenen verinin web uzerinden goruntulenmesini inceledik...Yukaridaki mantik ve kod yapisi ile UPDATE,DELETE gibi sorgulari veritabaninda uyuglamak co zor olmayacaktir.