PHP: bestanden uploaden via uw website

January 25th, 2012

via een HTML formulier

Met enige regelmaat krijgt onze klantenservice een vraag over het uploaden van bestanden via PHP, hoe dit moet. Hierom hebben wij een voorbeeld ter illustratie gemaakt. In de broncode kunnen fouten aanwezig zijn.

Let op: dit eenvoudige voorbeeld doet niets aan beveiliging (c.q een controle op het geüploade bestand).

Belangrijk:

  • de map waarin bestanden geüpload moeten worden, moet schrijfrechten hebben. U kunt dit instellen via ons klantenportaal MyVEVIDA
  • zonder een adequate loginbeveiliging kunnen derden bestanden uploaden naar uw website en misbruiken
  • bestanden moeten daarom niet gecontroleerd worden op extensie (.doc, .gif, .jpg), maar op het MIME type)
  • zie voor dit laatste het geavanceerdere script onderaan

Ons advies is om niet zomaar een willekeurig script te gaan gebruiken. Lees dit alles aandachtig door en als u vragen heeft over de werking of functionaliteit, neem gerust contact op met onze klantenservice. Dit kan via ons klantenportaal MyVEVIDA. Ieder script heeft weer eigen aanpassingen nodig.

Minimaal upload.php script

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
<?php
// Leeg laten, variabele initialisatie.
// http://www.testingcode.org/blog/2010/08/php-variabelen-vooraf-declareren/
$uploadDir = ''; $filename = '';
 
// Let er op dat er een "trailing slash" '/' achter het PATH geplaatst wordt.
// de upload-map moet schrijfrechten hebben
$uploadDir = 'D:/www/FTP-inlognaam/www/upload/';
 
// Geef de naam in dat gebruikt wordt in het HTML-formulier invoerveld.
$filename = 'userfile';
?>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>PHP File-Upload</title>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
</head>
<body>
 
<?php
/**
 * Controle of het formulier verzonden is
 */
if (isset($_POST['set']))
{
  if (move_uploaded_file($_FILES[$filename]['tmp_name'], $uploadDir . 
    $_FILES[$filename]['name']) == FALSE)
  {
    /*
	 * Whoops, we've caught an upload error...
	 */
	echo "Error number: ".$_FILES[$filename]["error"];
	die();
  }
  else
  {
    // Geef een bevestiging aan de gebruiker
    print "<p>Bestand is goed bevonden en is succesvol geupload.
      Bestandsnaam is: " .$_FILES[$filename]['name'] . "<br />
      Klik <a href=\"" .htmlentities($_SERVER['PHP_SELF']) ."\">hier</a> om 
	  nog een bestand te uploaden.</p>
    ";
 
	// voorkom dubbele POSTs
	unset($_POST['set']);
  }
}
else
{
  // formulier was niet gesubmit, geef het formulier weer
  ?>
<p>
  <form enctype="multipart/form-data" method="post" action="
    <?php echo htmlentities($_SERVER['PHP_SELF']);?>" id="upload">
    <!-- De MAX_FILE_SIZE is een advies aan de browser, geen harde limiet -->
    <input type="hidden" name="MAX_FILE_SIZE" value="2000000" />
    Upload dit bestand: <input name="userfile" type="file" /><br />
    <input type="submit" name="set" value="Upload bestand" />
  </form>
</p>
 
<p>U kunt een bestand tot 10 MB uploaden.</p>
 
  <?php
  }  // einde else-lus
  ?>
 
</body>
</html>

Sla bovenstaande code op in een bestand genaamd “upload.php” en plaats het op uw website. In dit script moet in ieder geval

$uploadDir = 'D:/www/FTP-inlognaam/www/upload/';

gewijzigd worden met het volledige pad naar waar de bestanden geplaatst moeten worden.

Uitgebreider script

Een uitgebreider script voert enkele controles uit, bijvoorbeeld op het MIME type van het bestand. Dit is belangrijk zodat een kwaadwillende het script niet kan misbruiken om ander soortige scripts te uploaden. Dit uitgebreider script bestaat uit twee delen:

  • upload.php

  • upload.functions.php (wordt automatisch opgenomen in upload.php)

Het geheel van de twee scripts gaat er van uit dat:

  • alleen bepaalde documenten of afbeeldingen geüpload kunnen worden. De MIME types zijn uitbreidbaar, hieronder wordt alleen gecontroleerd op:

    • “image/png” (.png-extensie)
    • “image/jpeg” (.jpg/jpeg-extensie)
    • “image/gif” (.gif-extensie)
    • “image/psd” (.psd-extensie)
    • “image/bmp” (.bmp-extensie)
    • “application/vnd.openxmlformats-officedocument.wordprocessingml.document” (.docx-extensie)
    • “application/vnd.ms-excel” (.xls-extensie)
    • “application/vnd.openxmlformats-officedocument.spreadsheetml.sheet” (.xlsx-extensie)
    • “application/vnd.ms-powerpoint” (.pst-extensie)
    • “application/vnd.openxmlformats-officedocument.presentationml.presentation” (.pstx-extensie)
    • “application/pdf” (.pdf-extensie)

upload.functions.php

