9.14a. File feltöltése űrlapon keresztül

Default book

A file feltöltése űrlapon keresztül csak POST metódussal történhet. ennek oka az, hogy elvileg tetszőleges méretű fájlt fel lehet tölteni és a böngészők parancssorában - a GET metódus esetén oda kerül minden elküldendő adat - korlátos a méret. Az alábbi egyszerű kódot nézzük a HTML oldalon

<form enctype="multipart/form-data" action="upload.php" method="POST">
    <!-- MAX_FILE_SIZE be lehet állítani egy maximális méretet -->
    <input type="hidden" name="MAX_FILE_SIZE" value="30000" />
    <!-- A feltöltött fájl valtozónevét adhatjuk itt meg, amely a $_FILES tömbben megjelenik.-->
    Feltöltendő fájl: <input name="userfile" type="file" /> <br/>
    <input type="submit" name="upload" value="Feltöltés" />
</form>

A PHP.INI-ben be kell állítani néhány dolgot, hogy a fájlok feltöltése működjön. ( PHP. INI Windowson általában a PHP könyvtárban található)

;Engedélyezzük a feltöltést
file_uploads=on

;A fájl feltöltés ideiglenes könyvtára. Ha nincsen beállítva, akkor az általános temp könyvtár lesz
; upload_tmp_dir =

;A feltölthető maximális fájl méret (Megabájtokban kifejezve)
upload_max_filesize = 16M

;Az egy űrlapon egyszerre feltölthető fájlok maximális száma
max_file_uploads=20

;A POST adatok maximális mérete
post_max_size=20M

;A maximális várakozási idő, ameddig a script futhat (másodpercben kifejezve)
max_input_time=60

;Ez a memória szükséges a script futásához és a feltöltött fájlnak is bele kell férnie
memory_limit=128M

;Mennyi ideig futhat a script
max_execution_time=30

A fenteikhez egy kis magyarázat:

A feltölthető fájl méretét több helyen is lehet korlátozni:

  • Az űrlapon a <input type="files" max-file-size="20000000"> beállítással maximum 20Mb-os fájlt lehet feltölteni. Ezt persze ki lehet játszani, de ez mindegy...
  • A PHP.INI-ben az upoad_max_filesize beállítással lehet korlátozni a fájl méretét
  • A httpd.conf file-ban a LimitRequestBody 2000000 beállítással is lehet korlátozni

A fenti korlátozások közül a legkisebb méret lesz a mérvadó.

Ha több fájlt akarunk feltölteni, akkor az alábbi dolgot kell beállítanunk a HTML kódban és lehet korlátozni a feltöltendő fájlok típusát is.

<!-- Ebben a példában legkevesebb 0 és legfeljebb 4 fájlt lehet egy időben feltölteni -->
<input type="file" name="userfile" multiple min="0" max="4">

<!-- Csak képeket lehet feltölteni! -->
<INPUT type="file" name="userfile" multiple min="0" max="4" max-file-size="16632" total-max-size="52365"
 accept=".jpg, .jpeg, .png">

<!-- MIME típusokkal korlátozunk -->
<INPUT type="file" name="userfile" accept="image/png, image/jpeg, .doc, .docx,application/msword, 
application/vnd.openxmlformats-officedocument.wordprocessingml.document">

Akár a fáfl kiterjesztésével, akár a MIME típusok megadásával lehet korlátozni. A fenti példában kiterjesztéssel és MIME típussal is Írtunk példát.Az MIME a weben nagyjából megfelel a Windowsos kiterjesztéseknek, de nyilvánvalóan nem ugyanaz...

A feltöltött fájlok szerver oldali feldolgozása

A feltöltés során a fájlok véletlenszerűen kiválasztott névvel a beállított vagy a rendszer által megadott /tmp könyvtárba kerülnek és a $_FILES tömb tartalmazni fog minden szükséges adatot a feltöltött fájlokról.

A fájl feltöltés azért kritikus, mert ilyenkor a szerverre lehet feljuttatni különböző, a szoftver írója által nem teljesen kontrollált fájlokat, amelyek egy fajta biztonsági rést jelenthetnek. Az első dolog tehát az, hogy csak bejelentkezett felhasználó megfelelő jogosultságok birtokában tölthet fel fájlokat, amit a szerver oldalon ellenőrizni kell.

<?PHP

