AJAX’in artık bir çok farklı alanda kullanılabileceğini eburhan‘ın AJAX Ne Gibi Durumlarda Kullanılmalı? başlıklı yazısında gördük. Gelin bunlara bir de AJAX ile sitemize dosya göndermeyi ekleyelim. Bunun nasıl yapıldığını kendi yazmış olduğum AJAX Göndermeç isimli betik ile anlatmaya çalışacağım. Konu hakkında biraz daha ipucu vermek gerekirse AJAX ile dosya göndermenin mümkün olup olmadığını göreceğiz.
AJAX ile dosya göndermenin mantığı
Yukarıda AJAX ile dosya göndermenin mümkün olup olmadığını göreceğimizi söylemiştim. Şimdi de cevabını veriyorum; malesef hayır, yani AJAX ile dosya gönderemiyoruz. Sebebini açıklamak gerekirse, bildiğiniz gibi normal form bilgilerini GET ve POST metodlarıyla gönderiyoruz. Form ile dosya göndereceğimiz zaman da POST metodunu kullanırız ve karşı tarafta da gönderilen dosyanın bilgilerini $_FILES[’…’] değişkeni ile alabiliriz.
AJAX ile dosyayı göndermeye çalıştığımızda ise form normal bir şekilde gönderiliyor gibi görünmektedir fakat alıcı dosyada $_FILES[’…’] değişkeni bir sonuç vermez ve hata ile karşılaşırız. Çünkü kullanmış olduğumuz tarayıcılar malesef güvenlik nedeniyle (özel ayarlar yapılmadığı müddetçe) XmlHttpRequest nesnesi üzerinden dosya göndermeye müsade etmiyor
Peki bir çözümü var mıdır ve varsa nedir? Kısmen de olsa bir çözüm var diyebiliriz; gizli bir iframe kullanmak. Sitemize göndereceğimiz dosyayı seçtikten sonra formumuzu bu iframe’e göndeririz. Ardından AJAX ile dizin listemizi güncelleriz. Kullanıcı sanki tek bir işlem oluyormuş gibi görür yani dosyanın AJAX ile gönderildiğini düşünür. Oysa ki dosyayı gönderen AJAX değil bildiğimiz HTML formu ve iframe‘dir. İnanıyorum ki AJAX Göndermeç‘i açıkladıktan sonra konuyu daha iyi anlayabilirsiniz.
AJAX Göndermeç betiğimiz iki klasör ve 4 adet dosyadan oluşuyor.
Ajax Göndermeç dosyaları
Dosyaları tanıtmaya başlamadan önce şunu söylemeliyim ki sanırım artık dosyaların içini olduğu gibi yazmama gerek yok. Zaten makalenin sonunda indirebileceğiniz bağlantılar bulunuyor. Yazımda sadece kodlarda dikkatinizi çekmek istediğim noktaları belirteceğim.
KLASÖRLER
dosyalar: Sitemizde göndermiş olduğumuz dosyaları barındırdığımız klasör. İsteğinize göre değiştirebilirsiniz. Önemli olan klasörün izninin yani CHMOD ayarının 777 yani yazılabilir olması gerektiği.
eyceks: Bu betiği hazırlarken sitemiz yazarı Erhan Burhan’ın eyceks isimli kütüphanesinin son versiyonu olan 1.3′ten faydalandım. eyceks klasöründe eyceks kütüphanesi (eyceks.js) ile yüklenme esnasında gösterilecek olan resim dosyası (loading.gif) bulunuyor.
DOSYALAR
index.php: Betiğimizin temel dosyası ve anasayfasıdır. Dosya gönderme formu, javascript fonksiyonlarımız ve css stil seçicilerimiz bu dosyada bulunur. Dosyanın dikkatinizi çekmek istediğim kısmı javascript fonksiyonlarıdır.
PLAIN TEXTJAVASCRIPT:
function dosyaSil(silinecekDosya) {
if( confirm('Dosya Silinsin mi?') ) {
var sc="yap=sil&dosya="+silinecekDosya;
JXP(1, "dizin_alani", "cevap.php", sc);
}
}
function yenile() {
var sc="yap=yenile";
JXP(1, "dizin_alani", "cevap.php", sc);
}
function dosyaGonder(){
document.dosyaFormu.submit();
var sc="yap=gonder";
JXP(1, "dizin_alani", "cevap.php", sc);
document.dosyaFormu.reset();
}
Farkettiyseniz artık AJAX nesnesi XmlHttpRequest'i çağırmak için bir ton kod ile uğraşmıyoruz. Hazır kütüphane kullanmanın faydalarından birisi de budur. Tabi konunun mantığını anlamadan da hazır kütüphane kullanmanızı kesinlikle tavsiye etmiyorum.
Javascript fonksiyonlarına dönecek olursak:
dosyaSil(dosya) fonksiyonu cevap.php dosyasına silinmesini istediğimiz dosyanın ismini gönderir. Gelen sonuç dizin_alani id'sine sahip alanda görüntülenir. Şunu da belirtmekte fayda var, gelen sonuç yine dizindeki dosyaları listeleme işlemidir.
yenile() fonksiyonu dosya listesini yenilemenizi sağlayan fonksiyondur. Tüm sayfa yerine sadece AJAX sayesinde dosya listesini yenileyebiliyoruz. Yenilerken yapılan işlem cevap.php dosyasından dizini listelemesini istemekten başka bir şey değildir
dosyaGonder() fonksiyonu önce formumuzu yani gözat diyerek seçmiş olduğunuz dosyayı iframe'e gönderir, ardından cevap.php dosyasından dosya listesini yenilemesini ister ve son olarak formu sıfırlar.
Not: Dosyayı iframe'e göndermesini buradan değil, formun tanım bilgisinden target="pencere" yani pencere isimli iframe diyerek belirtiyoruz.
dizin.php: Bu dosyanın tek işlevi kendi içinde barındırdığı ve bizim düzenlediğimiz klasor değişkeni ile belirtilen dizindeki dosyaları listelemek. Bu dosyayı include('dizin.php'); diyerek anasayfada(index.php) ve cevap.php dosyasında çağırıyoruz.
PLAIN TEXTPHP:
<?php
$klasor = "dosyalar/"; //Burayi duzenleyin
$sonuc='<table style="font-size:12px;">';
if ($dizin = opendir($klasor)) {
while ($dosya = readdir($dizin)) {
if ($dosya!='.' AND $dosya!='..')
{
$sonuc.= '<tr style="background-color:#EEEEEE;height:10px;border:1px dashed Gray;">';
$sonuc.= '<td style="padding: 5px;" width="450" align="left">';
$sonuc.= '<a href="dosyalar/'. $dosya. '">'. $dosya. '</a></td>'; //burasi onemli
$sonuc.= '<td style="padding: 5px;" width="50" align="center">';
$sonuc.= '[<a href="javascript:dosyaSil(\''. $dosya. '\');">sil</a>]</td>';
$sonuc.= '</tr>';
}
}
closedir($dizin);
}
$sonuc.='</table>';
echo $sonuc;
?>
cevap.php: Bu dosya AJAX ile bilgileri gönderdiğimiz dosyadır. İki adet işlevi bulunmakta:
1) Eğer silme işlemi seçilmişse, dosya değişkeni ile gelen dosyayı siliyor.
2) Dizindeki dosyaları dizin.php dosyasını çağırarak listeliyor.
Burada dikkatinizi çekmek istediğim konu sleep(2) fonksiyonu. Bu fonksiyon içine girilmiş olan değer boyunca(saniye) betiği bekletir. Bekletmek istedim çünkü aynı zamanda bir yandan iframe'e gönderilmiş bir dosya bulunmakta ve bu dosya siteye yüklenmekte. Diyelim ki dosyamız biraz büyük. O halde cevap.php fonksiyonundan cevap geldiğinde dosya hala yüklenmediği için yine eski dizini görebiliriz. Bu yüzden de dosyanın gönderilmediğini sanarız. Oysa ki dosya hala gönderilmektedir. Aslında buna bir tedbir olarak anasayfaya (index.php) dizin listesini yenilemek için Yenile bağlantısı koydum ama yine de bu sleep fonksiyonu da bir önlem olabilir.
PLAIN TEXTPHP:
<?php
$klasor = "dosyalar/"; //Burayi duzenleyin
if ($_POST['yap'] =="sil")
{
$dosyasil = $klasor.$_POST['dosya'];
$silindi=unlink($dosyasil);
}
sleep(2);
include('dizin.php');
?>
islem.php: Bu dosya iframe içinde çağırdığımız dosyadır ve form ile gönderilen dosyayı yine islem.php dosyasında bulunan klasor değişkeni ile belirttiğimiz klasöre gönderir.
PLAIN TEXTPHP:
<?php
$klasor = "dosyalar/"; //Burayi duzenleyin
$giden = $klasor . basename($_FILES['dosya']['name']);
move_uploaded_file($_FILES['dosya']['tmp_name'], $giden)
?>
Ve mutlu son
Bu uygulama geliştirildiği takdirde basit işlemler için güzel bir dosya yöneticisi haline dönüşebilir. Hatta dosya gönderme işlemi php'nin ftp fonksiyonlarıyla yapılırsa tıpkı bir ftp programı gibi kullanılabilen bir betik bile olabilir
Umarım AJAX Göndermeç'ten memnun kalırsınız. Maksadım mantığını anlatmak olduğu için basit bir örnek sundum size. Belki ilerki seviyelerde sadece kullanmanız için güzel örnekler verebiliriz.