Image Upload Script, Please Help

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
Adam
Forum Newbie
Posts: 11
Joined: Mon Jul 28, 2003 2:45 am

Image Upload Script, Please Help

Post by Adam »

I need sone help, and I would appreciate any that anyone could provide. I have a script set up that uploads images path to my database, but I want it to upload the images to my server as well, and store the path in the database. The code looks like this.

Code: Select all

<?php
if ($action == "add") {

	if ($step == "2") {
	if ($folder == "") {
		print "You must fill in all feilds"; die;
	}
		if ($path == "") {
			print "You must fill in all feilds"; die;
	}
		if ($thumb == "") {
			print "You must fill in all feilds"; die;
	}

	$query="SELECT * FROM games WHERE gameid = '$gameid'";
	$result=mysql_query($query);
	$row = mysql_fetch_array($result);
	$gamename = "$row[gamename]";



	$linkID = @mysql_connect("$dbhost", "$dbuser", "$dbpassword");
	mysql_select_db("$dbname", $linkID) or die(mysql_error());

	$date = date("Y-m-d H:i:s");
	$resultID = mysql_query("INSERT INTO screenshots (screensid, folder, path, thumb, gameid, gamename, systemid, date) VALUES ('$screensid', '$folder', '$path', '$thumb', '$gameid', '$gamename', '$systemid', '$date')", $linkID) or die(mysql_error());
	if ($resultID == TRUE) {
		print "Screenshot was added to the database.<BR>";
	} else {
		print "Screenshot was not added to the database. Please try again.<BR>";
	}
}
else
{
	$query="SELECT * FROM games WHERE systemid = '$systemid'";
	$result=mysql_query($query);
	$row = mysql_fetch_row($result);
	$ngames = $row[0];
	if ($ngames == "") { print "There is not games in this system."; die; }

	echo "<form method="POST"action="?module=screenshots.php&action=add&step=2">
	<input type="hidden" name="systemid" value="$systemid">
  <table cellSpacing="0"cellPadding="5"width=668 border="0"height="546">
    <tr>
      <td vAlign="top"width=147 align="right"height="22">
      <p><font face=""Verdana"">Game:</font></td>
      <td vAlign="top"width=511 height="22"><b>
      <font face="Arial, Helvetica, sans-serif"size="2">
      <p align="left">";
	echo "<input type="hidden" name="systemid" value="$systemid">";
	$query="SELECT * FROM games WHERE systemid = '$systemid' ORDER BY gamename ASC";
	$result=mysql_query($query);
	echo "<select name="gameid" style="width:"100%";" tabindex="2">";
	while($row = mysql_fetch_object($result)) {
		echo "<option value="".$row->gameid.""";
		echo ">".$row->gamename."</option>";
	}
	echo "</select>";
      echo "</font></b></td>
    </tr>
    <tr>
      <td vAlign=top align="right" height="10">
      <face="Verdana">folder:</font></td>
      <td vAlign="top" height="10">
	  <input type="text" name="folder" size="20"></td>

    </tr>
        <tr>
	      <td vAlign=top align="right" height="10">
	      <face="Verdana">File Path:</font></td>
	      <td vAlign="top" height="10">
		  <input type="text" name="path" size="20"></td>

    </tr>
        <tr>
	      <td vAlign=top align="right" height="10">
	      <face="Verdana">thumb:</font></td>
	      <td vAlign="top" height="10">
		  <input type="text" name="thumb" size="20"></td>

    </tr>
    <tr>
      <td vAlign=top width=147 align="right"height="324">
      &nbsp;</td>
      <td vAlign="top"width=511 height="324">
      <p align="left"><BR>
  	 <p><input type="submit"value="Add Screenshots"name="B1"><input type="reset"value="Clear"name="B2"></p>
  		</td>
    </tr>
  </table>
</form>";
die;
}
}
?>
Once again, any help appreciated.
Thanks, Adam
fractalvibes
Forum Contributor
Posts: 335
Joined: Thu Sep 26, 2002 6:14 pm
Location: Waco, Texas

Post by fractalvibes »

To start with, if you are uploading files, you need to add this to your form tag:

ENCTYPE="multipart/form-data"

In the script that is the action of the form, you need to fetch that file:
assuming the file is called 'txtTheFile' (the form field that is of type file
<input type=file name=txtTheFile> etc.

$newfile = fopen($txtTheFile, "r");
$filecontents = fread($newfile, filesize($txtTheFile));
$Path = "/wherethefilegoes/" . $txtTheFile_name;
$anotherfile = fopen("$Path", "a+");
fputs($anotherfile, $filecontents);

plus any manipulation

Phil J.
Adam
Forum Newbie
Posts: 11
Joined: Mon Jul 28, 2003 2:45 am

Post by Adam »

Sorry to be a pain, but can you show me what the code would look like txtTheFile was an image, and if my code was with it? Thanks a bunch either way.

Adam
Galahad
Forum Contributor
Posts: 111
Joined: Fri Jun 14, 2002 5:50 pm

Post by Galahad »

Hey, check out the php manual's section handling file uploads. It was a great help to me when I was trying to figure out uploading.

I don't think fractalvibes's idea will actually work. I believe $txtTheFile would actually be an array, not a text string. $_FILES['txtTheFile'] would be a better way to access that variable, just $txtTheFile will only work with register globals on and that can be less secure. Then, you don't want to open the file and fputs it into another file, just use move_uploaded_file(). Read the manual section for a much more detailed explanation, it even has nice examples.
fractalvibes
Forum Contributor
Posts: 335
Joined: Thu Sep 26, 2002 6:14 pm
Location: Waco, Texas

Post by fractalvibes »

Actuallly it works quite well. :-) You can do ample checking of file size and type before actually saving the file. Should work for any file type you want to allow.

