File Uploads (extensions, renaming)

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

furiousweebee
Forum Commoner
Posts: 69
Joined: Sun Jul 11, 2004 7:38 am
Location: Brisbane, Australia
Contact:

File Uploads (extensions, renaming)

Post by furiousweebee »

Hey,

I'm sure this is easy for many of you, but I'm only just starting out with using PHP so I'm not sure where to go from here. Anyway, my problems/tasks are as follows:

- I have a form which both adds information to MySQL, and uploads a file. The file uploading works, but the way I have it working, it gives all uploaded files a JPG extension. I'd like to retain the extension of the original file.

- The uploaded file uses a name taken from one of the other form fields. This is purely so that I can later display the appropriate image (on another page of my site). Instead, I'd like to be able to rename the file based on some abbreviations, and then a number which is today's date (eg my file might end up like this: "DJ-11.05.05" (being short for "Disc Jockey", uploaded on 11th May 2005).

I did hunt around these forums for existing code but couldn't find quite what I was looking for/wasn't sure exactly how to implement it.

Below is my code:

Code: Select all

<FORM ENCTYPE=&quote;multipart/form-data&quote; ACTION=&quote;<? $PHP_SELF ?>&quote; METHOD=&quote;POST&quote;>

<strong>Name:</strong><br>
<INPUT type=&quote;text&quote; name=&quote;name&quote; size=&quote;40&quote;><br><br>

<strong>Website:</strong><br>
http://<INPUT type=&quote;text&quote; name=&quote;website&quote; size=&quote;50&quote;><br><br>

<strong>Type:</strong><br>
<select name=&quote;type&quote;>
<option selected>Band</option>
<option>Label</option>
<option>Site</option>
</select><br><br>

<strong>Short Description:</strong><br>
<INPUT type=&quote;text&quote; name=&quote;description&quote; size=&quote;78&quote;><br><br>

<strong>Banner / Logo:</strong><br>
<INPUT type=&quote;file&quote; name=&quote;fnt&quote; size=&quote;78&quote;><br><br>
<input type=&quote;submit&quote; name=&quote;enter_data&quote; value=&quote;Submit&quote;></TD>
</form>

Code: Select all

<?

if ($_POST['enter_data']) {

if ($fnt != "") {
$name = stripslashes($name);
copy($_FILES['fnt']['tmp_name'], "../images/ads/$name.jpg");
$resource = mysql_query("INSERT into sponsors (name, website, description, type, pic) VALUES ('$name', '$website', '$description', '$type', 'Y')") or die(mysql_error()); }

else {
$resource = mysql_query("INSERT into sponsors (name, website, description, type) VALUES ('$name', '$website', '$description', '$type')") or die(mysql_error()); }

MYSQL_CLOSE();
echo"<META HTTP-EQUIV=refresh content=0;URL=index.php>";

}

?>
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post by Chris Corbyn »

Don't use $name by the way for POST... it's bad practise. Always use $_POST['name'];

OK to the question(s). To avoid the .jpg extension remove the .jpg extensions from the last argument in copy().

Code: Select all

$name = $_POST['name']; //Always do it like this
copy($_FILES['fnt']['tmp_name'], "../images/ads/$name");
For the abbreviations... that'll be damn hard if you want it to recognise words and abbreviate based on them. But to trim the filename to a fixed length and append the date (and perhaps time to avoid duplicates :? ) would be easy.

Untested (may need some tweaking)...

Code: Select all

preg_match('/^(.+)\.?([^\.]+?)$/', $_POST['name'], $base_and_ext); //Get bits into array
$base = substr($base_and_ext[1], 0, 4); //Allows up to 4 Chars in filename
$ext = $base_and_ext[2]; //The extension
$date = date("d.m.y");
copy($_FILES['fnt']['tmp_name'], '../images/ads/'.$base.'_'.$date.'.'.$ext); //Copy the newly named file
If run on 13th March 2005 the above should turn Saturday.jpeg into Satu_13.03.05.jpeg ;-)

EDIT: Modified regexp for ^ and $ and corrected position of $ext in filename :oops:
furiousweebee
Forum Commoner
Posts: 69
Joined: Sun Jul 11, 2004 7:38 am
Location: Brisbane, Australia
Contact:

Post by furiousweebee »

Thanks, I gave that a shot and ended up with the code below. However, when using the name of "Test2" on my form, I ended up with the following filename (including extension): "14.03.05.2". Note that I changed it to 10 characters.

Code: Select all

