Bazı web sitelerinin siz bir ZIP dosyası gönderdiğinizde ilgili dosyayı açıp içindeki dosyaları sitenin tercihlerine göre işlediğine şahit olmuşunuzdur. NETTUTS'ta yayımlanan bu makale ile sizlere PHP kullanarak Zip dosyalarının nasıl açılabileceğini açıklamaya çalışacağım.
Yapmamız Gerekenler
Adım 1: Upload Formunu Oluşturmak

|
|
Kullanıcılarınızın dosya göndermesine izin vereceğinz her zaman, form etiketindeki "enctype" değerini "multipart/form-data" olarak değiştirmeniz gerekir. Ardından formun hedefini forumun bulunduğu sayfaya yönlendirecek, ve "method" değerini "post" olarak belirteceğiz.

Her şeyi mümkün olduğu kadar sade tutabilmek için sadece dosya giriş alanı ve gönder düğmemiz var. Dosya giriş alanının adını "fupload" olarak belirlediğimize dikkat edin. Birazdan bu değeri sayfanın geri gönderilip gönderilmediğini kontrol etmek için kullanacağız.
Adım 2: PHP'yi Yazmak
index.php sayfanızın en üzerinde, doctype değeri henüz belirtilmeden aşağıdaki kodu girin:
|
|
Adım adım anlatalım:
Diyelim kullanıcı "myPics.zip" adında bir dosya seçmiş olsun.

Şimdi, dosya adını ve uzantısını ayıralım:
|
|
"myPics.zip" dosya örneğimizde olduğu gibi - $name[0] "myPics" değerini, $name[1] "zip" değrini alacak.
Şimdi, $target adında bir değişken oluşturalım. Bu değişken dosyamızın sunucuda kaydedilecek konumunu belirtsin. Başka bir kullanıcının "myPics" adında bir dosya göndererek halihazırda sunucuda bulunan "myPics" dosyasının üzerine yazmasını enlemek için gönderilen dosyanın tekil bir yere kaydedilmiş olduğundan emin olmamız gerek. Bu görevi yerine getirebilmemiz için "time()" fonksiyonunu dahil edeceğiz. Eğer bu değeri gönderilen dosyanın adına dahil edersek her zaman tekil bir klasör adı kullanılacağından emin olabiliriz.
$target = "dosyalar/myPics-31122009/"
Adım 3: Zip Dosyasının Seçili Olduğundan Emin Ol
$target değrinden hemen sonra aşağıdaki kodu yapıştırın:
|
|
Ne yazık ki Safari ve Chrome tarayıcları zip dosyaları için türü kaydetmiyorlar. Bu da bizim için bir problem oluşturuyor. Biraz araştırmadan sonra, PEAR uzantısını kullanmadan basit bir çözüm bulamadım. Bunun yerine biz de en azından dosya adının .zip ile bittiğinden emin olmamız gerekecek. Bunun %100 güvenli olmadığını bilyorum. Ya kullanıcı uzantısı .zip olan başka bir dosya gönderirse? Yorumlarınızı bekliyorum.
|
|
Sırada $okay değişkeninin değerinin false olup olmadığını kontrol edeceğiz. Eğer false ise 'zip' dosyasının seçilmediğini anlayacağız. Bu durumda PHP'ye kodu işlemeyi durdurmasını söyleyeceğiz.
|
|
Adım 4: Zip Dosyasını Kaydetmek
|
|
Adım 5: openZip() Komutu
Yeni bir sayfa oluşturun ve "functions.php" adıyla kaydedin, sonra aşağıdaki kodu yapıştırın.

|
|
Bu fonksiyon sadece bir parametreyi kontrol edecektir: $file_to_open. Bu parametre açmaya çalıştığımız zip dosyasının konumunu içerecektir.

Unutmayın - functions.php dosyamızı oluşturduk ancak onu dahil etmemiz gerekiyor. Aşağıdaki kodu 'index.php' sayfanızın üst kısmına, PHP açılış etiketinin hemen ardına ekleyin.
|
|
İçeriği Yazdırmak

