php file upload not working right - php

I have been assigned the task of fixing an older php site since it has been moved to a newer server. The server it is on now doesn't allow globalized variables and that's pretty much all this site was running off of. When trying to upload an image, my sql statement is showing everything but the id for the listing I am adding the image to. I was hoping someone could help me figure this out.
This is my upload function:
function upload(){
global $imagefolder, $id;
global $tbl_units;
include "globalizePOSTGET.php";
// $uid = uuid();
$minsize = 5000; // 5kb
$maxsize = 3000000; // 3mb
$ext = explode('.',basename($_FILES['userfile']['name']));
$ext = $ext[count($ext)-1];
$ext = strtolower($ext);
if ($ext != "jpg" && $ext != "jpeg" && $ext != "png") {
echo "<script> alert('Image is not a png or jpeg format'); </script>";
return false;
}
$imagename = $_POST['id']."_img".$_FILES['img'].".$ext";
$imagename2 = "X_".$imagename;
$uploadfile = $imagefolder . $imagename;
$uploadfile2 = $imagefolder . $imagename2;
$uploadthumb = $imagefolder . "tn_" . $imagename;
if (file_exists($uploadfile)) unlink($uploadfile);
if (file_exists($uploadthumb)) unlink($uploadthumb);
if (file_exists($uploadfile)) {
echo "<script> alert('Image already exists!'); </script>";
}
else
{
if(is_uploaded_file($_FILES['userfile']['tmp_name'])) {
// check the file is less than the maximum file size
if($_FILES['userfile']['size'] < $maxsize) {
$imgData = addslashes(file_get_contents($_FILES['userfile']['tmp_name'])); // prepare the image for insertion
$size = getimagesize($_FILES['userfile']['tmp_name']); // get the image info..
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile2)) {
$Image = #imagecreatefromjpeg($uploadfile2);
if ($Image) {
$img_height = imagesy($Image);
$img_width = imagesx($Image);
imagedestroy($Image);
}
if ($img_height > $img_width) { // portrait
$tempMultiplier = 150 / $img_height;
$tempMultiplierFull = 600 / $img_height;
} else {
$tempMultiplier = 150 / $img_width;
$tempMultiplierFull = 600 / $img_width;
}
$imageHeight = $img_height * $tempMultiplier;
$imageWidth = $img_width * $tempMultiplier;
$fullimageHeight = $img_height * $tempMultiplierFull;
$fullimageWidth = $img_width * $tempMultiplierFull;
createthumb($imagename2,"tn_".$imagename,$imageWidth,$imageHeight);
if($_FILES['userfile']['size'] > $minsize) {
createthumb($imagename2,$imagename,$fullimageWidth,$fullimageHeight);
if (file_exists($uploadfile2)) unlink($uploadfile2);
} else {
rename($uploadfile2, $uploadfile);
}
$sql = "UPDATE $tbl_units SET photo".$_FILES['img']." = \"" . $imagename . "\" WHERE id = " . $_POST['id'];
echo $sql;
if(!mysql_query($sql)) {
echo "<script> alert('Unable to upload file'); </script>";
} else {
?> <script>location.replace('memonly.php?action=edit_record&id=<?php echo $id; ?>');</script> <?php
}
}
} else {
// if the file is not less than the maximum allowed, print an error
$file_n = basename($_FILES['userfile']['name']);
$file_s = $_FILES['userfile']['size'];
?>
<script> alert("File exceeds the maximum limit of <?php echo $maxsize; ?>\nFile <?php echo $file_n; ?> is <?php echo $file_s; ?>");</script>
<?php
}
}
}
}
I am echoing the sql statement on the line that is giving me the error, I think. After clicking on submit, the page tells me Unable to upload file'. Which is why I echoed the sql there. I end up with a sql statement looking like this:UPDATE member_units SET photo = "_img.jpg" WHERE id = `
Someone please help me! I am very inexperienced in PHP and I have no idea what to do here.
Here is the form that is doing the uploading:
<form enctype="multipart/form-data" action="<?php echo $_SERVER['PHP_SELF']?>" method="post">
<input type="hidden" name="_submit_check" value="1" />
<input type="hidden" name="id" value="<?php echo $id; ?>" />
<input type="hidden" name="img" value="<?php echo $img; ?>" />
Image URL: <input type="file" name="userfile" value="" style="font-size: 10px; width: 100%;">
<input type="submit" value="Submit" onClick="return validate();">
<input type="button" value="Cancel" onClick="location.href='/memonly.php?action=edit_record<?php echo "&id=$id&memberid=$memberid"; ?>';">
</form>

