zip file upload

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
Jim_Bo
Forum Contributor
Posts: 390
Joined: Sat Oct 02, 2004 3:04 pm

zip file upload

Post by Jim_Bo »

Hi,

I am using the following code to upload files limited to zip or rar, upon upload I have it set to rename the uploaded files to the id of the record placed in the database adding the file extension onto that.

Problem is that it leaves the file extension off ie

1
2
etc
etc

no file extension on the uploaded file.

also when it inserts the data (filename) into the database the file extension is marked as ie

1.x-zip-compressed
2.x-zip-compressed

I am wanting to have a page that allows people to download the files using links and need the file extensions to be ie

1.rar
2.zip
etc
etc

depending on the file type uploaded.

code:

Code: Select all

$file_dir  = "files"; 
$counter = 0; 

$allowed_file_types = array( 
'application/x-zip-compressed' => 'x-zip-compressed'); 

$file = $_FILES['file']; 
         
    while($counter <= count($file)) 
{ 
    if($file['size'][$counter] > 0) 
{ 
    if(!array_key_exists($file['type'][$counter], $allowed_file_types)) 
{ 
    echo 'File '.($counter+1).' is not a accepted file type!<br />'; 
}else{ 
        @mysql_query("INSERT INTO filename (filename) VALUES ('0')"); 
        $new_id = mysql_insert_id(); 
        $filetype = $file['type'][$counter]; 
        $extention = $allowed_file_types[$filetype]; 
        $filename = $new_id.".".$extention; 

        @mysql_query("UPDATE filename SET modelid='".$_GET['modelid']."', filename='".$filename."', userid='".$_SESSION['userid']."' WHERE fileid='".$new_id."'"); 

    $newfile = $file_dir.'/'.$filename[$counter]; 
    move_uploaded_file($_FILES['file']['tmp_name'][$counter], $newfile);   


} 
} 
$counter++; 
}

How to solve this?


Thanks
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post by timvw »

You could solve this by trying to understand what you're doing...
What do the following three lines mean?

Code: Select all

$allowed_file_types = array('application/x-zip-compressed' => 'x-zip-compressed'); 

$extention = $allowed_file_types[$filetype];
$filename = $new_id.".".$extention;
(Btw, you're not validating input, not preparing it for use in a mysql query, and you're using $_SESSION but i don't see a call to session_start)
User avatar
ambivalent
Forum Contributor
Posts: 173
Joined: Thu Apr 14, 2005 8:58 pm
Location: Toronto, ON

Post by ambivalent »

I'm not sure what you're trying to do with this but I can't see how it would ever enter the first "if" loop

Code: Select all

if($file['size'][$counter] > 0)
Wouldn't $file['size'][$counter] return a value of NULL?
Jim_Bo
Forum Contributor
Posts: 390
Joined: Sat Oct 02, 2004 3:04 pm

Post by Jim_Bo »

Hi,

You dont see session_start(); as I have only posted the part of the script I am having the issue with.


$allowed_file_types = array('application/x-zip-compressed' => 'x-zip-compressed');

To my knowladge I am stating to only allow application\compressed files to be upload ie 'image/jpeg' => 'jpg', only allowing jpg files to be uploaded.

&

$extention = $allowed_file_types[$filetype];
$filename = $new_id.".".$extention;

$extension grabs the file extension ie .jpg for jpg images, but in the case of zip files $extension seems to hold -> x-zip-compressed and $_FILES['name']; seems to hold the name and extension of zip files.

$filename now grabs the insert id and $extension preparing to store in the database as 1.zip, 2.zip etc etc and rename the file upon upload

Code: Select all

$newfile = $file_dir.'/'.$filename[$counter]; 
	move_uploaded_file($_FILES['file']['tmp_name'][$counter], $newfile);
So I am sure I kno whats going on except that I am lost on 'application/x-zip-compressed' => 'x-zip-compressed'); aposed to application/zip => 'zip'

I kno how this structure works with photos, but cant get it to work for rar and zip files.