session_start();
if( !$_SESSION["login_in"] ){
    die("Nem vagy bejelentkezve);
}

A következő lépés annak ellenőrzése, hogy a megfelelő script töltötte-e fel a fájlt itt igazából csak azt tudjuk ellenőrizni, hogy a megadott gombot nyomta-e meg a felhasználó és a változó is a megfelelő.

if ( !isset($_POST["userfile"])) || !isset($_POST["upload"]) || $_POST["upload" != "upload" ){
   die("Nem a megfelelő űrlapból töltöttük fel a fájlt");
}

Utána ellenőrizni kell a feltöltött fájlok típusait, a méretüket, majd át kell helyezni őket a megfelelő könyvtárba a /temp könyvtárból. Az első példában csak egy file feltöltését ellenőrizzük le.

if( isset($_FILES['image']) ){
      $errors= array();
      $file_name = $_FILES['upload']['name'];
      $file_size = $_FILES['upload']['size'];
      $file_tmp = $_FILES['upload']['tmp_name'];
      $file_type= $_FILES['upload']['type'];

      // ellenőrizzük a file kiterjesztését (típusát)
      $file_ext=strtolower(end(explode('.',$_FILES['image']['name'])));
      
      $extensions= array("jpeg","jpg","png");
      
      if(in_array($file_ext,$extensions)=== false){
         $errors[]="extension not allowed, please choose a JPEG or PNG file.";
      }

     // Ellenőrizzük a file méretét      
      if($file_size > 2097152){
         $errors[]='A file méretének kisebbnek kell lennie 20MB-nál';
      }
      
     //Ha minden rendben volt, akkor átmozgatjuk a fáilt a végleges helyére és a végleges néven!
      if(empty($errors)==true){
         move_uploaded_file($file_tmp,"images/".$file_name);
         echo "Sikeres volt a feltöltés";
      }else{
         print_r($errors);
      }
}

A teljes script nagyjából így néz ki, kicsit átalakítva. Valójában mindegy, hogy a $_SESSION-t hogyan kezeljük, csak ha nincsen bejelentkezve a felhasználó, akkor ne kerülhessen fel fájl a szerverre.

<?PHP
session_start();

$errors= array();
if( !$_SESSION["loogin_in"] ){
   $errors[]= "Nem vagy bejelentkezve";
}

if ( !isset($_POST["userfile"])) || !isset($_POST["upload"]) || $_POST["upload" != "upload" ){
         $errors[]= "Nem a megfelelő űrlapból töltöttük fel a fájlt";
}
if( isset($_FILES['image']) && empty($errors) ){
      $file_name = $_FILES['upload']['name'];
      $file_size = $_FILES['upload']['size'];
      $file_tmp = $_FILES['upload']['tmp_name'];
      $file_type= $_FILES['upload']['type'];

      // ellenőrizzük a file kiterjesztését (típusát)
      $file_ext=strtolower(end(explode('.',$_FILES['image']['name'])));
      
      $extensions= array("jpeg","jpg","png");
      
      if(in_array($file_ext,$extensions)=== false){
         $errors[]="extension not allowed, please choose a JPEG or PNG file.";
      }

     // Ellenőrizzük a file méretét      
      if($file_size > 2097152){
         $errors[]='A file méretének kisebbnek kell lennie 20MB-nál';
      }    
}

//Ha minden rendben volt, akkor átmozgatjuk a fáilt a végleges helyére és a végleges néven!
 if(empty($errors)==true){
       move_uploaded_file($file_tmp,"images/".$file_name);
       echo "Sikeres volt a feltöltés";
 }else{
       print_r($errors);
 }

Ha több fájlt akarunk feltölteni, akkor az alábbi kódot használhatjuk. A HTML űrlap így néz ki:

<form method='post' action='' enctype='multipart/form-data'>
   <input type="file" name="file[]" id="file" multiple>
   <input type='submit' name='submit' value='Upload'>
</form>

A szerver oldali kód így néz ki:

<?php 
if(isset($_POST['submit'])){
   // A fájlok teljes száma
   $countfiles = count($_FILES['file']['name']);

   // Végigmegyünk ciklussal az összes fájlon
   for($i=0;$i<$countfiles;$i++){
      $filename = $_FILES['file']['name'][$i];
 
      // A sikeresen feltöltött sfájlokat átmozgatjuk a végleges helyre
      move_uploaded_file($_FILES['file']['tmp_name'][$i],'upload/'.$filename);
   }
} 
?>

Ez a példa nem ellenőriz semmit, csak a feltöltött fájlokat mozgatja át a végleges helyükre.