roopurt18 Posted November 30, 2007 Share Posted November 30, 2007 http://www.php.net/features.file-upload Scroll down to where it talks about $_FILES. Essentially, $_FILES is an auto-global like $_SESSION or $_SERVER. When you have an input of type="file" in an HTML form, $_FILES will have an index with the same key as the name attribute of your input. For example, you have: <input type="file" name="image"><br><br> Thus there will be a variable $_FILES['image'] that contains data about the image upload. Try adding this to your script in the processing portion: echo '<pre style="text-align: left;">' . print_r($_FILES, true) . '</pre>'; While $_FILES has a decent amount of information packed into it, I will warn you in advance that you should not trust the 'type' index. This is provided by the browser and can easily be faked. Quote Link to comment Share on other sites More sharing options...
runnerjp Posted December 1, 2007 Author Share Posted December 1, 2007 i added code and still getting Warning: move_uploaded_file(http://www.runningprofiles.com/members/images) [function.move-uploaded-file]: failed to open stream: HTTP wrapper does not support writeable connections. in /home/runningp/public_html/members/upload.php on line 33 Warning: move_uploaded_file() [function.move-uploaded-file]: Unable to move '/tmp/php1tyJB1' to 'http://www.runningprofiles.com/members/images' in /home/runningp/public_html/members/upload.php on line 33 Array ( [image] => Array ( [name] => logooo.bmp [type] => image/bmp [tmp_name] => /tmp/php1tyJB1 [error] => 0 [size] => 135054 ) ) Warning: unlink(./images/) [function.unlink]: Is a directory in /home/runningp/public_html/members/upload.php on line 51 $_FILES['image'] is the code error Quote Link to comment Share on other sites More sharing options...
roopurt18 Posted December 1, 2007 Share Posted December 1, 2007 It looks as if move_uploaded_file() is trying to move the file to another server. Your script is in: /home/runningp/public_html/members/ and your images directory is in: /home/runningp/public_html/members/images/ Try this: if(is_uploaded_file($_FILES['image']['tmp_name'])){ // set destination directory $dst = realpath(dirname(__FILE__) . '/images') . '/' . get_username($_SESSION['user_id']); if(move_uploaded_file($_FILES['image']['tmp_name'], $dst)){ // Success, file has been moved and renamed // now do whatever else is necessary } } Quote Link to comment Share on other sites More sharing options...
runnerjp Posted December 2, 2007 Author Share Posted December 2, 2007 added code above and still getting a mass array of errors Warning: move_uploaded_file(/home/runningp/public_html/members/images/) [function.move-uploaded-file]: failed to open stream: Is a directory in /home/runningp/public_html/members/upload.php on line 36 Warning: move_uploaded_file() [function.move-uploaded-file]: Unable to move '/tmp/phpokPjcd' to '/home/runningp/public_html/members/images/' in /home/runningp/public_html/members/upload.php on line 36 Warning: fread(): supplied argument is not a valid stream resource in /home/runningp/public_html/members/upload.php on line 43 Warning: fclose(): supplied argument is not a valid stream resource in /home/runningp/public_html/members/upload.php on line 46 Warning: unlink() [function.unlink]: No such file or directory in /home/runningp/public_html/members/upload.php on line 55 <? session_start(); require_once '../settings.php';?> <? session_start(); require_once '../settings.php';?> <?php if (!$_POST['uploaded']){ //If nothing has been uploaded display the form ?> <form action="<? echo $_SERVER['PHP_SELF']; ?>" method="post" ENCTYPE="multipart/form-data"> Upload:<br><br> <input type="file" name="image"><br><br> <input type="hidden" name="uploaded" value="1"> <input type="submit" value="Upload"> </form> <? }else{ //if the form hasn't been submitted then: //from here onwards, we are copying the file to the directory you made earlier, so it can then be moved //into the database. The image is named after the persons IP address until it gets moved into the database //get users IP $id= get_username ( $_SESSION['user_id'] ); //don't continue if an image hasn't been uploaded if(is_uploaded_file($_FILES['image']['tmp_name'])){ // set destination directory $dst = realpath(dirname(__FILE__) . '/images') . '/' . get_username($_SESSION['user_id']); if(move_uploaded_file($_FILES['image']['tmp_name'], $dst)){ // Success, file has been moved and renamed // now do whatever else is necessary } } //record the image contents into a variable $contents1 = fread($fp1, filesize($filename1)); //close the file fclose($fp1); //encode the image into text $encoded = chunk_split(base64_encode($contents1)); //insert information into the database mysql_query("INSERT INTO images (img,data)"."VALUES ('NULL', '$encoded')"); //delete the temporary file we made unlink($filename1); } //end ?> Quote Link to comment Share on other sites More sharing options...
runnerjp Posted December 2, 2007 Author Share Posted December 2, 2007 *bump* Quote Link to comment Share on other sites More sharing options...
runnerjp Posted December 2, 2007 Author Share Posted December 2, 2007 ** Quote Link to comment Share on other sites More sharing options...
roopurt18 Posted December 2, 2007 Share Posted December 2, 2007 I added a debugging function and commented out most of the "fluff." This will upload and move the file into the proper directory. <?php session_start(); require_once '../settings.php'; if(!$_POST['uploaded']){ /** * DISPLAY FORM */ ?> <form action="" method="post" enctype="multipart/form-data"> Upload:<br><br> <input type="file" name="image"><br><br> <input type="hidden" name="uploaded" value="1"> <input type="submit" value="Upload"> </form> <?php }else{ /** * PROCESS FORM */ // %% debugging info dbg_out($_SESSION); dbg_out($_FILES); //from here onwards, we are copying the file to the directory you made earlier, so it can then be moved //into the database. The image is named after the persons IP address until it gets moved into the database //get users IP $id= get_username ( $_SESSION['user_id'] ); //don't continue if an image hasn't been uploaded if(is_uploaded_file($_FILES['image']['tmp_name'])){ // set destination directory $dst = realpath(dirname(__FILE__) . '/images') . '/' . $id; dbg_out($dst); // %% if(move_uploaded_file($_FILES['image']['tmp_name'], $dst)){ // Success, file has been moved and renamed // now do whatever else is necessary dbg_out('SUCCESS!'); // %% } } /* You haven't fopen()'ed the file, so $fp1 is unassigned $contents1 = fread($fp1, filesize($filename1)); fclose($fp1); */ /* let's forget about the following until we resolve the is_uploaded_file() and move_uploaded_file() errors //encode the image into text $encoded = chunk_split(base64_encode($contents1)); //insert information into the database mysql_query("INSERT INTO images (img,data)"."VALUES ('NULL', '$encoded')"); //delete the temporary file we made unlink($filename1); */ } /** * remove this function later and all calls to it */ function dbg_out($msg){ if(is_bool($msg)){ $msg = $msg ? '[TRUE]' : '[FALSE]'; }else if(is_null($msg)){ $msg = '[NULL]'; }else if(is_string($msg) && strlen($msg) == 0){ $msg = '[EMPTY STRING]'; } echo '<pre style="text-align: left;">' . print_r($msg, true) . '</pre>'; } ?> Copy and paste what the above outputs. If it is_uploaded_file() and move_uploaded_file() still produce errors, check the file permissions on the folder you're copying into. Quote Link to comment Share on other sites More sharing options...
runnerjp Posted December 2, 2007 Author Share Posted December 2, 2007 still getting error Array ( ) Array ( [image] => Array ( [name] => runner.bmp [type] => image/bmp [tmp_name] => /tmp/phpfFCXtw [error] => 0 => 216054 ) ) /home/runningp/public_html/members/images/ Warning: move_uploaded_file(/home/runningp/public_html/members/images/) [function.move-uploaded-file]: failed to open stream: Is a directory in /home/runningp/public_html/members/upload.php on line 38 Warning: move_uploaded_file() [function.move-uploaded-file]: Unable to move '/tmp/phpfFCXtw' to '/home/runningp/public_html/members/images/' in /home/runningp/public_html/members/upload.php on line 38 strange as members/images/ is set to 777 Quote Link to comment Share on other sites More sharing options...
roopurt18 Posted December 2, 2007 Share Posted December 2, 2007 You should really take the time to try and figure out why this isn't working. The answer is pretty obvious. The first thing my code prints out is your $_SESSION array, which is EMPTY! Since you're trying to set the destination filename based on $_SESSION['user_id'], which doesn't exist, the $id variable is empty as well. Thus the destination you're trying to write to is (wrong): /home/runningp/public_html/members/images/ vs. (correct) /home/runningp/public_html/members/images/filename So why is your $_SESSION variable empty? Quote Link to comment Share on other sites More sharing options...
runnerjp Posted December 3, 2007 Author Share Posted December 3, 2007 ahhh bingo got it to upload the file... so now do i just add the extra things...also how would i call the users image? have nit figured that 1 out Quote Link to comment Share on other sites More sharing options...
runnerjp Posted December 3, 2007 Author Share Posted December 3, 2007 i added $encoded = chunk_split(base64_encode($contents1)); mysql_query("INSERT INTO images (img,data)"."VALUES ('NULL', '$encoded')"); but it does not add data to table? Quote Link to comment Share on other sites More sharing options...
runnerjp Posted December 3, 2007 Author Share Posted December 3, 2007 bumping Quote Link to comment Share on other sites More sharing options...
roopurt18 Posted December 3, 2007 Share Posted December 3, 2007 Based on your code, it appears that you want to store the actual file contents into the database. While you can do this, it makes things a little more complicated. Also, since you already have a copy of the file on your file system, it would be redundant to store it in the database. Let's summarize what we have so far. All of the member images are stored here: /home/runningp/public_html/members/images/ Each image is named after the member's username, thus each member can have only one image. For example, a user named 'bobsmith' would be associated with the image: /home/runningp/public_html/members/images/bobsmith Your website domain maps to the directory: /home/runningp/public_html/ So to display bobsmith's image, you could create this HTML: <img src="http://www.yourdomain.com/members/images/bobsmith" alt="bobsmith's image" /> We have a small problem. Since there is no file extension appended to the file, the browser does not know what type of file it is. Anyone visiting that URL will get a prompt to open or save the file. We also have a related problem. Your upload script is not performing any validation; any file uploaded by the user will be accepted, whether it's a valid image or not. So at this point in time, we can fix two problems at once if we can deterine the file type. There are two ways to do this: 1) Check the value of $_FILES['image']['type']. This field is not trust-worthy however because it is supplied by the web browser. Basically, a user could upload a .php script to delete your entire website but fool the browser into thinking it was a valid image. 2) By using getimagesize() or the fileinfo package. Let's try the getimagesize() approach first. What does this code output (note that I've again commented out your DB stuff, save it for last): <?php session_start(); require_once '../settings.php'; if(!$_POST['uploaded']){ /** * DISPLAY FORM */ ?> <form action="" method="post" enctype="multipart/form-data"> Upload:<br><br> <input type="file" name="image"><br><br> <input type="hidden" name="uploaded" value="1"> <input type="submit" value="Upload"> </form> <?php }else{ /** * PROCESS FORM */ // %% debugging info dbg_out($_SESSION); dbg_out($_FILES); // First line of error checking, make sure upload successful if($_FILES['image']['error'] !== UPLOAD_ERR_OK){ echo 'Error: There was an error with your upload.'; exit(); } // Now we know we have an uploaded file, let's check the type $image_size = getimagesize($_FILES['image']['tmp_name']); if($image_size === FALSE){ echo 'Error: getimagesize() has failed.'; exit(); } // Debug print the mime type that was found dbg_out($image_size['mime']); //get users IP $id= get_username ( $_SESSION['user_id'] ); //don't continue if an image hasn't been uploaded if(is_uploaded_file($_FILES['image']['tmp_name'])){ // set destination directory $dst = realpath(dirname(__FILE__) . '/images') . '/' . $id; dbg_out($dst); // %% if(move_uploaded_file($_FILES['image']['tmp_name'], $dst)){ // Success, file has been moved and renamed // now do whatever else is necessary dbg_out('SUCCESS!'); // %% } } /* You haven't fopen()'ed the file, so $fp1 is unassigned $contents1 = fread($fp1, filesize($filename1)); fclose($fp1); */ /* let's forget about the following until we resolve the is_uploaded_file() and move_uploaded_file() errors //encode the image into text $encoded = chunk_split(base64_encode($contents1)); //insert information into the database mysql_query("INSERT INTO images (img,data)"."VALUES ('NULL', '$encoded')"); //delete the temporary file we made unlink($filename1); */ } /** * remove this function later and all calls to it */ function dbg_out($msg){ if(is_bool($msg)){ $msg = $msg ? '[TRUE]' : '[FALSE]'; }else if(is_null($msg)){ $msg = '[NULL]'; }else if(is_string($msg) && strlen($msg) == 0){ $msg = '[EMPTY STRING]'; } echo '<pre style="text-align: left;">' . print_r($msg, true) . '</pre>'; } ?> Copy and paste what your script outputs and I can continue to help you. Quote Link to comment Share on other sites More sharing options...
runnerjp Posted December 3, 2007 Author Share Posted December 3, 2007 can i first say thankyou so much for helping me out and dedicating your time to doing so... if there is any way i can return the favour i will! Array ( [user_id] => 1 [logged_in] => 1 ) Array ( [image] => Array ( [name] => runner.bmp [type] => image/bmp [tmp_name] => /tmp/php9LyKjn [error] => 0 [size] => 216054 ) ) image/bmp /home/runningp/public_html/members/images/admin SUCCESS! [code] is the output [/code] Quote Link to comment Share on other sites More sharing options...
roopurt18 Posted December 3, 2007 Share Posted December 3, 2007 This line of the code: // Debug print the mime type that was found dbg_out($image_size['mime']); correlates to this line of output: image/bmp This tells us that getimagesize() is supported (and working) on your server. From here it is trivial to validate and rename the file. To validate the file as an image, we will separate the type from the extension. $img_arr = explode('/', $image_size['mime']); if(count($img_arr) != 2){ echo 'Error: Problem with image type'; exit(); } $type = $img_arr[0]; // mime type $ext = $img_arr[1]; // file extension if(strlen($type) == 0 || strlen($ext) == 0){ // Neither of those vars can be zero length echo 'Error: No type or extension found'; exit(); } if($type != 'image'){ // Not an image! echo 'Error: Uploaded file was not an image'; exit(); } Now currently, your code is naming the image after the user's username, which is fine. But what happens if someone (for whatever reason) changes their username? You have to remember to go back and change their image as well. To avoid this, let's name the image after the user's id, which will never change. $id= $_SESSION['user_id']; Next we will change our line of code that sets the destination to use the extension. $dst = realpath(dirname(__FILE__) . '/images') . '/' . $id . '.' . $ext; Now, let's think about how we go about calling this image up later. The images are located in: /home/runningp/public_html/members/images/ They are named with the following format: <user_id>.<extension> So if a user with id 2 uploads a jpg, it will be located in: /home/runningp/public_html/members/images/2.jpg The appropriate img tag is then: <img src="http://www.yourdomain.com/members/images/2.jpg" alt="2's avatar" /> So now let's think of what the givens are. All of the files are stored in the same directory All of the files are named after the user's id The only thing that changes from image to image is the extension; therefore, the only thing we need to save in the database is the extension and which user it is attached to. Here is the create table for the proper database table. CREATE TABLE `user_images` ( `user_id` INTEGER NOT NULL DEFAULT 0, `ext` VARCHAR(4) NOT NULL DEFAULT '', `created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', `modified` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00' ); Thus, if the user's id is stored in $user_id and the extension is stored in $ext, here is the query to insert: $Clean = Array(); $Clean['user_id'] = "'" . mysql_real_escape_string($user_id) . "'"; $Clean['ext'] = "'" . mysql_real_escape_string($ext) . "'"; $sql = " INSERT INTO `user_images` (`user_id`, `ext`, `created`, `modified`) VALUES ( {$Clean['user_id']}, {$Clean['ext']}, NOW(), NOW() ) "; Putting it all together: <?php session_start(); require_once '../settings.php'; if(!$_POST['uploaded']){ /** * DISPLAY FORM */ ?> <form action="" method="post" enctype="multipart/form-data"> Upload:<br><br> <input type="file" name="image"><br><br> <input type="hidden" name="uploaded" value="1"> <input type="submit" value="Upload"> </form> <?php }else{ /** * PROCESS FORM */ // %% debugging info dbg_out($_SESSION); dbg_out($_FILES); // First line of error checking, make sure upload successful if($_FILES['image']['error'] !== UPLOAD_ERR_OK){ echo 'Error: There was an error with your upload.'; exit(); } // Now we know we have an uploaded file, let's check the type $image_size = getimagesize($_FILES['image']['tmp_name']); if($image_size === FALSE){ echo 'Error: getimagesize() has failed.'; exit(); } // Debug print the mime type that was found dbg_out($image_size['mime']); $img_arr = explode('/', $image_size['mime']); if(count($img_arr) != 2){ echo 'Error: Problem with image type'; exit(); } $type = $img_arr[0]; // mime type $ext = $img_arr[1]; // file extension if(strlen($type) == 0 || strlen($ext) == 0){ // Neither of those vars can be zero length echo 'Error: No type or extension found'; exit(); } if($type != 'image'){ // Not an image! echo 'Error: Uploaded file was not an image'; exit(); } //get users ID $id = $_SESSION['user_id']; //don't continue if an image hasn't been uploaded if(is_uploaded_file($_FILES['image']['tmp_name'])){ // set destination directory $dst = realpath(dirname(__FILE__) . '/images') . '/' . $id . '.' . $ext; dbg_out($dst); // %% if(move_uploaded_file($_FILES['image']['tmp_name'], $dst)){ // Success, file has been moved and renamed // now do whatever else is necessary dbg_out('SUCCESS!'); // %% $Clean = Array(); $Clean['user_id'] = "'" . mysql_real_escape_string($id) . "'"; $Clean['ext'] = "'" . mysql_real_escape_string($ext) . "'"; $sql = " INSERT INTO `user_images` (`user_id`, `ext`, `created`, `modified`) VALUES ( {$Clean['user_id']}, {$Clean['ext']}, NOW(), NOW() ) "; $q = mysql_query($sql); if($q === FALSE){ dbg_out('ERROR: ' . mysql_error()); }else{ dbg_out('Database insert successful'); } } } /* Everything else you had is irrelevant at this point */ } /** * remove this function later and all calls to it */ function dbg_out($msg){ if(is_bool($msg)){ $msg = $msg ? '[TRUE]' : '[FALSE]'; }else if(is_null($msg)){ $msg = '[NULL]'; }else if(is_string($msg) && strlen($msg) == 0){ $msg = '[EMPTY STRING]'; } echo '<pre style="text-align: left;">' . print_r($msg, true) . '</pre>'; } ?> Copy and paste what that code gives you and we can keep going. Now keep in mind so far that we're only handling a user uploading an image. We haven't done anything yet to delete an existing image if it exists. Also, with the arrangement of this current system, each user is limited to a single image. If this is for avatars, then this limitation is fine. If this is for something more complex, like a photo gallery, then there are substantial design changes to be made. Quote Link to comment Share on other sites More sharing options...
runnerjp Posted December 3, 2007 Author Share Posted December 3, 2007 the id part makes sence... i dont know why i thought of username it just made sence at 1st lol Array ( [user_id] => 1 [logged_in] => 1 ) Array ( [image] => Array ( [name] => runner.bmp [type] => image/bmp [tmp_name] => /tmp/phpH5lxms [error] => 0 [size] => 216054 ) ) image/bmp /home/runningp/public_html/members/images/1.bmp SUCCESS! Database insert successful i also see the data has been added to db thanks again you are rlly making it more simple for me to understand... bte this script is aimed for avatours Quote Link to comment Share on other sites More sharing options...
roopurt18 Posted December 3, 2007 Share Posted December 3, 2007 Let's handle the first part of expanding upon this. See if you can add the necessary code to delete a user's avatar if it already exists while they are uploading a new one. Quote Link to comment Share on other sites More sharing options...
runnerjp Posted December 3, 2007 Author Share Posted December 3, 2007 would it not just overwrite the image?? Quote Link to comment Share on other sites More sharing options...
runnerjp Posted December 3, 2007 Author Share Posted December 3, 2007 $sql = "DELETE FROM user_images WHERE name='$user_id'"; should delete image Quote Link to comment Share on other sites More sharing options...
roopurt18 Posted December 3, 2007 Share Posted December 3, 2007 Looking at the documentation for move_uploaded_file(), if the file exists it will be overwritten. Warning -- If the destination file already exists, it will be overwritten. That means you technically don't have to delete the file off the file system. But you might want to anyways. Because if the user uploads a gif image first and then a jpg, you will have two files for that user (3.gif & 3.jpg). This isn't a problem for display purposes because your `user_images` table should only ever have one entry per user and it should always be the most current one, but your file system will wind up containing images that are never used for anything. It's something to consider if your host doesn't give you lots of disk space. So before you run the INSERT, you should run the following: $sql = "DELETE FROM `user_images` WHERE `user_id`={$Clean['user_id']}"; That will guarantee that your table only has one row per user and that it is the most recent one. Quote Link to comment Share on other sites More sharing options...
runnerjp Posted December 3, 2007 Author Share Posted December 3, 2007 ok i tryed if(move_uploaded_file($_FILES['image']['tmp_name'], $dst)){ // Success, file has been moved and renamed // now do whatever else is necessary dbg_out('SUCCESS!'); // %% $Clean = Array(); $Clean['user_id'] = "'" . mysql_real_escape_string($id) . "'"; $Clean['ext'] = "'" . mysql_real_escape_string($ext) . "'"; $sql = "DELETE FROM `user_images` WHERE `user_id`={$Clean['user_id']}"; $sql = " INSERT INTO `user_images` (`user_id`, `ext`, `created`, `modified`) VALUES ( {$Clean['user_id']}, {$Clean['ext']}, NOW(), NOW() ) "; $q = mysql_query($sql); if($q === FALSE){ dbg_out('ERROR: ' . mysql_error()); }else{ dbg_out('Database insert successful'); } and it added data but didnt delete old data Quote Link to comment Share on other sites More sharing options...
helraizer Posted December 3, 2007 Share Posted December 3, 2007 Haven't followed this perfectly but if you were to use the GD library, could you not just use ImageJpeg (or ImagePng, or ImageGif, or other) and save the file as the username.jpg For instance, something along the lines of what you've already got but then to save as the username.jpg: <?php //database code to get username and uploading files code, including $image = ImageCreateFromJpeg (or ..FromGif or... FromPng (depending on the extension of the file uploaded)) header ("Content-type: image/jpg"); ImageJpeg($image, $username. ".jpg"); ImageDestroy($image) ?> Then add those files (path) into the database. I'm not sure that's what you're after but that'd work in theory Sam Quote Link to comment Share on other sites More sharing options...
runnerjp Posted December 3, 2007 Author Share Posted December 3, 2007 hey thanks just like to see what roopurt18 has to say about it as i have been follwing his sytem so far Quote Link to comment Share on other sites More sharing options...
roopurt18 Posted December 3, 2007 Share Posted December 3, 2007 You forgot to call mysql_query() after creating the DELETE statement. Quote Link to comment Share on other sites More sharing options...
runnerjp Posted December 3, 2007 Author Share Posted December 3, 2007 would it be $sql = "DELETE FROM `user_images` WHERE `user_id`={$Clean['user_id']}"; $q = mysql_query($sql); if($q === FALSE){ dbg_out('ERROR: ' . mysql_error()); $sql = " INSERT INTO `user_images` (`user_id`, `ext`, `created`, `modified`) VALUES ( {$Clean['user_id']}, {$Clean['ext']}, NOW(), NOW() ) "; Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.