Thanks
Last edited by Jim_Bo on Sat May 06, 2006 5:33 pm, edited 2 times in total.
Jim_Bo
Forum Contributor
Posts: 390
Joined: Sat Oct 02, 2004 3:04 pm

Post by Jim_Bo »

It means if no files or non allowed files were uploaded then

echo 'File '.($counter+1).' is not a accepted file type!<br />';

else continue


Thanks
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post by timvw »

Jim_Bo wrote: So I am sure I kno whats going on except that I am lost on 'application/x-zip-compressed' => 'x-zip-compressed'); aposed to application/zip => 'zip'
To me it appears that you already know the answer for your problem? Or i don't understand your problem ;)


(Btw, windows seems to use application/zip as mimetype instead...)
Jim_Bo
Forum Contributor
Posts: 390
Joined: Sat Oct 02, 2004 3:04 pm

Post by Jim_Bo »

Im not sure that I do,

When i use

'application/x-zip-compressed' => 'x-zip-compressed' it writes the file extension as --> .x-zip-compressed

if I use

'application/zip' => 'zip' it wont allow me to upoad acceptable files

I also want to allow .rar and have tried

'application/rar' => 'rar' and still wont allow acceptable files to be uploaded.

I thought I was on the right track but the file extension to be writen into the database with the new file name and changing the file name of the uploaded file seems to be wrong

.x-zip-compressed rather than zip etc


Thanks
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post by timvw »

A little search teaches me that you would have to allow the following mimetypes:

application/zip
application/x-zip
application/x-zip-compressed
application/octet-stream
application/x-compress
application/x-compressed
multipart/x-zip

application/rar
application/x-compressed
application/x-rar
application/x-rar-compressed
application/x-rar-compressed; application/x-compressed
compressed/rar; application/x-rar-compressed

thus the following should work...

Code: Select all

$allowed = new array();
$allowed['application/zip'] => 'zip';
$allowed['application/xzip'] => 'zip';
...
Jim_Bo
Forum Contributor
Posts: 390
Joined: Sat Oct 02, 2004 3:04 pm

Post by Jim_Bo »

Hi,

I tried the following with rar and zip, both ways I get -> is not a accepted file type!

Code: Select all

$allowed_file_types = array(
'application/rar' => 'rar',
'application/xrar' => 'xrar');

Should that work, I tried that before I tried

Code: Select all

$allowed_file_types = array(
'application/x-zip-compressed' => 'x-zip-compressed');
Which allowed zip files to be uploaded.

Not sure where to from here?


Thanks
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post by timvw »

I suggest that you make a very basic script in order you hopefully start understanding what is going on...

Make a script that outputs the mimetype of an uploaded file.
Upload a couple of zip and rar archives.
Write down the mimetypes.
For each mimetype you add an row to your $allowed_filed_types array (thus $mimetype => 'wanted extension').
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post by timvw »

Here is such a sample script...

Code: Select all

<?php
ini_set('error_reporting', E_ALL);
ini_set('display_errors', TRUE);

$allowed = array();
$allowed['application/zip'] = 'zip';
$allowed['application/x-zip'] = 'zip';
$allowed['application/x-zip-compressed'] = 'zip';
$allowed['application/octet-stream'] = 'zip';
$allowed['application/x-compress'] = 'zip';
$allowed['application/x-compressed'] = 'zip';
$allowed['multipart/x-zip'] = 'zip';

$allowed['application/rar'] = 'rar';
$allowed['application/x-rar'] = 'rar';
$allowed['application/x-rar-compressed'] = 'rar';
$allowed['application/x-rar-compressed; application/x-compressed'] = 'rar';
$allowed['compressed/rar; application/x-rar-compressed'] = 'rar';

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
	if (isset($_FILES) && isset($_FILES['thefile'])) {
		echo $_FILES['thefile']['type'] . ' is ';
		if(array_key_exists($_FILES['thefile']['type'], $allowed)) {
			echo 'allowed';
		} else {
			echo 'not allowed';
		}
	}
}
?>
<form action='#' method='post' enctype='multipart/form-data'>
<input type='file' name='thefile'/>
<input type='submit' name='uploadbutton' value='Upload'/>
</form>
Jim_Bo
Forum Contributor
Posts: 390
Joined: Sat Oct 02, 2004 3:04 pm

