Kullanımdaki dosyayı kilitleyin!
Web sunucusundaki dosyalarımızla sadece bir kişi işlem yapıyor olsa idi, bir sorun olmazdı; ne var ki, bir Web sitesine aynı anda birden fazla kişi eriyebilir ve dosyalarla işlem yapan programları çalıştırıyor olabilir. Bu, PHP'nin dosya işlemlerine engel olabilir. Bu sebeple, işlem için açacağımız bir dosyayı, önce kilitlemek yerinde bir önlem sayılır. Bunu, flock() fonsiyonu ile yaparız; bu fonksiyona kilitlemek istediğimiz dosyanın işaret değişkeninin adını ve kilit türünü belirten endeks sayısını parametre olarak yazarız. Örnek:
<?php
$dosya_adi = "/inetpub/wwwroot/bir_dosya.txt";
$dosya = fopen ($dosya_adi , 'w') or die ("Dosya açılamadı!");
flock ( $dosya , 2); // dosyayı kilitle
$metin = "Bu satır dosyaya yazılacak: Merhaba Dünya!\n";
fwrite ( $dosya , $metin ) ;
fputs ( $dosya , "Bu satır ise sonradan eklenecek\n" ) ;
flock ( $dosya , 3); //dosyayı kilidini aç
fclose ($dosya);
?>
Bu fonksiyon ile kullanabileceğimiz endeks parametreleri şunlardır:
1 Paylaşım Diğer proseslerin dosyayı paylaşmalarına imkan verir
2 Tam Diğer proseslerin dosyaile işlem yapmasına engel olur
3 Serbest Dosyanın 1 veya 2 olan kilidini kaldırır
Bir dosya, herhangi bir PHP programı tarafından kilitlendiği anda, aynı dsyayı daha sonra kilitlemeye kalkan diğer programlar kendilerinden önce konulmuş kilide saygı gösterirler.
Dizinlerle İşlemler
PHP ile sunucuda, Web dizini olarak kullandığımız alanda yeni dizinler oluşturabiliriz, silebiliriz, ve bunlar hakkında bilgi edinebiliriz. Bu işlemleri Web sunucuda yapabilmek için Web dizininde okuma ve yazma izni bulunması gerekir.
Dizin içeriğini listeleme: opendir() ve readdir()
Belirttiğiniz bir dizindeki tüm dosya ve alt-dizin adlarını bir liste, hatta ilişkilendirilmiş hypertext (köprü, link) listesi olarak sunabilmek için önce dizini içeriğini okuyabilmek için opendir() fonksiyonu ile açmak, sonra da içindeki bilgileri readdir() fonksiyonu ile edinmek gerekir. readdir() fonksiyonu dizinin içindeki alt-dizin ve dosyaların adlarını sırayla, tek-tek okur. Bu fonksiyondan gelen bilgileri bir değişkene atayarak ve bir döngü içinde yazdırarak, dizin listesi çıkartabiliriz. Örnek
<?php
$dizin_adi = "./";
$dizin = opendir ($dizin_adi);
while ( gettype ( $bilgi = readdir( $dizin ) ) != boolean ) {
if ( is_dir( "$dizin_adi/$bilgi" ) )
print " [Dizin] " ;
print ("<A href="$dizin_adi/$bilgi">$bilgi</A><br>\n");
}
closedir ($dizin);
?>
Kişisel Web sunucuda sınama amacıyla çalıştırabilmek için dizin adı olarak bu dosyanın içinde bulunduğu dizini verebiliriz. opendir() fonksiyonu da okunmak amacıyla açacağı dizine işaret eden bilgiyi bir değişkene yazmak zorundadır; bu işaret değişkenine burada $dizin adını veriyoruz. $dizin değişkeninin işaret ettiği dizini okuyan readdir() fonksiyonundan dönen bilgileri ise $bilgi değişkenine yazıyoruz. readdir() fonksiyonu dizin bilgisini okumanının sonuna vardığında, bir dosya ve dizin adı yerine doğru veya yanlış şeklinde bir mantıksal (boolean) değer verecektir; buradaki while döngüsü $bilgi değişkeninin türünü gettype() fonksiyonu ile sürekli sınayarak, henüz dizin ve dosya adı edinildiği sırada bu bilgileri print() fonksiyonuna verecektir. Bu bilginin bir dizine ait olup olmadığını is_dir() fonksiyonu ile sınayan if döngüsü ise bilgi bir dizine aitse, bu bilgnin baştarafına "[Dizin]" kelimesini yazdıracaktır. (Bu programı geliştirerek, önce dizinleri, sonra dosyaları yazabilen biçime getirmek mümkündür. Bunun bir örneği bu kitapçığı örnek kod dosyaları arasında dizin_oku01a_server.php ve dizin_oku01a_pws.php aadıyla bulhabilirsiniz.)
Dizin oluşturma: mkdir()
PHP programlarımız gerektiğinde sunucunun yazma yetkisi verdiği Web'e açık kök ve alt-dizinlerde yeni dizinler oluşturabilir. Bunu, mkdir() fonksiyonu ile yaparız. Bu fonksiyona oluşturulacak dizinin adı ve 8 tabanlı (octal) sayı cinsinden ve önüne bir sıfır konarak dizinin okuma/yazma/çalıştırma izinlerini belirten parametre verilir. Örnek:
mkdir ("deneme", 0777);
Burada yer alan 0777, bu dizinin herkes için okuma ve yazma izni olduğunu gösterir. Bu parametre sadece Unix işletim sisteminde çalışan sunucular için geçerlidir.
Dizin silme: rmdir()
PHP programlarımızda gerektiğinde sunucunun yazma yetkisi verdiği Web'e açık kök ve alt-dizinlerde mevcut dizinleri silebiliriz. Bunu, rmdir() fonksiyonu ile yaparız. Bu fonksiyona oluşturulacak dizinin adı parametre verilir. Örnek:
Bir Dosya İşlemi Örneği: Konuk Defteri
Böylece PHP ile "iş yapmak" için gerekli araçlarımıza bir yenisini ekledik. Artık PHP programlarımızdan sabit diskteki dosyalara ulaşmayı ve dosyalarla çalışmayı biliyoruz. Buraya kadar öğrendiklerimizi bir PHP programı üzerinde uygulayabiliriz. Bunun için birlikte bir konuk defteri yapalım.
Diyelim ki konuk defterimize sadeceziyaretçimizin adını, elektronik posta adresini ve kısa bir mesajını isteyeceğiz. Öyle bir sayfa yapalım ki; ziyaretçi bu sayfayı ilk kez açtığında, yani henüz Form'dan sunucuya bir veri gelmemiş dolayısıyla $HTTP_POST_VARS dizi değişkenin içinde değer bulunmadığı sırada, programımız bu durumu belirleyerek ziyaretçiye konuk defteri Form'nu sunmalı; ziyaretçi formu doldurup gönder düğmesini tıkladığı zaman programımız bir yandan ziyaretçinin gönderdiği bilgileri kendisine gösterir ve teşekkürlerimizi aktarırken, diğer yandan da bu bilgileri bir düzyazı programı girmeli. Bu sırada ziyaretçimize isterse defterimizdeki diğer mesajları okuma imkanı da sunabilmeliyiz. Biraz uzunca olan şu programı kd_01.php adıyla kaydedelim. (Bu dosyayı, kitapçığın örnek kodlar arasında bulabilirsiniz; fakat bu alıştırmayı bir düz yazı programı ile buradaki örnek ifadeler ve alan/değişken adlarını değiştirerek tekrar etmeniz yerine olur:
<?php
if ( isset ( $HTTP_POST_VARS )) {
// Form dolduruldmuş ise
echo ("
<HTML>
<HEAD>
<TITLE>PHP'de Misafir Defteri</TITLE>
<meta http-equiv='content-type' content='text/html; charset=ISO-8859-9'>
<meta http-equiv='Content-Type' content='text/html; charset=windows-1254'>
</HEAD>
<BODY>
<P><font size='3' class='s4' face='Arial, Helvetica'>
");
Programımızın buraya kadar olan bölümü, if ile $HTTP_POST_VARS dizi değişkeninde değer bulunup bulunmadığına ilişkin sınamanın olumlu sonuç vermesi halinde uygulanan bölümüne dahil. Burada dikkatini echo() fonksiyonu ile birden fazla satır yazdırdığımız çekmiş olmalı. echo(), fonksiyonuna Browser penceresine göndereceğimiz değerleri çift-tırnak içinde yazacağımız için, HTML etiketlerinin çift-tırnak gerektiren etiketlerinde tek tırnak kullandığımıza dikkat edin. if sınavının olumlu sonucuna ilişkin bölümü yazmaya devam edelim:
$dosya_adi = "mesajlar.txt";
if (file_exists("$dosya_adi")) {
$yazilacak_dosya = fopen($dosya_adi,'a');
}
else {
$yazilacak_dosya = fopen($dosya_adi,'w');
}
foreach ($HTTP_POST_VARS as $anahtar=>$deger ) {
$yeni_anahtar = strtoupper($anahtar);
print ("$yeni_anahtar: $deger<br>");
$metin = "$yeni_anahtar: $deger<br>";
fputs($yazilacak_dosya, $metin);
}
fputs($yazilacak_dosya, date("D d M Y h:i:s"));
fputs($yazilacak_dosya, "<br>\n");
fputs($yazilacak_dosya, "<center>
<img src='nokta.gif' width=100% height=1 border=0></center>\n");
fclose($yazilacak_dosya);
Konuk defteri programımızHTML için gerekli temel etiketleri ürettikten sonra bu bölümde veritabanı dosyası olarak kullandığımız mesajlar.txt isimli dosyanın bulunup bulunmadığını sınıyor; dosya varsa ek yapmak için ('a'),dosya yoksa yazmak için ('w'), dosyayı açıyoruz. Sonra, $HTTP_POST_VARS dizi-değişkenine Form'dan gelmiş olan anahtar=değer çiftlerinin her birini (yani, Browser'dan gelen örneğin "adi" değişkeni ve bunun değeri olan ismi) önce print() ile ziyaretçinin Browser'ına, sonra da fputs() ile biraz önce açtığımız veritabanı dosyasına yazdırıyoruz. Fakat burada bundan önce Form'dan küçük harf olarak gelen değişken adlarını (anahtarları) strtoupper() fonksiyonu ile büyük harfe çeviriyoruz.Şimdilik bu fonksiyonun üzerinde durmayın; biraz sonra metin düzenleme ve düzenli ifadeler konusuna geleceğiz. Ancak bu sırada ziyaretçilerin mesajlarını daha sonra güzel görüntelemek için aralarına çizgi olarak kullanmak üzere bir resim dosyasını IMG etiketi ile yerleştirdiğimize de dikkat edin. Bu grafik dısyasının eni-boyu 1 piksel olduğu halde burada ziyaretçinin Browser penceresinin eni kadar genişleterek çizgi üretmiş oluyoruz! Evet, koda devam:
echo ("
<HTML>
<HEAD>
<TITLE>PHP'de Misafir defteri</TITLE>
<meta http-equiv='"content-type' content='text/html; charset=ISO-8859-9'>
<meta http-equiv='Content-Type' content='text/html; charset=windows-1254'>
</HEAD>
<BODY>
<P><font size='3' class='s4' face='Arial, Helvetica'>
<center><img src='nokta.gif' width=100% height=1 border=0></center>
Sayın: $adi<br>
Defterimi imzaladığınız için teşekkür ederim</P>
<p>Ana Sayfaya Dönmek için <A HREF="index.htm"> tıklayın</A><BR>
Mesajları okumak için<A HREF="mesajlar.php"> tıklayın</A>
</BODY>
</HTML>
");
}
Programımızın bu bölümünde, ziyaretçiye teşekkür ediyoruz; ve isterse diğer mesajları okumak üzere tıkllayacağı köprüyü sağlıyoruz. Mesajların çok uzaması halinde bu köprüyü bir sayfanın üstünde, bir de altında vermekte yarar var. Şimdi, programımızın Form doldurulduktan sonra işleyen bölümünü yazmış olduk. Taa en başta yaptığımız $HTTP_POST_VARS dizi-değişkeninin değer içerip içermediğine ilişkin sınamanın olumsuz olması halinde, prıogramımız, işe buradan başlayacaktır:
else {
echo ("
<HTML>
<HEAD>
<TITLE>PHP'de Formlar</TITLE>
<meta http-equiv='"content-type' content='text/html; charset=ISO-8859-9'>
<meta http-equiv='Content-Type' content='text/html; charset=windows-1254'>
</HEAD>
<BODY>
<FORM ACTION="$PHP_SELF" METHOD="POST">
<P><font size='3' face='verdana, Arial, Helvetica'>
Defteri imzalamadan okumak için <a href='mesajlar.php'>
burayı tıklayın</a></FONT></P>
<P><font size='3' face='Arial, Helvetica'>
Adınız, Soyadınız: <br><INPUT TYPE="TEXT" NAME="adi"><BR>
Elektronik Adresiniz: <br><INPUT TYPE="TEXT" NAME="adres"><BR>
Mesajınız:<BR>
<TEXTAREA NAME="mesaj" ROWS=10 COLS=30 WRAP=virtual></TEXTAREA>
<BR><BR><BR>
<INPUT TYPE="SUBMIT" VALUE="Defteri imzala!">
<INPUT TYPE="RESET" VALUE="Tümünü sil!">
</FORM>
</BODY>
</HTML>
");
}
?>
Bu bölümde çift-tırnak işaretlerini değiştirmek yerine, bunları ESC karakteri ile özel işaret değil, metin olarak ele alınacak hale getirdik. Programımız burada yine echo() ile düz ve basit bir HTML Formu oluşturuyor. Programın akış planını anlamış olmalısınız: ziyaretçi önce Form'u dolduracak ve gönder düğmesini tıklayacak.
Bu ACTION, Form'da INPUT alanlarındaki değerleri POST yöntemiyle yine kendisine gönderecek; böylece PHP, programı yeniden çalıştırırken, bu kez en baştaki şartın yerine geldiğini (yani $HTTP_POST_VARS dizi-değişkeninin değer içerip içermediğine ilişkin sınamanın olumlu sonuç verdiğini) görerek, işe baştan baştan başlayacaktır. Bu, INPUT etiketinin alanlarından oluşturulan değişkenlerden yararlanarak, ziyaretçiye bize ulaştırdığı bilgileri ve bizim teşekkür mesajımızı yollamaktan ibarettir.
Program bu şekliyle ne güvenlik önlemlerine sahip, yani kötüniyetli kişilerin INPUT alanlarına kötü niyetli kodlar yazmaları halinde bunları ayıklıyor; ne de ziyaretçinin boş Form gönderip göndermediğini sınıyor. Bu gibi işleri, PHP ile metin düzenlemeyi öğrendikten ve Düzenli İfadeler denen kavramı ile tanıştıktan sonra yapacağız.
Metin Düzenleme ve Düzenli İfadeler
Web programlarımızda bir ziyaretçinin bize ulaştırdığı Form bilgilerini ve bir veritabanı dosyasından aldığımız ham verileri yeniden düzenlememiz gerekir. PHP bunu yapabilmek için bize 50'den fazla fonksiyon sağlar. Bunlardan sık kullanmamız gerekenleri ele alacağız. Daha sonra, özellikle Unix işletim sistemine, Perl veya Javascript diline aşina olanların hatırlayacağı Düzenli İfadedeler denen metin ve sıralanış (pattern) eşleştirme araçlarının üzerinde duracağız. Bu iki araçla, elimize aldığımız berhangi metne istediğimiz biçimi vermek veya metnin içinden istediğimiz bölümü hemen hemen tamamen seçip biçimlendirmek ve kullanmak mümkün olur.
Temel Alfanümerik Fonksiyonları
PHP'nin metin olarak gördüğü değişkenlere alfanümerik (String) türü değişkenler adını vermiştik. PHP'nin alfanümerik fonksiyonları, bu tür değişkenlerin değerlerinin içinden bir bölümü alma, atma veya değiştirme imkanı sağlar. Programlarımızda sık kullanacağımız bir kaç fonksiyonu ele alalım. Bu fonksiyonların tam listesini bu kitapçığın örnek kodları arasında alfa_fonksiyonlar.htm adlı dosyada bulabilirsiniz. (Aşağıdaki örnekler de alfa_fonksiyonlarXX.php adlı dosyalarda bulunabilir.)
substr()
Bir alfanümerik değişkenin değerinin veya bir metnin tanımladığınız bölümünü verir. İkisi zorunlu, biri seçmeli üç parametre ile kullanılır. Yazılışı:
substr($degisken, başla, [boyut] );
Burada, $degisken yerine içinden bir bölümü seçmek istediğiniz metni tutan değişkenin adını; başla yerine seçme işleminin başlayacağı karakterin baştan itibaren kaçıncıdan sonra olduğunu ve isterseniz boyut yerine de seçilmesini istediğimiz karakter sayısını yazarız. Kaç karakter seçileceğini gösteren boyut parametresini yazmazsanız, PHP değişkenin veya metnin sonuna kadar seçer. Örnek
$secilen = substr ("abcdef", 1);
Burada $secilen değişkeninin değeri "bcdef" olacaktır; çünkü birinci karakterden sonra seçime başlatıyoruz ve seçimin boyutunu belirlemiyoruz. PHP, verdiğimiz metnin sonuna kadar seçecektir.
$degisken = "Olumsuz düşünce ve mekanizmalar üzerine olumlu şeyler bina edilemez!";
$secilen = substr ($degisken, 8, 20);
Burada ise seçime 8'nci karakterden sonra başladığımız ve 20 karakterlik seçim yapılmasını belirttiğimiz için seçilen değer "düşünce ve mekanizma" olacaktır.
Başlanıç olarak verdiğiniz sayı negatif ise (önünde - işareti varsa) seçim işlemine değişkenin sonundan itibaren başlanır. Yukarıdaki substr() fonksiyonunu:
$secilen = substr($degisken, -9);
şeklinde yazarsak, dönen değer, "edilemez!" olacaktır.
trim()
Bir alfanümerik değişkenin değerinin baş ve son tarafındaki boşlukları atar. Yazılışı:
trim($degisken);
Bu fonksiyon değişken değerinin veya metnin başındaki ve sonundaki "\n", "\r", "\t", "\v", "\0", ve aralık işaretini boşluk sayar. Örnek:
$degisken = "\0 Olumsuz düşünce ve mekanizmalar üzerine olumlu şeyler bina edilemez!\n\r\t";
$secilen = trim ($degisken);
Burada seçilen metinde, baştaki boşluk, sondaki yeni satır, satır başı ve sekme karakterleri olmayacaktır.
chr()
Parametre olarak ASCII değerini belirttiğimiz karakteri sağlar. Örnek:
echo (chr(34);
Bu komutla Browser penceresinde çift-tırnak işareti görüntülenir.