Sla onderstaande code op in een bestand genaamd upload.functions.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
<?php
/*
 * ondersteunende functies
 */
function check_upload_tmp_dir()
{
  if(is_writable(ini_get('upload_tmp_dir'))
  {
    return TRUE;
  }
  else
  {
    return FALSE;
  }
}
 
function check_upload_folder($folder)
{
  if(is_dir($folder) && is_writable($folder))
  {
    return TRUE;
  }
  else
  {
    return FALSE;
  }
}
 
function check_image_mime($tmpname)
{
  $imageInfo = getimagesize($tmpname);
  if ($imageInfo['mime'] == ("image/png") ||
    $imageInfo['mime'] == ("image/jpeg") ||
	$imageInfo['mime'] == ("image/gif") ||
	$imageInfo['mime'] == ("image/psd") ||
	$imageInfo['mime'] == ("image/bmp"))
  {
    return TRUE;
  }
  else
  {
    return FALSE;
  }
}
 
function check_doc_mime($tmpname)
{
  // MIME types:
  // http://filext.com/faq/office_mime_types.php
  $finfo = finfo_open(FILEINFO_MIME_TYPE);
  $mtype = finfo_file($finfo, $tmpname);
  if($mtype == ("application/vnd.openxmlformats-officedocument.wordprocessingml.document") || 
    $mtype == ("application/vnd.ms-excel") ||
    $mtype == ("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") ||
    $mtype == ("application/vnd.ms-powerpoint") ||
    $mtype == ("application/vnd.openxmlformats-officedocument.presentationml.presentation") ||
    $mtype == ("application/pdf"))
  {
    finfo_close($finfo);
    return TRUE;
  }
  else
  {
    finfo_close($finfo);
    return FALSE;
  }
}
?>

Dit bovenstaande bestand moet in dezelfde map geplaatst worden als het hieronderstaande upload.php bestand.

upload.php

Het eerdere upload.php bestand is aangepast, zodat van bovenstaande functies gebruik wordt gemaakt.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
<?php
// onderstaande require is niet verplicht, maar wel
// nodig voor ondersteunende functies.
require_once('upload.functions.php');
 
// Leeg laten, variabele initialisatie.
$uploadDir = ''; $filename = '';
 
// Let er op dat er een "trailing slash" '/' achter het PATH geplaatst wordt.
// de upload-map moet schrijfrechten hebben
$uploadDir = 'D:/www/FTP-inlognaam/www/upload/';
 
// Geef de naam in dat gebruikt wordt in het HTML-formulier invoerveld.
$filename = 'userfile';
 
?>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>PHP File-Upload</title>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
</head>
<body>
 
<?php
/**
 * Check if form is submitted.
 */
if (isset($_POST['set']))
{
  if(function_exists("check_image_mime") && function_exists("check_doc_mime"))
  {
    if((check_image_mime($_FILES[$filename]['tmp_name']) == FALSE) &&
      (check_doc_mime($_FILES[$filename]['tmp_name']) == FALSE))
	{
	  // FOUTIEF bestand (geen MIME-type van een afbeelding of document) 
	  // is geupload. Stop hier, of doe wat aan foutafhandeling.
	  echo "foutief bestand!"; die();
	}
	else
	{
	  if(function_exists("check_upload_tmp_dir") &&
        function_exists("check_upload_folder"))
	  {
	    if(check_upload_folder($uploadDir))
		{
		  if(move_uploaded_file($_FILES[$filename]['tmp_name'], $uploadDir .
            $_FILES[$filename]['name']) == FALSE)
		  {
		/*
	         * Whoops, we've caught an upload error...
	         */
	        echo "Fout tijdens verplaatsen bestand. Foutnummer: "
		  .$_FILES[$filename]["error"];
		echo "Ga terug met de browser.";
		die();
          }
          else
          {
            // Geef een bevestiging aan de gebruiker
            print "
              <p>
		Bestand is goed bevonden en is succesvol geupload.
                Bestandsnaam is: " .$_FILES[$filename]['name'] . "<br />
                Klik <a href=\"upload.php\">hier</a> om nog een bestand te 
		uploaden.
              </p>
            ";
          }
        }
      }
    }
  }
unset($_POST['set']);
}
 
else
{
  // formulier was niet gesubmit, geef het formulier weer
  ?>
 
<p>
  <form enctype="multipart/form-data" method="post" action="
    <?php echo $_SERVER['PHP_SELF'];?>" id="upload">
    <!-- De MAX_FILE_SIZE is een advies aan de browser, geen harde limiet -->
    <input type="hidden" name="MAX_FILE_SIZE" value="2000000" />
    Upload dit bestand: <input name="userfile" type="file" /><br />
    <input type="submit" name="set" value="Upload bestand" />
  </form>
</p>
 
<p>U kunt een bestand tot 10 MB uploaden.</p>
 
  <?php
  }  // einde else-lus
  ?>
 
</body>
</html>

 

Hebt u vragen hierover? Neemt u dan contact op met onze klantenservice. Deze is telefonisch bereikbaar via 050-5492234 (Nederland) of 09-2185919 (België). U kunt ook een vraag stellen via het scherm “Mijn vragen” in MyVEVIDA.

Aantal keren bekeken: 322 views

Comments are closed.