Post by Jim_Bo »

Hi,

I understand most of that, except when it uploads the file it renames it to

1
2

seems to leave off the file extension, but writes it to the database as

1.zip
2.zip

Code: Select all

$filename = $new_id.".".$extention;

		@mysql_query("UPDATE filename SET modelid='".$_GET['modelid']."', filename='".$filename."', userid='".$_SESSION['userid']."' WHERE fileid='".$new_id."'");

	$newfile = $file_dir.'/'.$filename[$counter]; 
	move_uploaded_file($_FILES['file']['tmp_name'][$counter], $newfile);
Jim_Bo
Forum Contributor
Posts: 390
Joined: Sat Oct 02, 2004 3:04 pm

Post by Jim_Bo »

Hi,

Removing [$counter] from $newfile = $file_dir.'/'.$filename[$counter]; seemed to solve the problem.

Full code:

Code: Select all

<?php  

	$file_dir  = "files";
	$numoffile = 2;
	$counter = 0;

$allowed_file_types = array(); 
$allowed_file_types['application/zip'] = 'zip'; 
$allowed_file_types['application/x-zip'] = 'zip'; 
$allowed_file_types['application/x-zip-compressed'] = 'zip'; 
$allowed_file_types['application/octet-stream'] = 'zip'; 
$allowed_file_types['application/x-compress'] = 'zip'; 
$allowed_file_types['application/x-compressed'] = 'zip'; 
$allowed_file_types['multipart/x-zip'] = 'zip'; 

$allowed_file_types['application/rar'] = 'rar'; 
$allowed_file_types['application/x-rar'] = 'rar'; 
$allowed_file_types['application/x-rar-compressed'] = 'rar';
$allowed_file_types['application/octet-stream'] = 'rar'; 
$allowed_file_types['application/x-rar-compressed; application/x-compressed'] = 'rar'; 
$allowed_file_types['compressed/rar; application/x-rar-compressed'] = 'rar';

if ($_POST) {  

$file = $_FILES['uploadedfile'];
        
	while($counter <= count($file))
{
	if($file['size'][$counter] > 0)
{
	if(!array_key_exists($file['type'][$counter], $allowed_file_types))
{
	echo 'File '.($counter+1).' is not a accepted file type!<br />';
}else{
		@mysql_query("INSERT INTO filename (filename) VALUES ('0')");
		$new_id = mysql_insert_id();
		$filetype = $file['type'][$counter];
		$extention = $allowed_file_types[$filetype];
		$filename = $new_id.".".$extention;

		@mysql_query("UPDATE filename SET modelid='".$_GET['modelid']."', filename='".$filename."', userid='".$_SESSION['userid']."' WHERE fileid='".$new_id."'");

	$newfile = $file_dir.'/'.$filename; 
	move_uploaded_file($_FILES['uploadedfile']['tmp_name'][$counter], $newfile);  


 }
}
$counter++;
}

		@mysql_query("INSERT INTO comments (modelid, comment, userid) VALUES ('".$_GET['modelid']."', '".addslashes($_POST['comment'])."', '".$_SESSION['userid']."')");
		echo '<center>Files uploaded successfully</center>';
		
	}else{
  	echo '<form method="post" enctype="multipart/form-data">';  
	for($i=0;$i<$numoffile;$i++) {  
    echo '<input type="file" name="uploadedfile[]" size="30"><br />';  
	} 
	echo '<br /><textarea name="comment" cols="42" rows="8"></textarea><br /><br />';   
  	echo '<input type="submit" name="action" value="Upload">';  
  	echo '</form>';
	}

?>
Is that acceptable code, could it be writen any better?

It is for people to zip files using winzip or winrar and upload to the server, could any of the $allowed_file_types be droped or should there be more added?


Thanks
Post Reply