Some hosting does not have permission to use the move_uploaded_file function should replace the copy function
POST yöntemi ile karşıya dosya yükleme
Bu özellik metin ve ikil dosyaları yükleme imkanı verir. PHP'nin kimlik doğrulama ve dosya işletim işlevleri ile kimin karşıya dosya yükleme yetkisi olacağına ve yüklenen dosya ile ne yapılacağı hakkında tam denetime sahip olursunuz.
PHP, herhangi bir RFC 1867 uyumlu tarayıcıdan gelen dosya yüklemelerini alabilir.
Bilginize: İlgili Yapılandırmalar
Ayrıca php.ini içindeki file_uploads, upload_max_filesize, upload_tmp_dir, post_max_size ve max_input_time yönergelerine bakınız.
PHP ayrıca Netscape Composer ve W3C'nin Amaya istemcileri tarafından kullanılan PUT yöntemiyle dosya yüklemeleri de destekler. Ayrıntılı bilgi için PUT Yöntemi Desteği'ne bakınız.
Örnek 1 - Karşıya Dosya Yükleme Formu
Bir dosya yükleme ekranı aşağıdaki gibi özel bir form ile oluşturulabilir:
<!-- Veri kodlama türü, enctype, aşağıdaki gibi belirtilmek ZORUNDADIR -->
<form enctype="multipart/form-data" action="__URL__" method="POST">
<!-- MAX_FILE_SIZE dosya giriş alanından önce bulunmak zorundadır -->
<input type="hidden" name="MAX_FILE_SIZE" value="30000" />
<!-- input elemanının adı $_FILES dizisinin içindeki ismi belirler -->
Bu dosyayı gönder: <input name="kullanici_dosyasi" type="file" />
<input type="submit" value="Dosyayı Gönder" />
</form>
Yukarıdaki örnekteki __URL__ bir PHP dosyası ile değiştirilmelidir.
MAX_FILE_SIZE gizli alanı (bayt cinsinden) dosya giriş alanından önce bulunmak zorundadır ve değeri PHP tarafından kabul edilecek azami dosya boyutudur. Bu form elemanı azami-büyüklüğü aşan bir dosyanın gönderilmesini baştan engelleyeceği için büyük dosyaları boşuna beklememek açısından kullanıcılara zaman kazandırır; bu nedenle her zaman kullanılmalıdır. Ancak unutmayın: Bu ayarı tarayıcı tarafında devre dışı bırakmak oldukça kolaydır, bu nedenle daha büyük boyuttaki dosyaların bu özellik tarafından engelleneceğine güvenmeyiniz. Bunula birlikte, PHP'nin azami-büyüklük ayarı devre dışı bırakılamaz.
Bilginize:
Dosya yükleme formunuzun enctype="multipart/form-data" özniteliğine sahip olduğundan emin olun, aksi takdirde dosya yükleme çalışmaz.
$_FILES küreseli PHP 4.1.0'dan itibaren vardır (Daha eski sürümünü kullanıyorsanız yerine $HTTP_POST_FILES kullanın). Bu diziler bütün yüklenen dosya bilgilerini içerir.
Örnek formdaki $_FILES içeriği aşağıda verilmiştir. Yukarıdaki örneğe göre yüklenen dosya adı kullanici_dosyasi'dır. Bu herhangi bir isim olabilir.
- $_FILES['kullanici_dosyasi']['name']
-
İstemci makinasındaki asıl dosya adıdır.
- $_FILES['kullanici_dosyasi']['type']
-
Eğer tarayıcı bu bilgiyi sağladıysa dosyanın MIME türüdür. Örneğin, "image/gif". Bu MIME türü PHP tarafında denetlenmez; bu bakımdan bu değeri dikkate almayın.
- $_FILES['kullanici_dosyasi']['size']
-
Yüklenen dosyanın bayt cinsinden boyutudur.
- $_FILES['kullanici_dosyasi']['tmp_name']
-
Yüklenen dosyanın sunucuda saklandığı sıradaki geçici dosya adıdır.
- $_FILES['kullanici_dosyasi']['error']
-
Bu dosya yüklemesiyle ilişkili hata kodudur. Bu eleman PHP 4.2.0'da eklenmiştir
php.ini içindeki upload_tmp_dir yönergesi ile başka bir yer belirtilmediyse, dosyalar, öntanımlı olarak sunucunun öntanımlı geçici dizininde saklanır. Sunucunun öntanımlı geçici dizini PHP'nin içinde çalıştığı ortamdaki TMPDIR ortam değişkenine başka bir değer vererek değiştirilebilir. Buna PHP betiği içinden putenv() işlevi ile değer verirseniz çalışmaz. Bu ortam değişkeni diğer işlemlerin yüklenen dosyalar üzerinde çalıştığından emin olmak için de kullanılabilir.
Örnek 2 - Dosya yüklemelerinin doğrulanması
Daha fazla bilgi için is_uploaded_file() ve move_uploaded_file() işlev girdilerine de bakınız. Aşağıdaki örnek bir formdan gelen dosya yükleme isteğini işleyecektir.
<?php
// 4.1.0'dan önceki PHP sürümlerinde, $_FILES yerine
// $HTTP_POST_FILES kullanılmalıdır.
$dizin = '/var/siteler/uploads/';
$yuklenecek_dosya = $dizin . basename($_FILES['kulldosyasi']['name']);
echo '<pre>';
if (move_uploaded_file($_FILES['kulldosyasi']['tmp_name'], $yuklenecek_dosya))
{
echo "Dosya geçerli ve başarıyla yüklendi.\n";
} else {
echo "Olası dosya yükleme saldırısı!\n";
}
echo 'Diğer hata ayıklama bilgileri:';
print_r($_FILES);
print "</pre>";
?>
Yüklenen dosyayı alan PHP betiği yüklenen dosya ile ne yapılacağını belirlemek için gerekli mantığı uygulamalıdır. Örneğin, $_FILES['kullanici_dosyasi']['size'] değişkenini çok küçük ve büyük dosyaları engellemek için kullanabilirsiniz. $_FILES['kullanici_dosyasi']['type'] değişkenini belirli türlere uymayan dosyaları engellemek için kullanabilirsiniz, fakat bunu sadece birincil denetimlerde kullanın, çünkü bu değer tamamen istemci kontrolündedir ve PHP tarafında denetlenmez. PHP 4.2.0'dan itibaren $_FILES['kullanici_dosyasi']['error'] kullanabilir ve mantığınızı hata kodlarına göre planlayabilirsiniz. Her şartta dosyayı ya geçici dizinden silmeli ya da başka bir yere taşımalısınız.
Eğer formunuzda yüklemek için bir dosya seçilmediyse, PHP $_FILES['kullanici_dosyasi']['size'] değerini 0 ve $_FILES['kullanici_dosyasi']['tmp_name'] değerini boş döndürür.
İstemin sonunda dosya başka bir yere taşınmadı veya adı değiştirilmediyse geçici dizinden silinir.
Örnek 3 - Dosya dizisi yükleme
PHP HTML dizisi özelliğini dosyalar için de destekler.
<form action="" method="post" enctype="multipart/form-data"> <p>Resimler: <input type="file" name="resimler[]" /> <input type="file" name="resimler[]" /> <input type="file" name="resimler[]" /> <input type="submit" value="Gönder" /> </p> </form>
<?php
foreach ($_FILES["resimler"]["error"] as $anahtar => $hata) {
if ($hata == UPLOAD_ERR_OK) {
$tmp_name = $_FILES["resimler"]["tmp_name"][$anahtar];
$name = $_FILES["resimler"]["name"][$anahtar];
move_uploaded_file($tmp_name, "data/$name");
}
}
?>
Dosya yükleme ilerleme çubuğu Dosya Yüklemeyi İzleme seçeneği kullanılarak gerçeklenebilir.
"If no file is selected for upload in your form, PHP will return $_FILES['userfile']['size'] as 0, and $_FILES['userfile']['tmp_name'] as none."
Note that the situation above is the same when a file exceeding the MAX_FILE_SIZE hidden field is being uploaded. In this case $_FILES['userfile']['size'] is also set to 0, and $_FILES['userfile']['tmp_name'] is also empty. The difference would only be the error code.
Simply checking for these two conditions and assuming no file upload has been attempted is incorrect.
Instead, check if $_FILES['userfile']['name'] is set or not. If it is, a file upload has at least been attempted (a failed attempt or not). If it is not set, no attempt has been made.
The documentation is a little unclear about the MAX_FILE_SIZE value sent in the form with multiple file input fields. The following is what I have found through testing - hopefully it may clarify it for others.
The MAX_FILE_SIZE is applied to each file (not the total size of all files) and to all file inputs which appear after it. This means that it can be overridden for different file fields. You can also disable it by sending no number, or sending 0 (probably anything that == '0' if you think about it).
Example:
<form enctype="multipart/form-data" action="." method="POST">
<!-- no maximum size for userfile0 -->
<input name="userfile0" type="file" />
<input type="hidden" name="MAX_FILE_SIZE" value="1000" />
<!-- maximum size for userfile1 is 1000 bytes -->
<input name="userfile1" type="file" />
<!-- maximum size for userfile2 is 1000 bytes -->
<input name="userfile2" type="file" />
<input type="hidden" name="MAX_FILE_SIZE" value="2000" />
<!-- maximum size for userfile3 is 2000 bytes -->
<input name="userfile3" type="file" />
<input type="hidden" name="MAX_FILE_SIZE" value="0" />
<!-- no maximum size for userfile4 -->
<input name="userfile4" type="file" />
</form>
If you want to increase the upload size, it could make sense to allow it only to a specified directory and not in the php.ini for the whole domain or server. In my case it worked very well placing that into the .htaccess file like this:
php_value upload_max_filesize 100M
php_value post_max_size 101M
Remember, post_max_size must be bigger than the upload_max_filesize.
$_FILES will be empty if a user attempts to upload a file greater than post_max_size in your php.ini
post_max_size should be >= upload_max_filesize in your php.ini.
Just a little note, when I was trying to get this to work on my webserver I got error telling me the permissions were wrong, I checked and couldn't see anything wrong then I thought to try "./" for my upload directory instead of the full address which was something like "home/username/public_html/uploaddir". This will save it in the same directory as your script for the program above thats something like
<?php
// In PHP versions earlier than 4.1.0, $HTTP_POST_FILES should be used instead
// of $_FILES.
$uploaddir = './';//<----This is all I changed
$uploadfile = $uploaddir . basename($_FILES['userfile']['name']);
echo '<pre>';
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
echo "File is valid, and was successfully uploaded.\n";
} else {
echo "Possible file upload attack!\n";
}
echo 'Here is some more debugging info:';
print_r($_FILES);
print "</pre>";
?>
I know something trivial but when your new to this, those kind of things elude you.
I think the way an array of attachments works is kind of cumbersome. Usually the PHP guys are right on the money, but this is just counter-intuitive. It should have been more like:
Array
(
[0] => Array
(
[name] => facepalm.jpg
[type] => image/jpeg
[tmp_name] => /tmp/phpn3FmFr
[error] => 0
[size] => 15476
)
[1] => Array
(
[name] =>
[type] =>
[tmp_name] =>
[error] => 4
[size] =>
)
)
and not this
Array
(
[name] => Array
(
[0] => facepalm.jpg
[1] =>
)
[type] => Array
(
[0] => image/jpeg
[1] =>
)
[tmp_name] => Array
(
[0] => /tmp/phpn3FmFr
[1] =>
)
[error] => Array
(
[0] => 0
[1] => 4
)
[size] => Array
(
[0] => 15476
[1] => 0
)
)
Anyways, here is a fuller example than the sparce one in the documentation above:
<?php
foreach ($_FILES["attachment"]["error"] as $key => $error)
{
$tmp_name = $_FILES["attachment"]["tmp_name"][$key];
if (!$tmp_name) continue;
$name = basename($_FILES["attachment"]["name"][$key]);
if ($error == UPLOAD_ERR_OK)
{
if ( move_uploaded_file($tmp_name, "/tmp/".$name) )
$uploaded_array[] .= "Uploaded file '".$name."'.<br/>\n";
else
$errormsg .= "Could not move uploaded file '".$tmp_name."' to '".$name."'<br/>\n";
}
else $errormsg .= "Upload error. [".$error."] on file '".$name."'<br/>\n";
}
?>
Also note that since MAX_FILE_SIZE hidden field is supplied by the browser doing the submitting, it is easily overridden from the clients' side. You should always perform your own examination and error checking of the file after it reaches you, instead of relying on information submitted by the client. This includes checks for file size (always check the length of the actual data versus the reported file size) as well as file type (the MIME type submitted by the browser can be inaccurate at best, and intentionally set to an incorrect value at worst).
Note that the MAX_FILE_SIZE hidden field is only used by the PHP script which receives the request, as an instruction to reject files larger than the given bound. This field has no significance for the browser, it does not provide a client-side check of the file-size, and it has nothing to do with web standards or browser features.
