Bölüm 19. Dosya yükleme yönetimi

Ýçindekiler
POST metodu ile dosya yükleme
Genel Tehlikeler
Çoklu Dosya Yükleme
PUT Yönetmi Desteği

POST metodu ile dosya yükleme

PHP, RFC-1867 uyumlu tüm tarayıcılardan (Netscape Navigator 3 ve daha üst sürümler, Mücrosoft'un yayınladığı bir yama ile Microsoft Internet Explorer 3, veya diğer üst sürümleri) dosya yüklemek için yeteneklidir. Bu özellik kullanıcıların binary veya metinsel dosya yükleyebilmelerini sağlamaktadır. PHP'nin yetkilendirme ve dosya işleme özellikleri ile, dosyaları kimin yükleybileceği ve yüklendikten sonra ne yapılacağı konusunda tam kontrol sahibisinizdir.

PHP, Netscape Composer ve W3C'nin Amaya üyeleri tarafından kullanılan PUT yöntemi ile de dosya yükleme işlemini destekler. PUT Yöntemi hakkında detaylı bilgi içintıklayınız.

Dosya yükleme ekranı, aşağıdaki gibi özel bir form hazırlamakla oluşturulur:

Örnek 19-1. Dosya Yükleme Formu

<form enctype="multipart/form-data" action="_URL_" method="post">
<input type="hidden" name="MAX_FILE_SIZE" value="1000">
Bu dosyay&inodot; gönder: <input name="userfile" type="file">
<input type="submit" value="Gönder">
</form>
_URL_ bir PHP dosyasını işaret etmelidir. MAX_FILE_SIZE gizli alanı, form içinde dosya alanından üstte olmalıdır ve taşığıdı değer, kabul edilebilir enfazla dosya boyunu gösterir. Değer byte cinsindendir.

Uyarý

MAX_FILE_SIZE sadece tarayıcıya, bu boyutu aşmamasını söyler. Bunu aşmak çok kolaydır. Bu yüzden buna pek fazla güvenmeyin. PHP'nin ayarlarındaki maximum-size ise aşılamaz.

PHP'de , php.ini içindeki register_globals'ın on olduğu varsayılırsa, başarılı bir dosya yükleme anında aşağıdaki değişkenler tanımlanır. Eğer track_vars on ise, bu değişkenler PHP'nin $HTTP_POST_VARS dizinleri olarak da alınabilir. Aşağıdaki değişken adları, yukarıdaki örnekteki 'userfile' alan adının kullanıldığı varsayılarak verilmiştir:

Yukarıdaki değişkenlerin "$userfile" bölümü, yükleme formundaki INPUT TYPE=file alanına verdiğiniz isimdir. Yukarıdaki yükleme formunda biz "userfile" ismini kullandık.

PHP 4'de durum bir parça farklı. Yüklenen dosya bilgileri $HTTP_POST_FILES dizinlerine yüklenmiştir. Bu PHP 3'de olduğu gibi, eğer track_vars on olarak tanımlanmış ise geçerlidir. Fakat PHP 4.0.2 ve üst sürümlerinde track_vars on olarak tanımlı gelir.

$HTTP_POST_FILES'ın içeriği aşağıdaki gibidir. Bu örnekte de, formdaki dosya yükleme alanının adının "userfile" olduğu varsayılmıştır:

$HTTP_POST_FILES['userfile']['name']

Dosyanın, dosyayı gönderenin bilgisayarındaki orijinal adı.

$HTTP_POST_FILES['userfile']['type']

Tarayıcının bu bilgiyi vermesine bağlı olarak, dosyanın mime tipi. Örneğin "image/gif".

$HTTP_POST_FILES['userfile']['size']

Gönderilen dosyanın byte cinsinden boyutu.

$HTTP_POST_FILES['userfile']['tmp_name']

Dosyanın, sunucuda saklanan geçici adı.

php.ini içindeki upload_tmp_dir tanımlamasına farklı bir yer tanımlanmadıkça, dosyalar, sunucuda tanımlı olan geçici klasör de saklanır. Sunucunun tanımlı geçici klasörü, TMPDIR değişkeni tanımlanarak değiştirilebilir. Bu tanımlamayı, PHP dosyası içinde putenv() fonksiyonunu kullanarak tanımlamak geçerli olmayacaktır. Bu değişkeni, gönderilen dosya üzerindeki başka işlemlerin çalışırlığından emin olmak içinde kullanabilirsiniz.

Örnek 19-2. Dosya Yükleme Kontrolü

Aşağıdaki örnek, PHP 3'ün, 3.0.16'den ve PHP 4'ün 4.0.2'den yüksek sürümleri içindir. Fonksiyon özellikleri için is_uploaded_file() ve move_uploaded_file() sayfalarına bakınız.

<?php 
if (is_uploaded_file($userfile)) {
    copy($userfile, "/place/to/put/uploaded/file");
} else {
    echo "Possible file upload attack: filename '$userfile'.";
}
/* ...or... */
move_uploaded_file($userfile, "/place/to/put/uploaded/file");
?>

PHP'nin daha önceki sürümleri için, aşağıdaki gibi bir seye ihtiyacınız var.

Not: Bu örnek PHP'nin 4.0.2'den sonraki sürümlerinde çalışmaz.

<?php
/* Userland test for uploaded file. */ 
function is_uploaded_file($filename) {
    if (!$tmp_file = get_cfg_var('upload_tmp_dir')) {
        $tmp_file = dirname(tempnam('', ''));
    }
    $tmp_file .= '/' . basename($filename);
    /* User might have trailing slash in php.ini... */
    return (ereg_replace('/+', '/', $tmp_file) == $filename);
}

if (is_uploaded_file($userfile)) {
    copy($userfile, "/place/to/put/uploaded/file");
} else {
    echo "Possible file upload attack: filename '$userfile'.";
}
?>

Gönderilen dosyayı alan PHP dosyanız, gönderilen dosyanın ne yapılacağına karar vermek için programlanmalıdır. Örneğin, dosya boyutu çok büyük veya çok küçük olan dosyaları kabul etmemek için $file_size değişkenini kullanabilirsiniz. $file_type değişkenini, belirlediğiniz kriterlerdeki dosya tipine uymayan dosyaları kabul etmemek için kullanabilirsiniz. İstemediğiniz bu dosyaları, geçici klasörden silebilir veya farklı bir klasöre taşıyabilirsiniz.

İşlem sonunda, dosya taşınmadı veya adı değiştirilmedi ise, geçici klasörden silinir.