Avatar

This function validates files uploaded through a form. There has to be a file named 'info', 'data', and 'thumbnail'. Optional is a file called 'bg'. Each file has predefined max sizes. There should be no two files with the same name, and unknown filenames invalidate the upload.
The code works, but I was wondering if it could be written better. New to PHP.
Also not sure if there's a better way for debug messages.

Thanks!

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
define("MAX_INFO_SIZE",500);
define("MAX_DATA_SIZE",100000);
define("MAX_THUMBNAIL_SIZE",10000);
define("MAX_BG_SIZE",50000);
define("DEBUG",1);

function isUploadValid() {
	$isValid = true;
	$haveInfo = false;
	$haveData = false;
	$haveThumbnail = false;
	$haveBg = false;

	foreach ($_FILES['uploadFile']['name'] as $i => $name) {
		if ($name == "info") {
			if (DEBUG) echo ".validating info file\n";
			if ($haveInfo) { $isValid = false; } else { $haveInfo = true; }
			if (empty($_FILES['uploadFile']['tmp_name'][$i])) $isValid = false;
			if ($_FILES['uploadFile']['size'][$i] > MAX_INFO_SIZE) $isValid = false;
			if ($_FILES['uploadFile']['error'][$i]) $isValid = false;
		} elseif ($name == "data") {
			if (DEBUG) echo ".validating data file\n";
			if ($haveData) { $isValid = false; } else { $haveData = true; }
			if (empty($_FILES['uploadFile']['tmp_name'][$i])) $isValid = false;
			if ($_FILES['uploadFile']['size'][$i] > MAX_DATA_SIZE) $isValid = false;
			if ($_FILES['uploadFile']['error'][$i]) $isValid = false;
		} elseif ($name == "thumbnail") {
			if (DEBUG) echo ".validating thumbnail file\n";
			if ($haveThumbnail) { $isValid = false; } else { $haveThumbnail = true; }
			if (empty($_FILES['uploadFile']['tmp_name'][$i])) $isValid = false;
			if ($_FILES['uploadFile']['size'][$i] > MAX_THUMBNAIL_SIZE) $isValid = false;
			if ($_FILES['uploadFile']['error'][$i]) $isValid = false;
		} elseif ($name == "bg") {
			if (DEBUG) echo ".validating bg file\n";
			if ($haveBg) { $isValid = false; } else { $haveBg = true; }
			if (empty($_FILES['uploadFile']['tmp_name'][$i])) $isValid = false;
			if ($_FILES['uploadFile']['size'][$i] > MAX_BG_SIZE) $isValid = false;
			if ($_FILES['uploadFile']['error'][$i]) $isValid = false;
		} else {
			$isValid = false;		//unknown file
		}
		if (!$isValid) break;
	}

	// must have info, drawing and thumbnail
	if (!$haveInfo) $isValid = false;
	if (!$haveData) $isValid = false;
	if (!$haveThumbnail) $isValid = false;

	return $isValid;
}

Refactorings

No refactoring yet !

5a00a3a98dcf6f9cd717440fd2b606e5

Eineki

October 2, 2008, October 02, 2008 11:03, permalink

1 rating. Login to rate!

Hi, your code was repetitive, I've drawn the changing data into a bidimensional array and refactored the loop.
I tried to render the code straightforward, if you have question I'm here.

For debug I use a firefox extension named firephp (http.//www.firephp.org) maybe it is worth a try (I'm not sure it is suited to your needs)

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
<?
define("DEBUG",1);

function isUploadValid() {
  $file = array(
     'info'=>array('maxSize'=>5000, 'isLoaded'=>false),
     'data'=>array('maxSize'=>100000, 'isLoaded'=>false),
     'thumbnail'=>array('maxSize'=>10000, 'isLoaded'=>false),
     'bg'=>array('maxSize'=>50000, 'isLoaded'=>false)
  );
  $lastFileWasValid = true;

  foreach ($_FILES['uploadFile']['name'] as $i => $name) {
    if ($lastFileWasValid && isset($file[$name]) && !$file[$name]['isLoaded']){
      if (DEBUG) echo "validating $name file\n";
      $file[$name]['isLoaded'] = true;   
      $lastFileWasValid =  !empty($_FILES['uploadFile']['tmp_name'][$i]) 
               && $_FILES['uploadFile']['size'][$i] > $file[$name]['maxSize']
               && $_FILES['uploadFile']['error'][$i];
    } else {
      return false; // unknown or already loaded file (or the previous screened file was flawed)
    }
  }
   
  return   $file['info']['isLoaded'] 
           && $file['data']['isLoaded'] 
           && $file['thumbnail']['isLoaded'];
}
?>
Avatar

lajos

October 3, 2008, October 03, 2008 03:48, permalink

No rating. Login to rate!

Thanks so much for your help. Very elegant solution with the arrays.
Two small tweaks: flipped the greater than sign in the file size check and negate the error check. (Oh, and added one more debug message.)

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
<?php
	
  define("MAX_INFO_SIZE",500);
  define("MAX_DATA_SIZE",100000);
  define("MAX_THUMBNAIL_SIZE",10000);
  define("MAX_BG_SIZE",50000);
  define("DEBUG",1);
    
  function isUploadValid() {
    $file = array(
      'info'=>array('maxSize'=>MAX_INFO_SIZE, 'isLoaded'=>false),
      'data'=>array('maxSize'=>MAX_DATA_SIZE, 'isLoaded'=>false),
      'thumbnail'=>array('maxSize'=>MAX_THUMBNAIL_SIZE, 'isLoaded'=>false),
      'bg'=>array('maxSize'=>MAX_BG_SIZE, 'isLoaded'=>false)
    );
    $lastFileWasValid = true;

    foreach ($_FILES['uploadFile']['name'] as $i => $name) {
      if ($lastFileWasValid && isset($file[$name]) && !$file[$name]['isLoaded']){
        if (DEBUG) echo "validating $name file\n";
        $file[$name]['isLoaded'] = true;
      $lastFileWasValid =  !empty($_FILES['uploadFile']['tmp_name'][$i])
           && $_FILES['uploadFile']['size'][$i] < $file[$name]['maxSize']
           && !$_FILES['uploadFile']['error'][$i];
        if (DEBUG) echo ".isValid ".$name.": ".(int)$lastFileWasValid."\n";
      } else {
        return false; // unknown or already loaded file (or the previous screened file was flawed)
      }
    }

    return   $file['info']['isLoaded']
      && $file['data']['isLoaded']
      && $file['thumbnail']['isLoaded'];
  }
?>
5a00a3a98dcf6f9cd717440fd2b606e5

Eineki

October 3, 2008, October 03, 2008 20:48, permalink

No rating. Login to rate!

Sorry, it was the cut and paste curse :)

Avatar

sdfsd

November 17, 2008, November 17, 2008 08:39, permalink

No rating. Login to rate!

ddffd

Your refactoring





Format Copy from initial code

or Cancel