This page will build on the last page and use many techniques from earlier pages. It will be password protected with sessions but instead of a single password, it will have an array of passwords. The same technique used to check the passwords will be used to filter the file types submited. It will use loops both to make the HTML form and process the input. You will be able to upload up to ten files at a time, have the option to rename them and have the option to have overwrite protection. The full script is color highlighted at the bottom of this page as well as a link to a text file that you can upload to your own web site.
Both the list of passwords and the list of allowed files are stored in arrays like so:
<?
$passwords = array( "your_password", "guest_password" );
?>
<?
$allowed = array( "jpeg", "jpg", "gif", "png", "avi" );?>
You can easily search for a value within an array with the conditional in_array(). I used in_array() three times. First to log in:
<?
elseif ( in_array( "$_POST[pass]", $passwords ) )
{
$_SESSION[pass] = "$_POST[pass]";
header("location:$self");
exit;
}
?>
Next, to hide the form to people who are not logged in:
<?
if ( !in_array( "$_SESSION[pass]", $passwords ) )
{
echo "<h2 class=\"out\">Logged out</h2>";
echo "</body></html>";
exit;
}
?>
And finally, to block uploading of file types that are not in the $allowed array.
<?
if ( !in_array( $type, $allowed) )
{
echo "<div class=\"error\">File type ($type) is not allowed</div>";
}
?>
When you process the files, you can use if ( $_FILES[file_name][error] > 0 ) to see if there was an error followed by a
switch statement to tell the user what the error was. If the files passes the error check, you can use the values in the $_FILES array to filter user input. For example, if you only want image files entered into the form above, you can make an array of image MIME types and reject any file that doesn't have a MIME type in that array. For now, though, let's move down to the input form.
The first uploader had only one field to upload a file but this one has the option of having more. The number of fields is set by the variable $number_of_files near the top of the script. Since the number of fields is a variable, you use a loop to crank out how ever many you want.
<?
for ( $x=0; $x<=$number_of_files-1; $x++ )
{
$filenum = str_pad($x, 3, "0", STR_PAD_LEFT );
echo "<tr><td align=\"center\">";
echo "<input type=\"file\" name=\"file_name[$x]\" />";
echo "</td><td align=\"center\">";
echo "<input type=\"text\" name=\"new_name[$x]\" value=\"$filenum\" />";
echo "</td></tr>";
}
?>
As the script loops from $x=0 to $x=$number_of_files, it generates file inputs to upload files and text inputs to name them all with unique names:
<tr><td align="center">
<input type="file" name="file_name[0]" />
</td><td align="center">
<input type="text" name="new_name[0]" value="000" />
</td></tr>
<tr><td align="center">
<input type="file" name="file_name[1]" />
</td><td align="center">
<input type="text" name="new_name[1]" value="001" />
</td></tr>
<tr><td align="center">
<input type="file" name="file_name[3]" />
</td><td align="center">
<input type="text" name="new_name[3]" value="002" />
</td></tr>
Note the format of the input names: new_name[0], new_name[1], new_name[2] ... new_name[9]. That makes the name get submited as arrays: $_POST[file_name] and $_POST[new_name]. Submitting them as arrays lets you process the uploads by looping through the arrays:
<?
for ( $x=0; $x<=$number_of_files-1; $x++ )
{
# do it only if file has original name
# prevents processing when nothing submitted
if ( isset($_FILES[file_name][name][$x]) )
{
# check for upload errors
# check extension
# check size
# process upload
}
}
?>
To get the extensions of the uploaded files to see if they are on the list of allowed file types, I use explode() on the file name with . (period) as a separater. The last member of the resulting array is the extension.
<?
#### if file uploaded, get extension
else {
$original_name = [name][$x];
$original_name = trim($original_name);
$type = explode(".", $original_name);
$count = count($type);
$last = $count-1;
$type = "$type[$last]";
$type = strtolower($type);
# test extension type
if ( !in_array( $type, $allowed) )
{
echo "<div class=\"error\">File type ($type) is not allowed</div>";
}
?>
If the user has not submited a new name, the original name is used. If the user has submited a new name, spaces and illegal characters are removed the same way they were in the last lession. To prevent the user from changing the file type when changing the name, the extention that we got from the original file is appended to the name. If you didn't do that, the user could enter a text file of PHP code, rename it something.php and hack your website.
If $overwrite (at the top of the script) is "no", the script checks to see if a file with the same name already exists and aborts the file move if one does. Otherwise, the file is moved from the tmp directory to your upload directory. If the move fails, the PHP error message is supressed with the suppression operator (@) and your own error message is displayed.
<?
/*
######################################
# $passwords is an array of usable passwords.
# Make one password for yourself, make others for
# trusted relatives to upload photos directly to your site
# set $path to your uploads directory.
# upload directory must have 777 permissions.
# $number_of_files = number of upload inputs.
# $max_size = max file size in bytes
# $allowed is an array of allowed file extensions.
# do not allow scripts like .php, .pl or .cgi to be uploaded
# if $overwrite = "no" then overwriting blocked
######################################
*/
$passwords = array( "your_password", "guest_password" );
$path = "uploads/";
$number_of_files = 10;
$max_size = 30000000;
$allowed = array( "jpeg", "jpg", "gif", "png", "avi" );
$overwrite = "no";
$body_bg = "fad888";
$table_bg = "slategray";
$th = "black";
$title = "DJ Mike's Multi File Uploader";
$self = "$_SERVER[PHP_SELF]";
######################################
session_start();
############## log out ###############
if ( $_POST[logout] )
{
$_SESSION[pass] = "";
$_SESSION = "";
session_destroy();
header("location:$self");
exit;
}
#####################################
############### or log in ##############
elseif ( in_array( "$_POST[pass]", $passwords ) )
{
$_SESSION[pass] = "$_POST[pass]";
header("location:$self");
exit;
}
#####################################
?>
<html>
<head>
<title><? echo "$title"; ?></title>
<style>
body {background-color:#<? echo "$body_bg"; ?>}
h1, h2 { color:blue; text-align:center; }
h2.in { color:green; text-align:center; }
h2.out { color:red; text-align:center; }
.error { color:red; font-weight:bold; text-align:center; }
.ok { color:green }
th { color:<? echo "$th"; ?>}
</style>
</head>
<body bgcolor="#<? echo "$body_bg"; ?>">
<h1><? echo "$title"; ?></h1>
<center>
<form method="post">
<input type="password" name="pass" value="<? echo "$_SESSION[pass]"; ?>" />
<input type="submit" name="login" value="Log In" />
<input type="submit" name="logout" value="Log Out" />
</form>
</center>
<?
#### hide upload form if not logged in
if ( !in_array( "$_SESSION[pass]", $passwords ) )
{
echo "<h2 class=\"out\">Logged out</h2>";
echo "</body></html>";
exit;
}
else
{
echo "<h2 class=\"in\">Logged In</h2>";
}
?>
<hr><hr>
<center>
<a href="<? echo $path; ?>">Upload directory</a>
</center>
<?
#### start upload ####
## do it only if files submitted
if ( $_FILES )
{
# start loop
echo "<h2>Attempting Upload...</h2>";
for ( $x=0; $x<=$number_of_files-1; $x++ )
{
# do it only if file has original name
# prevents processing when nothing submitted
if ( isset($_FILES[file_name][name][$x]) )
{
# check for upload problems
####
if ( $_FILES[file_name][error][$x] > 0 )
{
echo "<span class=\"error\">
The file could not be upoaded because ";
switch ( $_FILES[file_name][error][$x] )
{
case 1:
echo "the file is too big.";
break;
case 2:
echo "the file is too big.";
break;
case 3:
echo "the file was only partially uploaded.";
break;
case 4:
echo "no file was uploaded.";
break;
case 6:
echo "no temporary folder was available.";
break;
case 7:
echo "unable to write to disk.";
break;
case 8:
echo "file upload stopped";
break;
default:
echo "a system error occured.";
} # end of switch
echo "</span><br />";
exit;
}
#### end of if files > 0
#### if file uploaded, get extension
else {
$original_name = $_FILES[file_name][name][$x];
$original_name = trim($original_name);
$type = explode(".", $original_name);
$count = count($type);
$last = $count-1;
$type = "$type[$last]";
$type = strtolower($type);
# test extension type
if ( !in_array( $type, $allowed) )
{
echo "<div class=\"error\">File type ($type) is not allowed</div>";
}
# then see if it is small enough
elseif ( $_FILES[file_name][size][$x] > $max_size )
{
echo "<div class=\"error\">File is too big</div>";
}
# if no errors and small enough, sanititize name
else
{
# if no new name use original name
if ( $_POST[new_name][$x] == "" )
{
# snip extension
$original_name = str_replace( ".$type", "", $original_name);
# sanitize original name
$original_name = preg_replace("@[^\w\.]@", "_", $original_name);
# add extension and directory path to clean name
$file_name = "$path$original_name.$type";
}
# if new name submited, use it
else
{
# sanitize new name
$newname = $_POST[new_name][$x];
$newname = trim($newname);
$newname = preg_replace("@[^\w\.]@", "_", $newname);
# add extension and directory path to clean name
$file_name = "$path$newname.$type";
}
# prevent overwriting if $overwrite is "no"
if ( $overwrite == "no" && file_exists($file_name) )
{
echo "<span class=\"error\">File $file_name already exists.</span><br />";
}
# move uploaded file to upload directory
# suppress PHP error message
elseif ( @move_uploaded_file($_FILES[file_name][tmp_name][$x], $file_name) )
{
echo "<span class=\"ok\">File uploaded to <a href=\"$file_name\">$file_name</a>.</span><br />";
}
# if move fails, give your own error message.
else
{
echo "<span class=\"error\">An error occured. File Not uploaded</span><br />";
}
}
echo "<br><br>";
}
} # end isset file name
}
echo "</center></body></html>";
exit;
# end upload
}
?>
<center>
<form enctype="multipart/form-data" action="<? echo "$_SERVER[PHP_SELF]"; ?>" method="POST">
<input type="hidden" name="MAX_FILE_SIZE" value="<? echo "$max_size"; ?>" />
<table bgcolor="<? echo "$table_bg"; ?>" border="1" cellpadding="10">
<tr>
<td colspan="2">
<ul>
<li>Limit <? echo number_format($max_size/1000); ?> KB each.
<li>Renaming is optional.
<li>Leave "New Name" field blank to retain original name.
<li>Do not include extension in new name.
<li>Periods and illegal characters will be replaced with underscores.
<li>Allowed file types: <?
foreach ( $allowed as $key=>$val)
{
echo "$val, ";
}
if ( $overwrite == "no" )
{
echo "<li><span class=\"ok\">Overwrite protection is on.</span>";
}
else
{
echo "<li><span class=\"error\">Overwrite protection is off.</span>";
}
?>
</ul>
</td>
</tr>
<tr>
<th>Files</th>
<th>New Name</th>
</tr>
<?
for ( $x=0; $x<=$number_of_files-1; $x++ )
{
$filenum = str_pad($x, 3, "0", STR_PAD_LEFT );
echo "<tr><td align=\"center\">";
echo "<input type=\"file\" name=\"file_name[$x]\" />";
echo "</td><td align=\"center\">";
echo "<input type=\"text\" name=\"new_name[$x]\" value=\"$filenum\" />";
echo "</td></tr>";
}
?>
<tr>
<td colspan="2" align="center">
<input type="submit" value="Upload Files" />
</td>
</tr>
</table>
</form>
</center>
</body>
</html>
|
|
|