fractalvibes
Galahad
Forum Contributor
Posts: 111
Joined: Fri Jun 14, 2002 5:50 pm

Post by Galahad »

fractalvibes, I'm confused by your upload file handling method. I've spent a lot of time working with uploads recently, so I feel like I have a fair understanding of how they work, so I'm curious about your approach now. Here are some questions about how your version works:

1. What version of php are you using / have you tried this with? I'm using 4.2.2. Just thought I'd ask to avoid any silly confusion.

2. The php manual section on uploads (see the link I posted earlier) says that a input like

Code: Select all

<input name="userfile" type="file">
will be recieved by php as an array in the $_FILES autoglobal array like:
$_FILES['userfile']['name']
The original name of the file on the client machine.

$_FILES['userfile']['type']
The mime type of the file, if the browser provided this information. An example would be "image/gif".

$_FILES['userfile']['size']
The size, in bytes, of the uploaded file.

$_FILES['userfile']['tmp_name']
The temporary filename of the file in which the uploaded file was stored on the server.

$_FILES['userfile']['error']
The error code associated with this file upload. ['error'] was added in PHP 4.2.0
As I read your code, you use $txtTheFile as string of the filename. Am I correct? If so, have you tried this recently?

3. When you fopen $txtTheFile, where is that file located? Is $txtTheFile an absolute path (like "/home/person/public_html/thefile.txt") or relative (just "thefile.txt")?

I guess that's enough for now. I supose I should just try your code out. Let me know what you think, and I'll see if I can get it to run on my machine. Thanks.
fractalvibes
Forum Contributor
Posts: 335
Joined: Thu Sep 26, 2002 6:14 pm
Location: Waco, Texas

Post by fractalvibes »

Galahad,

I am at work (ASP-only) - I will post a more complete example and PHP version, etc. this evening after I return home. What I have is working, last time I tried was 2 days ago.

fv
Galahad
Forum Contributor
Posts: 111
Joined: Fri Jun 14, 2002 5:50 pm

Post by Galahad »

Ok, here are my findings: It does work! I guess when register globals is on and it registers the $_FILES array, it registers a variable for each element in the array. For instance, if you have an array named $myArray that has ('name' => 'filename.txt', 'size' => '15'), you will end up with $myArray_name and $myArray_size. In the file case, just $txtTheFile gets set to $_FILES['txtTheFile']['tmp_name']. I'm not really sure why (a quick skim of the register_globals info in the manual didn't lead to anything), or if this sort of thing happens all the time or only with files (I didn't bother to check). However, the point is that it works. Sorry that I doubted you fractalvibes.

Here's my code:
Form page

Code: Select all

&lt;html&gt;
&lt;head&gt;
&lt;title&gt;Upload Test&lt;/title&gt;
&lt;/head&gt;

&lt;body&gt;
&lt;form enctype="multipart/form-data" action="uploadhandle.php" method="POST"&gt;
&lt;input type="hidden" name="MAX_FILE_SIZE" value="30000"&gt;
Send this file: &lt;input name="txtTheFile" type="file"&gt;
&lt;input type="submit" value="Send File"&gt;
&lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;
uploadhandle.php

Code: Select all

<?php
//  All of these echo's and print_r's are just to display what's going on with the variables

echo "\$_REQUEST array:\n";
print_r($_REQUEST);
echo "\n";

echo "\$_FILES array:\n";
print_r($_FILES);
echo "\n\n";

echo "Is \$txtTheFile set: ".isset($txtTheFile)."\n";
echo "Just \$txtTheFile: $txtTheFile\n\n";

echo "Is \$txtTheFile_name set: ".isset($txtTheFile_name)."\n";
echo "Just \$txtTheFile_name: $txtTheFile_name\n\n";

echo "Is \$txtTheFile_size set: ".isset($txtTheFile_size)."\n";
echo "Just \$txtTheFile_size: $txtTheFile_size\n\n";

// Done fooling around, do the actual file handling now
$newfile = fopen($txtTheFile, "r");
if ($newfile === FALSE) {
  echo "Could not open $txtTheFile\n";
  exit();
}
$filecontents = fread($newfile, filesize($txtTheFile));

// Just so I can see it
echo "\$filecontents: $filecontents\n\n";

// This is a dummy path, really should go somewhere other than /tmp
$Path = '/tmp/'.$txtTheFile_name;

$anotherfile = fopen("$Path", "a+");
if ($anotherfile === FALSE) {
  echo "Could not open $Path\n";
  fclose($newfile);
  exit();
}
fputs($anotherfile, $filecontents);

fclose($newfile);
fclose($anotherfile);
?>
I did find some problems with this approach. I think you could code in safeguards, but in my example, it is possible to copy any file on the server that the web server as read permissions on to any file on the server that the file has write permissions on. For instance, I typed this url into my browser:
And it copied the source code for the upload script into the /tmp directory. It wouldn't be that hard to figure out which variables to send in the url, you can find the name for txtTheFile in the html of the form, then you just need to know that the rest of the file variables will be in txtTheFile_* variables. I'm not sure this would be a huge issue because if you wanted to read it, you would need to figure out where to write the file that the web server would serve, but it would allow you to change files on the server. I suspect that securing a system using move_uploaded_file and the other stuff like the php manual suggests would be easier. Anyway, that was kind of long, but it was interesting to goof around with!
Post Reply