The first thing you need to do with this kind of problem is work through where the issues seem to be happening. So take your echoed statement...
UPDATE member_units SET photo = "_img.jpg" WHERE id = `
This corresponds to...
UPDATE $tbl_units SET photo".$_FILES['img']." = \"" . $imagename . "\" WHERE id = " . $_POST['id'];
We can see by comparison that it is clear that $_FILES['img'] is and empty variable as far as converting it to a string goes. The same is said for $_POST['id'], while $imagename gives a short _img.jpg file name.
Tracking back you can then see that $imagename comes from...
$_POST['id']."_img".$_FILES['img'].".$ext";
This is where your photo = "_img.jpg" comes from. Again, $_FILES['img'] and $_POST['id']
The fact that you're reaching the echo statement means that something is uploading, but it is through the $_FILES['userfile'] array, with all of it's associated variables, for example $_FILES['userfile']['name'] which would give you the filename of the image being uploaded.
What you need to ask yourself next is where you are expecting $_POST['id'] to come from, since it is missing or empty, and what field in your HTML form delivers that variable. Then you need to ask yourself what you are trying to achieve with your naming system. For example if you want an image file to look like: 1_imgLolCat.jpg then your variable will need to look more like
$imagename = $_POST['id']."_img".$_FILES['userfile']['name'];
However the final part of my answer below makes me think that instead of the file name, what you're looking for is actually a POST variable that denotes a category or type of image, in which case you may want to work from...
$imagename = $_POST['id']."_img".$_POST['img'].".$ext";
...if a HTML field exists with the name "img"!
Finally take a look at your SQL statement...
SET photo".$_FILES['img']." = \"" . $imagename . "\"
And double check your tables, since what you appear to be trying to do is set a unique variable in your table that would depend on something passed from the form. I may be wrong here but I assume (as I said above) you want $_POST['img'] in there.
Word of warning, you need...NEED to sanitise these variables before you input them in to a SQL statement like this. Someone could easily take
SET photo".$_POST['img']
and delete your whole table if permissions were set up for your database use to do so. There are plenty of other answers around as to how to do this properly. :)

It seems like 'id' field is not sent in the HTML form. I guess it should be a hidden input ?
Be careful, your script can be the target of an SQL injection : you use a user input ($_POST['id']) directly in an SQL query. You should check if this input is actually set and numeric.

Related

Empty $_FILES PHP

So, I have a form to post a text to a blog. One of the informations include an image.
<label class="w3-text-black">Image:</label>
<input name="image" type="file"/>
<br></br>
<button name="submit" type="submit" class="w3-btn w3-gray w3-hover-black">Send</button>
And I have the PHP part that receives all that information, but only sends the rest to the DB and uploads the image to my server if the image is a PNG.
$temp = explode(".", $_FILES['image']['name']);
if (strstr('.png', end($temp))){ //condition }
This code worked when used in my localhost, but once i uploaded it to my server, this error appeared: Warning: strstr(): Empty needle
And what $temp does is separate the extension with the use of explosion.
After that, i change the name of my file, so i can access it later with js.
$sqlImg = "SELECT * FROM posts WHERE post_id = (SELECT MAX(post_id) FROM posts)";
$resid = mysqli_query($conn, $sqlImg);
$linha = mysqli_fetch_assoc($resid);
$id = $linha['post_id'];
$path = 'blogimg/blog_img' . $id . '.' . end($temp);
if (move_uploaded_file($_FILES['imagem']['tmp_name'], $path)){}
You should not check the file extension with filename
instead of doing that.
$allowed = array('png'); // n number of file types here
$filename = $_FILES['image']['name'];
$ext = pathinfo($filename, PATHINFO_EXTENSION);
if(in_array($ext,$allowed) ) {
// Do operations;
}
I The prolem was actualy pretty simple. I had the enctype set on my local file, but the file hosted in my server did not have it. So i added it and everything worked.

Insert image MYSQL based on radio button choice with PHP

I have a website. In this website I can upload images that are then placed into my SQL database. From here I select the images from the database and show them as thumbnails in the photo gallery, when clicked on the image it shows a large version where you can vote/like and comments etc.
Now what I am trying to do is make 3 category pages, basically 3x the photo gallery that shows the thumbnails.
I have 3 different tables in my database where I insert the images in to.
So I copied the photo gallery 3x and the original upload table in the database 3x.
How ever I do not want to create 3 upload.php files for each photo gallery.php file.
What I'm trying to do is have 3 radio button choices on my upload page and with the choice made there, the image gets uploaded into the matching database table (photo1, 2 or 3).
I have been trying to do this with Functions etc. but I just can't get it to work, I am probably doing something really simple, really stupid.
This is the code i have for the radio button and getting the image:
$titel = "Image";
$query = "SELECT * FROM `i268296_studie`.`fotos` ORDER BY foto_ID DESC";
$result = mysqli_query($conn, $query) or die("query error " . mysqli_error($conn) );
$fotos = array();
//create array from images in database
while($data = mysqli_fetch_assoc($result))
{
$fotos[] = array('src' => $data['src'], 'id' => $data['foto_ID']);
}
?>
<section id="upload">
<form method="post" action="upload.php" enctype="multipart/form-data">
<label for="bestand">Upload image:</label><br><br>
<input type="file" name="bestand" id="file"><br><br>
<label for="categorie"> Categorie: </label>
<input type="radio" name="cat" value="cat1">Portrait
<input type="radio" name="cat" value="cat2">Landscape
<input type="radio" name="cat" value="cat3">Other
<input type="submit" name="submit" value="Upload">
</form>
</section>
<?php
}
?>
<section class="images">
<?php
//show image thumbnails in photogallery
foreach($fotos as $foto)
{
?>
<img class="image" src="<?php echo 'upload/thumb/t_'.$foto['src'];?>">
<?php
}
?>
</section>
The above code I have 3 times (surrounded by HTML etc. as the photo gallery pages).
This is my Upload file (i'll leave most of the thumbnail making code out of it since it's only about the upload part).
$titel = "Image";
$dir='upload/';
$allowedExts = array("jpg", "jpeg", "gif", "png");
$answer= $_POST['cat'];
//Properties of the to be uploaded file
$fileName = $_FILES["bestand"]["name"]; //file name
$fileType = $_FILES["bestand"]["type"]; //file format
$fileSize = $_FILES["bestand"]["size"]; //file size
$tmpName = $_FILES["bestand"]["tmp_name"]; //temporary save location for file
$error = $_FILES["bestand"]["error"]; //error check for file
$fp = fopen($tmpName, 'r');
$content = fread($fp, filesize($tmpName));
$content = addslashes($content);
fclose($fp);
if(!get_magic_quotes_gpc())
{
$fileName = addslashes($fileName);
}
//select image from database and check if it already exists
$sql = "SELECT * FROM `i268296_studie`.`fotos` WHERE src = '$fileName'";
$result = mysqli_query($conn, $sql) or die("query error " . mysqli_error($conn) );
$data = mysqli_fetch_assoc($result);
$num_rows=mysqli_num_rows($result);
if($num_rows > 0)
{
echo 'File already exists <br>';
echo '<a href="fotogallerij.php">Return to homepage/a>';
}
else
{
// if file doesn't exist move to database, create thumbnail path
if (move_uploaded_file( $tmpName,$dir.$fileName))
{
function category($cat, $titel, $filename)
{
global $conn;
$query = "INSERT INTO `i268296_studie`.`$cat` (`titel`, `src`) VALUES ('$titel', '$fileName')"; //INSERT file into database
$result = mysqli_query($conn, $query) or die("query error " . mysqli_error($conn) );
}
$tname = 't_'.$fileName;
$tpath = $dir.'thumb/';
$tnamestate = $tpath.$tname;
$tptype = substr($fileType,6);
$ttype = "imagecreatefrom$tptype";
$name = $fileName;
$path = $dir;
$namestate = $path.$name;
$width = 100;
$height = 100;
list($width_orig, $height_orig) = getimagesize("$namestate");
$ratio_orig = $width_orig/$height_orig;
if ($width/$height > $ratio_orig)
{
$width = $height*$ratio_orig;
}
else
{
$height = $width/$ratio_orig;
}
How ever I am staring myself blind on how to fix it or where to place it so it works.
I hope my explanation and question is clear to you guys trying to help me, if not please let me know what I can change or do to help :)
edit:
The errors I am getting are:
Undefined variable: titel
Undefined variable: fileName
Undefined variable: conn
mysqli_query() expects parameter 1 to be mysqli, null given
When I do not pick a radio button but just upload it directly i just get 1 error:
Undefined index: cat
And it uploads it into the 3rd category
Edit 2:
Changed the function with the global $conn in it.
1 function category($cat, $titel, $fileName) {
2 global $conn;
3 $query = "INSERT INTO `i268296_studie`.`$cat` (`titel`, `src`) VALUES ('$titel', '$fileName')";
4 $result = mysqli_query($conn, $query) or die("query error " . mysqli_error($conn) );
5 }
1: you need these variables from the context calling the function
2: you need the global $conn variable in the function context to be able to run the query
3: use a function parameter for the table to upate call
4: it would be better to return results instead of breaking inside the function
The calling code would be like the following:
if ($answer == "cat1") {
category("fotos", $titel, $fileName); // or "foto2", $titel, $fileName .....
}
Please mind the comments about injection vulnerabilities.
Also read this: http://php.net/manual/it/language.variables.scope.php

Bypassing forms input fields to upload unwanted files

My website having uploading profile image section for members and i've used the following code.
Form Code
<form action="send.php" method="post" enctype="multipart/form-data" name="send" id="send">
Your Image : <input type="file" name="pic" id="pic"/>
<input type="Submit" name="Submit" value="Submit"/>
</form>
PHP Code send.php
$ImageName = $_FILES[pic][name];
if(!empty($ImageName) && $_FILES[pic][type] == "image/jpeg" || $_FILES[pic][type] == "image/png" || $_FILES[pic][type] == "image/gif" || $_FILES[pic][type] == "image/bmp"){
$t = time();
$NewImageName = "$t$ImageName"; // image new name
copy($_FILES[pic][tmp_name], "users/$NewImageName"); // copy it to directory
} else {
echo "no upload done";
}
But someone by using firefox extension manage to bypass it and uploaded php file
Who uploaded the file to my website sent me message said "you only check for type !"
and said " i used firefox extension that can fake input fields and passed PHP file ".
So my question how do i protect my image upload form of the above code ? ~ thanks
First I don't think that's is the valid format to read $_FILE variable
$ImageName = $_FILES[pic][name];
You should use
$ImageName = $_FILES['pic'][name];
Then I think it is improbable that someone can fake a server side check.
Try to hack this, I use a *PATHINFO_EXTENSION* as mentioned in PHP.net Manual
$validFormat = array("jpg","JPG","jpeg","JPEG","png","PNG","gif","GIF");
$path = pathinfo($_FILES['pic']['name'], PATHINFO_EXTENSION);
if(in_array($path, $validFormat)){
// it's okay
}else{
// Error
}
I'm working with this code since I discovered pathinfo a while ago and nobody hack it..
The "type" entries in the $_FILES array are indeed just values that the client sent. Do not trust them.
files are executed as php not based on the MIME type given by the client (or the MIME type that is recognized from their data), but simply by their extension.
$imageName = $_FILES['pic']['name'];
if (isset($imageName)) {
$ext = pathinfo($imageName, PATHINFO_EXTENSION);
if (in_array(strtolower($ext), array('jpg', 'jpeg', 'gif', 'png', 'bmp')) {
$t = time();
$newImageName = $t . basename($imageName);
copy($_FILES['pic']['tmp_name'], 'users/' . $newImageName);
}
} else {
echo 'no upload done';
}
Note the invocation to pathinfo to get the extension, and basename to avoid path traversal attacks.

Problem with PHP (works on localhost, but errors on web server)

am having some trouble with PHP on the webserver I am using.
I am sure the answer is obvious but for some reason it is eluding me completely.
I have a php file which uploads two files, a before and an after shot of the client.
The script on my server(localhost) works fine, it uploads the files, renames the files to a timestamp and puts the images into there folders for further sorting by another script.
Yet when I upload it to the webserver, and some files work (i.e mel.jpg, test.jpg) but files like IMG_0042.jpg do not work, Im sure the answer is something simple, but is completely eluding me.
Im thinking the underscore may have something to do with it, but cannot for the life of my figure it out, any help greatly appreciated,
thanks very much.
<?php
if(!isset($_COOKIE['auth'])) {
header("Location: login12.php");
exit();
}
$page_title="test";
include('header.html');
// Upload and Rename File
if (isset($_POST['submitted'])) {
$filenamebef = $_FILES["uploadbef"]["name"];
$filenameaft = $_FILES["uploadaft"]["name"];
$file_basename_bef = substr($filenamebef, 0, strripos($filenamebef, '.'));
$file_basename_aft = substr($filenameaft, 0, strripos($filenameaft, '.'));
// get file extention
$file_ext_bef = substr($filenamebef, strripos($filenamebef, '.'));
$file_ext_aft = substr($filenameaft, strripos($filenameaft, '.'));
// get file name
$filesize_bef = $_FILES["uploadbef"]["size"];
$filesize_aft = $_FILES["uploadaft"]["size"];
$allowed = array('image/pjpeg','image/jpeg','image/JPG','image/X-PNG','image/PNG','image /png','image/x-png');
if ((in_array($_FILES['uploadbef']['type'], $allowed)) && in_array($_FILES['uploadaft']['type'], $allowed)) {
if (($filesize_bef < 200000) && ($filesize_aft < 200000)){
// rename file
$date = date("mdy");
$time = date("His");
$timedate = $time . $date;
$newfilenamebef = $timedate . $file_ext_bef;
$newfilenameaft = $timedate . $file_ext_aft;
if ((file_exists("upload/images/before" . $newfilenamebef)) && (file_exists("uploads/images/after" . $newfilenameaft))) {
// file already exists error
echo "You have already uloaded this file.";
} else {
move_uploaded_file($_FILES["uploadbef"]["tmp_name"], "uploads/images/before/" . $newfilenamebef) && move_uploaded_file($_FILES["uploadaft"]["tmp_name"], "uploads/images/after/" . $newfilenameaft);
echo "File uploaded successfully.";
}
}
} elseif ((empty($file_basename_bef)) && (empty($file_basename_aft))) {
// file selection error
echo "Please select a file to upload.";
} elseif (($filesize_bef > 200000) && ($filesize_aft > 200000)) {
// file size error
echo "The file you are trying to upload is too large.";
} else {
// file type error
echo "Only these file typs are allowed for upload: " . implode(', ',$allowed);
unlink($_FILES["uploadbef"]["tmp_name"]);
unlink($_FILES["uploadaft"]["tmp_name"]);
}
}
echo $newfilenamebef;
echo $newfilenameaft;
?>
<form enctype="multipart/form-data" action="uploading.php" method="post">
<input type="hidden" value="MAX_FILE_SIZE" value="524288">
<fieldset>
<legend>Select a JPEG or PNG image of 512kb or smaller to be uploaded : </legend>
<p><b>Before</b> <input type="file" name="uploadbef" /></p>
<p><b>After</b> <input type="file" name="uploadaft" /></p>
</fieldset>
<div align="center"><input type="submit" name="submit" value="Submit" /></div>
<input type="hidden" name="submitted" value="TRUE" />
</form>
<?php
include('footer.html');
?>
You should but these two lines at the top of your index.php or bootstrap.php :
error_reporting( -1 );
ini_set( "display_errors" , 1 );
And see if some error messages turn up.
It is quite possible that problem is caused by wrong file permissions.
At a quick guess I would say that your localhost is not case sensitive, whereas your webserver is.
In other words, on your localhost IMG_12345.JPG is the same as img_12345.jpg. On your webserver, though, they are treated differently.
Without any actual reported errors, it's hard to be certain, but this is a common problem.
You're not checking for valid uploads properly. Something like the following would be FAR more reliable:
// this value is ALWAYS present and doesn't depend on form fields
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$errmsgs = array();
if ($_FILES['uploadbef']['error'] !== UPLOAD_ERR_OK) {
$errs++;
$errmsgs[] = "'uploadebef' failed with code #" . $_FILES['uploadebef']['error'];
}
if ($_FILES['uploadaft']['error'] === UPLOAD_ERR_OK) {
$errs++;
$errmsgs[] = "'uploadeaft' failed wicode #" . $_FILES['uploadeaft']['error'];
}
if (count($errmsgs) > 0) {
print_r($errmsgs);
die();
}
... process the files here ...
}
As well, why re-invent the wheel to split up the file names?
$parts = path_info($_FILES['uploadaft']['name']);
$basename = $parts['basename'];
$ext = $parts['extension'];

PHP code breaking HTML layout

I have a simple file uploader, which thanks to stackoverflow is now fully working, however when I copied the PHP code across to my main layout, once initialised to upload a file, but it is wrong format or size and it echos the error, it breaks the HTML below it. Im thinking its to do with the "exit;" after each echo? but could be wrong.
<?php
if($_POST['upload']) {
if($_FILES['image']['name'] == "")
{
#there's no file name return an error
echo "<br/><b>Please select a file to upload!\n</b>";
exit;
}
#we have a filename, continue
#directory to upload to
$uploads = '/home/habbonow/public_html/other/quacked/photos';
$usruploads = 'photos';
#allowed file types
$type_array = array(image_type_to_mime_type(IMAGETYPE_JPEG), image_type_to_mime_type(IMAGETYPE_GIF), image_type_to_mime_type(IMAGETYPE_PNG), 'image/pjpeg');
if(!in_array($_FILES['image']['type'], $type_array))
{
#the type of the file is not in the list we want to allow
echo "<br/><b>That file type is not allowed!\n</b>";
exit;
}
$max_filesize = 512000;
$max_filesize_kb = ($max_filesize / 1024);
if($_FILES['image']['size'] > $max_filesize)
{
#file is larger than the value of $max_filesize return an error
echo "<br/><b>Your file is too large, files may be up to ".$max_filesize_kb."kb\n</b>";
exit;
}
$imagesize = getimagesize($_FILES['image']['tmp_name']);
#get width
$imagewidth = $imagesize[0];
#get height
$imageheight = $imagesize[1];
#allowed dimensions
$maxwidth = 1024;
$maxheight = 1024;
if($imagewidth > $maxwidth || $imageheight > $maxheight)
{
#one or both of the image dimensions are larger than the allowed sizes return an error
echo "<br/><b>Your file is too large, files may be up to ".$maxwidth."px x ".$maxheight."px in size\n</b>";
exit;
}
move_uploaded_file($_FILES['image']['tmp_name'], $uploads.'/'.$_FILES['image']['name']) or die ("Couldn't upload ".$_FILES['image']['name']." \n");
echo "<br/>The URL to your photo is <b>" . $usruploads . "/" . $_FILES['image']['name'] . "</b>. Please use this when defining the gallery photos";
}
?>
<form name="uploader" method="post" action="" enctype="multipart/form-data">
<input type="file" name="image" style="width:300px;cursor:pointer" />
<input type="submit" name="upload" value="Upload Image" />
</form>
Indeed, when you call exit; it means "immediately stop all processing; this script is finished." Anything that comes after it — including HTML — will not be interpreted.
A better organization would be to make this code a function, to the effect of:
function uploadMyStuffPlease() {
if($_POST['upload']) {
if($_FILES['image']['name'] == "")
{
#there's no file name return an error
echo "<br/><b>Please select a file to upload!\n</b>";
return;
}
#we have a filename, continue
// ....
}
Now you can simply call uploadMyStuffPlease(), which will do as much processing as it can, and perhaps return early in the event of an error. Either way, the function will return, and so the rest of your script (including that HTML) can still be interpreted.
If you call exit; your PHP script won't be able to output anything anymore. That's why the layout is broken.
You should maybe try to keep the HTML parts out of your PHP code and especially avoid opening tags that you don't close afterwards (i.e. divs or anything).
That being said, it's probably safest to just put everything into a function that won't exit the script when finished (see other's posts).
if(isset($_POST['upload'])){
OR
if(!empty($_POST['upload'])){
And remove exit...

Categories