Şimdiye kadarki her şey sorunsuz çalışıyor. Ancak size biraz geribildirim vermek için, yeni dizini taratalım ve içeriğini ekrana yazdıralım. Aşağıdaki kodu projenizden silmeniz gerek, zira bu kod sadece test etmeniz için var. Eğer kodu kullanmak istiyoesanız, o zaman bilgiyi echo kullanarak body etiketi içerisinde yazdırın.
|
|
Bu son bölüm hakkında çok konuşmayacağım - çünkü gerekli değil. Çok kısaca, yukarıdaki betik yeni dizinimizi tarıyor ve içeriğini sırasız liste olarak ekrana yazdırıyor.
Bitti
Çok zor değildi, değil mi? Projelerinize kolayca dahil edebileceğiniz kullanışlı bir özellik. Zip dosyaları gönderirken oluşabilecek olası güvenlik açıklarına yönelik görüşleriniz neler? Zip dosyasının içeriğinin zararsız olacağından nasıl emin olabiliriz? Bu güvenlik konularında herkesin yorumlarını duymak isterim. Eğer dikkatli bir şekilde kullanılmadığında bir bilgisayar korsanı sunucunuza ciddi zararlar verebilir. Gelin tartışalım! Tehlikeli dosyaları aramak (.htaccess dosyaları) ve silmek mümkün.
index.php Sayfasının Son Hali
|
|
önceki yazı Curl ile Birden Fazla Kaynaktan Veri Çekmek |
sonraki yazı JSON Tekniği ve Javascript ile ilişkisi.. |
Birincisi dosya ya da klasör ismi çakışması durumunu engellemek için isim içine tarih eklediniz. Ama bu tarih değeri bence yeterli değil. Ufak çapta ve az ziyaretçisi olan sitelerde sorun olmayacaktır ama yoğun ziyaretçisi olan sitelerde örneğin bir yılbaşı günü geldiğinde yüzlerce "cristmas" isimli dosya gelecektir. içine her ne kadar tarih eklesek bile çakışma olasılığı oldukça yüksek. Bu tarih ile birlikte saat dakika ve saniye değerlerini (hatta mümkünse salise) eklemek gerekir.
İkinci olarak dediğiniz gibi dosya uzantısını kontrol etmek pek bir şeyi değiştirmeyecektir. Zira amacı hack olan birisi zaten sizin uzantı kontrolü işleminizi rahatlıkla aşıyor. En çok dikkatsiz kullanıcıların .zip değil .jpg yüklemesini önlemiş olur. Ama bunun için server tarafında kasmaya gerek yok ki zaten. javascript ile de bunu server'ı hiç yormadan yaptırabiliriz. Ama bunun ile hedef kitlesi sadece hack bilgisi olmayan kötü amacı olmayan kullanıcıların yanlışlıklarını absorbe edebiliriz.
Benim fikrime göre yüklenen dosya binary olarak açılıp dosya başlığı okunabilirse ancak bu şekilde bir çözüm üretilebilir. zip algoritması format bilgilerini içeren başlığını sıkıştırmıyor diye biliyorum. her neyse ama bu sefer de server bu dosyayı açtığında zip'li bir içerik yerine virüs koduna rastlar ise bu da belleğe alınacak, belleğe sızmayı başaran kod kendini bir şekilde işlemciye çalıştırabilecektir. Sonuç olarak bu da bir çözüm olmaktan çıkar.
Bir başka yol da server tarafındaki antivirüsleri script içinden ve yüklenen dosyaları kontrol etmesi için tetiklemek gerekir. Belki her gün belli saatlerde topluca bir kontrol yapılabilir performans açısından. Yani kullanıcıları biraz bekletiriz. Bileşen desteği olan antivürüsler kullanmak gerekecektir. Ama sanırım en garantili yöntem bu olsa gerek..
Nettuts'daki yazının yorumlarında da söyledik, burada da söyleyelim, zip açmak için bundan daha kötü bir yol seçilemez.
Dosyanın zip olduğunu, bir oradan 1 buradan kontrol edelim diyemessiniz, merkezi ve tam çalışan bir yol bulmanız lazım. Ben çalışma izni olmayan 1 klasöre yükleyip php nin fonksiyonları ile mime type ı kontrol etmeyi tercih ediyorum.
Dosya adında birden fazla . var ise, benim.sevgili.dosyam.zip uzantı testini de geçemeyecektir.
@lazaronnie: time() ile aynı sn de aynı isimle birden fazla dosya yüklenmesi imkansız.
Dosya adında türkçe karakter var ise özellikle unix sunucularda dosya bulunamıyor hatası alır kullanıcılar. Bir çok sunucunun tr lokali olmadan derlendiğini unutmamak lazım.
bence mukemmel bir yazi olmus..anlamadigim noktalardan bir tanesi if structure ile === esit kullanarak compare mi yapiyoruz? == degil miydi o? 2.cisi ise php'de time() fonksiyonu ile klasor isminin cakismasi oldukca uzak bir olasilik gibi gorunuyor ki bunu onlemek icin mesela ip numarasini da isin icine katip daha sonra md5ledikten sonra ; belli bir kismini alip kullanmakta bu olasiligi kaldiriyor..
@its m00dy & alpr;
"===" ve "==" farklı karşılaştırmalardır. "==" sadece değerin eşitliğini karşılaştırırken, "===" veri türünü de karşılaştırır.
pillinetwork sitelerine yorum ekleyebilmek ve daha fazlası için, üye olun ya da giriş yapın.
Nokta ve pilli ortak yapımı olan kodaman.org hep birlikte içerik üretip gelirini yazarları ile paylaştığımız kolektif bir kod yazarları blogudur. Siz de katılabilirsiniz.