if ($fnt != "") {
$name = stripslashes($_POST['name']);
preg_match('/^(.+)\.?([^\.]+?)$/', $_POST['name'], $base_and_ext); // Get bits into array
$base = substr($base_and_ext[1], 0, 10); // Allows up to 10 chars in filename
$ext = $base_and_ext[2]; // The extension
$date = date("d.m.y");
copy($_FILES['fnt']['tmp_name'], "../images/ads/$base_$date.$ext"); //Copy the newly named file
hongco
Forum Contributor
Posts: 186
Joined: Sun Feb 20, 2005 2:49 pm

Post by hongco »

i would use strrchr() function to get the extension of the uploaded file
if you use something like this for file, says, mypic.jpg

Code: Select all

$ext = strrchr($HTTP_POST_FILES['fnt']['name'], ".");
echo $ext;  // result  .jpg  (with the dot in front)
It will always get the last dot (.). So if you have mypic.1.2.3.jpg...it still gives .jpg as the result
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

be aware that a file's extension does not necessarily determine what kind of file it actually is.
hongco
Forum Contributor
Posts: 186
Joined: Sun Feb 20, 2005 2:49 pm

Post by hongco »

feyd wrote:be aware that a file's extension does not necessarily determine what kind of file it actually is.
yeah, i thought check file type would help, but somehow, if I change the extension from *.exe to *.jpg, the uploading script that i am working still consider the file as an image type. Am i doing something wrong or there is a way to determine file's true type?

Thanks!
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

because of the ease of forging a fake file, the only way to be sure is binary recognition, basically.. to analyze images of "normal" web use, getimagesize() can be used.
hongco
Forum Contributor
Posts: 186
Joined: Sun Feb 20, 2005 2:49 pm

Post by hongco »

feyd wrote:because of the ease of forging a fake file, the only way to be sure is binary recognition, basically.. to analyze images of "normal" web use, getimagesize() can be used.
thank you feyd :)
This also gives me the idea how to determine mp3 file- the id3 tag. I will allow my website members upload their own singing with mp3 format.
hongco
Forum Contributor
Posts: 186
Joined: Sun Feb 20, 2005 2:49 pm

Post by hongco »

just wanted to post this helpful link:

http://www.flash-db.com/remoting/?servi ... Multimedia

This class gives info on mp3 file.

I tested it, and it works great for my need
furiousweebee
Forum Commoner
Posts: 69
Joined: Sun Jul 11, 2004 7:38 am
Location: Brisbane, Australia
Contact:

Post by furiousweebee »

So, back to my original topic hehe... I should end up with something like this?

Code: Select all

if ($fnt != "") {
$name = stripslashes($_POST['name']);
preg_match('/^(.+)\.?([^\.]+?)$/', $_POST['name'], $base_and_ext);
$base = substr($base_and_ext[1], 0, 10);
$ext = strrchr($HTTP_POST_FILES['fnt']['name'], ".");
$date = date("d.m.y");
copy($_FILES['fnt']['tmp_name'], "../images/ads/$base_$date.$ext");
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post by Chris Corbyn »

OK I tested my RegExp (preg_match() part) but it doesn't work as I'd hoped.

I'll try to re-write the regexp unless somebody does it before me.

The idea of just using strrchr() could be manipulated to do the same task too I guess but a pattern match would be nicer.

It just needs the preg_match() line tweaking and it'll work :-D
furiousweebee
Forum Commoner
Posts: 69
Joined: Sun Jul 11, 2004 7:38 am
Location: Brisbane, Australia
Contact:

Post by furiousweebee »

Sweet, that would be great if you could. The other thing I realised, is that I'm going to have to be able to recall this entire filename to later display it with the appropriate record. So instead of putting 'Y' into the 'pic' field in MySQL, I'm going to have to store the filename (or make another column for the name).
furiousweebee
Forum Commoner
Posts: 69
Joined: Sun Jul 11, 2004 7:38 am
Location: Brisbane, Australia
Contact:

Post by furiousweebee »

I've been playing around with it, and I came up with the following code:

Code: Select all

$name = $_POST['name'];

if (isset($_POST['enter_data'])) {
	if (!empty($_FILES['fnt'])) {
		$name_short = stripslashes(substr($_POST['name'], 0, 5));
		$extension = strrchr($_FILES['fnt']['name'], ".");
		$filename = $name_short."_".date("d.m.y").$extension;
		move_uploaded_file($_FILES['fnt']['tmp_name'], "../images/ads/".$filename);
		$resource = mysql_query("INSERT into sponsors (name, website, description, type, pic) VALUES ('$name', '$website', '$description', '$type', '$filename')") or die(mysql_error()); }
	else {
		$resource = mysql_query("INSERT into sponsors (name, website, description, type, pic) VALUES ('$name', '$website', '$description', '$type', 'n')") or die(mysql_error()); }

MYSQL_CLOSE();
echo"<META HTTP-EQUIV=refresh content=0;URL=index.php>";
	}
Now, this is working perfectly EXCEPT, if there's no file uploaded, I want it to write 'n' into the "pic" field of the table. It's not doing that. It's putting the uploaded filename (without extension), and I can't seem to get around it. Any ideas?
User avatar
n00b Saibot
DevNet Resident
Posts: 1452
Joined: Fri Dec 24, 2004 2:59 am
Location: Lucknow, UP, India
Contact:

Post by n00b Saibot »

Hint: check for $_FILES['fnt']['size'] being equal to 0. ;)
furiousweebee
Forum Commoner
Posts: 69
Joined: Sun Jul 11, 2004 7:38 am
Location: Brisbane, Australia
Contact:

Post by furiousweebee »

So change:

Code: Select all

if (!empty($_FILES['fnt'])) {
To:

Code: Select all

if ($_FILES['fnt']['size'] !== '0') {
?

Or did you mean I should add it to the second part of my loop (after the "else")?
Post Reply