1
0
mirror of https://github.com/php/doc-tr.git synced 2026-03-23 23:02:09 +01:00
Files
archived-doc-tr/features/file-upload.xml
Nilgün Belma Bugüner c2b5601293 some corrections
2025-09-02 11:17:47 +03:00

547 lines
20 KiB
XML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?xml version="1.0" encoding="utf-8"?>
<!-- EN-Revision: 04d9aded7bbd447523cf038ddf88e6d7f7e43c53 Maintainer: nilgun Status: ready -->
<!-- CREDITS: mesut, yasar -->
<chapter xml:id="features.file-upload" xmlns="http://docbook.org/ns/docbook">
<title>Karşıya dosya yükleme</title>
<sect1 xml:id="features.file-upload.post-method">
<title>POST yöntemi ile karşıya dosya yükleme</title>
<simpara>
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.
</simpara>
<simpara>
PHP, herhangi bir RFC 1867 uyumlu tarayıcıdan gelen dosya yüklemelerini
alabilir.
</simpara>
<note>
<title>İlgili Yapılandırmalar</title>
<para>
Ayrıca &php.ini; içindeki
<link linkend="ini.file-uploads">file_uploads</link>,
<link linkend="ini.upload-max-filesize">upload_max_filesize</link>,
<link linkend="ini.upload-tmp-dir">upload_tmp_dir</link>,
<link linkend="ini.post-max-size">post_max_size</link> ve
<link linkend="ini.max-input-time">max_input_time</link> yönergelerine
bakınız.
</para>
</note>
<para>
PHP ayrıca <productname>Netscape Composer</productname> ve W3C'nin
<productname>Amaya</productname> istemcileri tarafından kullanılan
PUT yöntemiyle dosya yüklemeleri de destekler. Ayrıntılı bilgi için
<link linkend="features.file-upload.put-method">PUT Yöntemi
Desteği</link>'ne bakınız.
</para>
<para>
<example>
<title>- Karşıya Dosya Yükleme Formu</title>
<para>
Bir dosya yükleme ekranı aşağıdaki gibi özel bir form ile
oluşturulabilir:
</para>
<programlisting role="html">
<![CDATA[
<!-- 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>
]]>
</programlisting>
<para>
Yukarıdaki örnekteki <literal>__URL__</literal> bir PHP dosyası ile
değiştirilmelidir.
</para>
<para>
<literal>MAX_FILE_SIZE</literal> 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.
</para>
</example>
</para>
<note>
<para>
Dosya yükleme formunuzun <literal>enctype="multipart/form-data"</literal>
özniteliğine sahip olduğundan emin olun, aksi takdirde dosya yükleme
çalışmaz.
</para>
</note>
<para>
Küresel <varname>$_FILES</varname> karşıdan yüklenen tüm dosyaların
bilgisini içerir. Örnek formdaki <varname>$_FILES</varname> içeriği aşağıda
verilmiştir. Yukarıdaki örneğe göre yüklenen dosya adı
<emphasis>kullanici_dosyasi</emphasis>'dır. Bu herhangi bir isim olabilir.
<variablelist>
<varlistentry>
<term><varname>$_FILES['kullanici_dosyasi']['name']</varname></term>
<listitem>
<para>
İstemci makinasındaki asıl dosya adıdır.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>$_FILES['kullanici_dosyasi']['type']</varname></term>
<listitem>
<para>
Eğer tarayıcı bu bilgiyi sağladıysa dosyanın MIME türüdür.
Örneğin, <literal>"image/gif"</literal>. Bu MIME türü PHP tarafında
denetlenmez; bu bakımdan bu değeri dikkate almayın.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>$_FILES['kullanici_dosyasi']['size']</varname></term>
<listitem>
<para>
Yüklenen dosyanın bayt cinsinden boyutudur.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>$_FILES['kullanici_dosyasi']['tmp_name']</varname></term>
<listitem>
<para>
Yüklenen dosyanın sunucuda saklandığı sıradaki geçici dosya adıdır.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>$_FILES['kullanici_dosyasi']['error']</varname></term>
<listitem>
<para>
Bu dosya yüklemesiyle ilişkili
<link linkend="features.file-upload.errors">hata kodu</link>dur.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>$_FILES['kullanici_dosyasi']['full_path']</varname></term>
<listitem>
<para>
Tam dosya yolu (full_path) tarayıcı tarafından gönderilir. Bu yol
her zaman gerçek dizin yapısını içermediğinden güvenilmemelidir.
PHP 8.1.0 ve sonrasında kullanılabilir.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
<para>
&php.ini; içindeki
<link linkend="ini.upload-tmp-dir">upload_tmp_dir</link> 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 <envar>TMPDIR</envar> ortam değişkenine
başka bir değer vererek değiştirilebilir. Buna PHP betiği içinden
<function>putenv</function> 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.
<example>
<title>- Dosya yüklemelerinin doğrulanması</title>
<para>
Daha fazla bilgi için <function>is_uploaded_file</function> ve
<function>move_uploaded_file</function> işlev girdilerine de bakınız.
Aşağıdaki örnek bir formdan gelen dosya yükleme isteğini işleyecektir.
</para>
<programlisting role="php">
<![CDATA[
<?php
$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>";
?>
]]>
</programlisting>
</example>
</para>
<simpara>
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,
<varname>$_FILES['kullanici_dosyasi']['size']</varname> değişkenini çok
küçük ve büyük dosyaları engellemek için kullanabilirsiniz.
<varname>$_FILES['kullanici_dosyasi']['type']</varname> 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. Ayrıca <varname>$_FILES['kullanici_dosyasi']['error']</varname>
kullanabileceği gibi mantığınızı da
<link linkend="features.file-upload.errors">hata kodları</link>na göre
planlayabilirsiniz. Her şartta dosyayı ya geçici dizinden silmeli ya da
başka bir yere taşımalısınız.
</simpara>
<simpara>
Eğer formunuzda yüklemek için bir dosya seçilmediyse, PHP
<varname>$_FILES['kullanici_dosyasi']['size']</varname> değerini 0 ve
<varname>$_FILES['kullanici_dosyasi']['tmp_name']</varname> değerini boş
döndürür.
</simpara>
<simpara>
İstemin sonunda dosya başka bir yere taşınmadı veya adı değiştirilmediyse
geçici dizinden silinir.
</simpara>
<example>
<title>- Dosya dizisi yükleme</title>
<para>
PHP <link linkend="faq.html.arrays">HTML dizisi özelliği</link>ni
dosyalar için de destekler.
</para>
<programlisting role="html">
<![CDATA[
<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>
]]>
</programlisting>
<programlisting role="php">
<![CDATA[
<?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];
// basename() dosya sisteminin geçiş saldırılarını engelleyebilir;
// dosya adının daha fazla doğrulanması/temizliği uygun olabilir
$name = basename($_FILES["resimler"]["name"][$anahtar]);
move_uploaded_file($tmp_name, "data/$name");
}
}
?>
]]>
</programlisting>
</example>
<para>
Dosya yükleme ilerleme çubuğu
<link linkend="session.upload-progress">Dosya Yüklemeyi İzleme</link>
seçeneği kullanılarak gerçeklenebilir.
</para>
</sect1>
<sect1 xml:id="features.file-upload.errors">
<title>Hata İletilerinin Açıklamaları</title>
<simpara>
PHP, dosya dizisi ile birlikte uygun bir hata kodu
döndürür. Hata kodu PHP tarafından dosya yüklenirken oluşturulan dosya
dizisinin <literal>error</literal> bölümünde bulunur. Diğer bir deyişle,
hata <varname>$_FILES['kullanici_dosyasi']['error']</varname> içinde
olabilir.
</simpara>
<simpara>
Bu hata kodunun değeri
<constant>UPLOAD_ERR_<replaceable>*</replaceable></constant>
sabitlerinden biridir.
</simpara>
</sect1>
<sect1 xml:id="features.file-upload.common-pitfalls">
<title>Bilinen zorluklar</title>
<simpara>
<literal>MAX_FILE_SIZE</literal> dosya boyutu &php.ini; dosyasında
<link linkend="ini.upload-max-filesize">upload_max_filesize</link>
yönergesinde belirtilenden büyük olamaz. Öntanımlı değeri 2 Megabayt'tır.
</simpara>
<simpara>
Eğer bir bellek sınırı etkinleştirildiyse, daha büyük bir
<link linkend="ini.memory-limit">memory_limit</link> gerekebilir.
<link linkend="ini.memory-limit">memory_limit</link> değerinin yeterli
olduğundan emin olun.
</simpara>
<simpara>
Eğer <link linkend="ini.max-execution-time">max_execution_time</link> çok
küçük verildiyse, betiğin çalışma süresi bu süreyi aşabilir.
<literal>max_execution_time</literal> değerinin yeterli olduğundan emin
olun.
</simpara>
<note>
<simpara>
<link linkend="ini.max-execution-time">max_execution_time</link> sadece
betiğin kendi çalışma süresini etkiler. Sistem çağrıları
<function>system</function>, <function>sleep</function> işlevleri,
veritabanı sorguları, dosya yükleme işlemi gibi betiğin işletimi dışında
yaşanan etkinliklerde harcanan zaman betiğin azami çalışma süresinin
belirlenmesinde hesaba katılmaz.
</simpara>
</note>
<warning>
<simpara>
<link linkend="ini.max-input-time">max_input_time</link> betiğin girdi
almak için harcayacağı azami süreyi saniye cinsinden belirler, buna dosya
yüklemeleri de dahildir. Büyük veya çoklu dosyalar için veya yavaş
bağlantılı kullanıcılar için <literal>60</literal> saniyelik öntanımlı
değer aşılabilir.
</simpara>
</warning>
<simpara>
Eğer <link linkend="ini.post-max-size">post_max_size</link> çok küçük
verildiyse, büyük dosyalar yüklenemez. <literal>post_max_size</literal>
değerinin yeterli olduğundan emin olun.
</simpara>
<simpara>
<link linkend="ini.max-file-uploads">max_file_uploads</link> yapılandırma
seçeneği bir istekte yüklenebilecek azami dosya sayısını belirtmek için
kullanılabilmektedir. Bu sayıdan fazla dosya yüklenmek istendiğinde
<varname>$_FILES</varname> bu sayıya ulaşıldığında dosya yüklemeyi
durduracaktır. Örneğin, <link
linkend="ini.max-file-uploads">max_file_uploads</link> için 10
belirtilmişse <varname>$_FILES</varname> asla 10 üyeden fazlasını
içermeyecektir.
</simpara>
<simpara>
Üzerinde çalıştığınız dosyanın doğrulanmaması kullanıcıların diğer
dizinlerde bulunan hassas bilgilere erişebileceği anlamına gelebilir.
</simpara>
<simpara>
Bir çok dizin listeleme şeklinin olmasından dolayı özgün isimlerin
(örneğin boşluk içerenler) uygun şekilde işlenebileceğinin garantisi
yoktur.
</simpara>
<simpara>
Normal girdi alanlarıyla dosya yükleme alanları karıştırılıp aynı form
değişkeninde (örneğin <literal>foo[]</literal> gibi) kullanılamaz.
</simpara>
</sect1>
<sect1 xml:id="features.file-upload.multiple">
<title>Çoklu dosya yükleme</title>
<simpara>
<literal>input</literal>lar için farklı <literal>name</literal> değerleri
kullanarak çoklu dosya gönderilebilir.
</simpara>
<simpara>
Ayrıca bilgilerin otomatik olarak dizilerde düzenlendiği bir eşzamanlı
dosya gönderimi de mümkündür. Bunun için, HTML formunda birden fazla input
için aynı dizi söz dizimini kullanmalısınız:
</simpara>
<para>
<example>
<title>- Çoklu dosya yükleme</title>
<programlisting role="html">
<![CDATA[
<form action="dosya-yukle.php" method="post" enctype="multipart/form-data">
Bu dosyaları gönder:<br />
<input name="kullanici_dosyasi[]" type="file" /><br />
<input name="kullanici_dosyasi[]" type="file" /><br />
<input type="submit" value="Dosyaları gönder" />
</form>
]]>
</programlisting>
</example>
</para>
<simpara>
Yukarıdaki form gönderildiğinde,
<varname>$_FILES['kullanici_dosyasi']</varname>,
<varname>$_FILES['kullanici_dosyasi']['name']</varname> ve
<varname>$_FILES['kullanici_dosyasi']['size']</varname> dizileri
ilklendirilir.
</simpara>
<simpara>
Örneğin, gönderilen dosya isimleri
<filename>/home/test/review.html</filename> ve
<filename>/home/test/xwp.out</filename> olsun. Bu durumda,
<varname>$_FILES['kullanici_dosyasi']['name'][0]</varname>
<filename>review.html</filename> değerini içerir ve
<varname>$_FILES['kullanici_dosyasi']['name'][1]</varname>
<filename>xwp.out</filename> değerini içerir.
Benzer şekilde,
<varname>$_FILES['kullanici_dosyasi']['size'][0]</varname>
<filename>review.html</filename>'in dosya boyutunu içerir ve böyle devam
eder.
</simpara>
<simpara>
<varname>$_FILES['kullanici_dosyasi']['name'][0]</varname>,
<varname>$_FILES['kullanici_dosyasi']['tmp_name'][0]</varname>,
<varname>$_FILES['kullanici_dosyasi']['size'][0]</varname> ve
<varname>$_FILES['kullanici_dosyasi']['type'][0]</varname>'a da ayrıca
değerleri atanır.
</simpara>
<warning>
<simpara>
<link linkend="ini.max-file-uploads">max_file_uploads</link> yapılandırma
seçeneği bir istekte yüklenebilecek azami dosya sayısını belirtmek için
kullanılabilmektedir. Formunuzun bir istekte bu sayıdan fazla dosya
yüklemeye çalışmamasını sağlamalısınız.
</simpara>
</warning>
<para>
<example>
<title>- Dizinin tamamen karşıya yüklenmesi</title>
<simpara>
HTML dosya karşıya yükleme alanlarında,
<literal>webkitdirectory</literal> özniteliği ile bir dizinin tamamı
karşıya yüklenebilir. Bu özellik günümüz tarayıcılarının çoğu
tarafından desteklenmektedir.
</simpara>
<simpara>
<literal>full_path</literal> bilgisi ile göreli dosya yolunu
saklamak ve sunucuda aynı dizini oluşturmak mümkündür.
</simpara>
<programlisting role="html">
<![CDATA[
<form action="file-upload.php" method="post" enctype="multipart/form-data">
Bu dizini gönder:<br />
<input name="userfile[]" type="file" webkitdirectory multiple />
<input type="submit" value="Dosyaları gönder" />
</form>
]]>
</programlisting>
</example>
<warning>
<simpara>
<literal>webkitdirectory</literal> özniteliği standart değildir ve
standartlaşma sürecinde değildir. İnternete açık üretim sitelerinde
kullanılmamalıdır: her kullanıcı için çalışmayacaktır. Ayrıca
uygulamalar arasında büyük uyumsuzluklar olabilir ve davranış gelecekte
değişebilir.
</simpara>
<simpara>
PHP sadece tarayıcının gönderdiği göreli dizin yapısını çözümler ve bu
bilgiyi <varname>$_FILES</varname> dizisinde aktarır.
<literal>full_path</literal> dizisindeki değerlerin gerçek dizin
yapısını içermesinin bir garantisi yoktur ve PHP uygulamalarında bu
bilgiye güvenilmemelidir.
</simpara>
</warning>
</para>
</sect1>
<sect1 xml:id="features.file-upload.put-method">
<title>PUT yöntemi desteği</title>
<para>
PHP bazı istemciler tarafından sunucuda dosya saklamak için kullanılan
HTTP PUT yöntemini de destekler. PUT istemleri POST istemleri ile dosya
yüklemesinden daha basittir ve şu şekildedir:
<informalexample>
<programlisting role="HTTP">
<![CDATA[
PUT /dizin_adi/dosyaismi.html HTTP/1.1
]]>
</programlisting>
</informalexample>
</para>
<para>
Bu normalde uzak istemci <filename>/dizin_adi/dosyaismi.html</filename>
içeriğini site ağacında saklamak istiyor anlamına gelir. Bu Apache veya
PHP'nin herkese site ağacındaki herhangi bir dosya üzerine yazma yetkisi
verme anlamına geleceği için iyi bir fikir değildir. Bu nedenle böyle bir
istem geldiğinde öncelikle HTTP sunucunuza bu istemin belirli bir PHP
betiği tarafından karşılanacağını söylemelisiniz. Apache'de bunu
<emphasis>Script</emphasis> yönergesi ile yapabilirsiniz. Bu Apache
yapılandırma dosyasının herhangi bir yerine konulabilir. Genellikle
<literal>&lt;Directory&gt;</literal> bloğu içine veya
<literal>&lt;VirtualHost&gt;</literal> bloğu içine konulur.
Bu, aşağıdaki gibi bir satır olabilir:
<informalexample>
<programlisting>
<![CDATA[
Script PUT /put.php
]]>
</programlisting>
</informalexample>
</para>
<simpara>
Bu Apache'ye URI'ler için bütün PUT istemlerinin put.php betiğine
gönderilmesini söyler. Tabii ki bu durumda <filename class="extension">.php</filename>
uzantısının ve PHP'nin etkin olduğu varsayılmaktadır. Bu betiğe gelen bütün
PUT istemleri için hedef kaynağı betiğin kendisi olmalıdır.
</simpara>
<simpara>
PHP ile put.php içinde şunu yapabilirsiniz. Bu yüklenen dosyanın içeriğini
sunucudaki <filename>myputfile.ext</filename> dosyasına kopyalar. Bu dosya
kopyalamayı gerçekleştirmeden önce bazı denetimlerin yanında kimlik
doğrulaması da yapmak isteyebilirsiniz.
</simpara>
<para>
<example>
<title>- HTTP PUT dosyalarının kaydedilmesi</title>
<programlisting role="php">
<![CDATA[
<?php
/* PUT verisi stdin akımına gelir */
$putdata = fopen("php://input", "r");
/* Yazmak için bir dosya aç */
$fp = fopen("put_dosyam.ekl", "w");
/* Bir kerede 1 KB veri oku ve dosyaya yaz */
while ($veri = fread($putdata, 1024))
fwrite($fp, $veri);
/* Akımları kapat */
fclose($fp);
fclose($putdata);
?>
]]>
</programlisting>
</example>
</para>
</sect1>
<sect1 xml:id="features.file-upload.errors.seealso">
&reftitle.seealso;
<para>
<simplelist>
<member><link linkend="security.filesystem">Dosya Sistemi
Güvenliği</link></member>
</simplelist>
</para>
</sect1>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->