PHP File Upload Failing - php

For some reason my PDF upload form is failing consistently, I have this code:
<?php
if($_POST["submit"] == "Add PDF to Comm and Special Projects")
{
$addsubp = $_POST["addsubp"];
$addsubp_name = $_POST["addsubp_name"];
$commuploadedfile = $_FILES['uploadedfile']['name'];
$sqldoc = "INSERT INTO projects_links (pid, display_name, link) VALUES ('".$addsubp."','".$addsubp_name."','".$commuploadedfile."')";
mysql_query($sqldoc) or die(mysql_error());
echo "<BR>";
$target_path = "D:\\Hosting\\69903\\html\\pdfs\\comm\\";
$target_path = $target_path . basename( $_FILES['uploadedfile']['name']);
if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {
echo "<br>The file ". basename( $_FILES['uploadedfile']['name']).
" has been uploaded<br>";
} else{
echo "<br>There was an error uploading the file, please try again.<br>";
}
}
?>
<form method="post">
Add PDF to Project for Committees and Special Projects <br>Choose Project<select name="addsubp"><?php
$query = "SELECT
projects.*
FROM
projects";
$showresult = mysql_query($query);
$csp_c = 1;
while($buyarray = mysql_fetch_assoc($showresult))
{
echo "<option value=".$buyarray['id'].">".$buyarray["pname"]."</option>";
}
?></select><br>
Choose Display Name for PDF <input type="text" name="addsubp_name" /> <Br>
Choose PDF: <input name="uploadedfile" type="file" /> <Br>
<input type="submit" value="Add PDF to Comm and Special Projects" name="submit" />
</form>
I have made sure that the application has write privileges to the "comm" directory. I have godaddy and used the file manager to make sure of that. I have had problems with permissions in this project before, so I know this isn't case. It keeps printing
There was an error uploading the file, please try again.
It doesn't attempt to upload any PDF at all, what am I doing wrong?
thanks!

You may have permissions issues, but for file uploads your form tag should contain the proper enctype attribute.
<form enctype="multipart/form-data" method="POST">
and defining a file size limit is also a good idea:
<input type="hidden" name="MAX_FILE_SIZE" value="1000000" />

try checking the Upload error message: http://php.net/manual/en/features.file-upload.errors.php

Your code is blindly assuming the file upload succeeded. At bare minimum you should have something like
if ($_FILES['uploadedfile']['error'] === UPLOAD_ERR_OK) {
... handle the upload
}
Your code is vulnerable to SQL injection. You do not escape any of the 3 values you're inserting into the database
You're creating the database record before making sure the file was successfully moved into the target directory. What happens if the file can't be written for any reason (as it is now with your problem)? The database will say it's there, file system will say it isn't
You're not checking for file collisions. If two seperate uploads send "file.txt", the second upload will overwrite the first one.
You're storing the files with the user-supplied name, which is under user control. If this file is web-accessible, anyone with access to your upload form can upload anything they want (e.g. a php file) and the server will happily execute it for them.

Related

can't copy uploaded file (php)

I'm creating a site that displays news uploaded on it's admin panel.
Each post has an image and a title (and description, but i haven't implemented it yet).
My problem is, that when i try to post (and upload image with it) the post is created, but the image doesn't exist.
uploader (php):
if (isset($_FILES['image'])) {
//this script
//connects to mysql database
//declares an array that contains table names (array name is db)
require_once("db.php");
//move file to the img folder
move_uploaded_file($_FILES['image']['tmp_name'], "img/" . $_FILES['image']['tmp_name']);
//upload the post to the database
$sql = "INSERT INTO `{$db["posts"]}` (`img`, `text`) VALUES ('img/{$_FILES['image']['tmp_name']}', '{$_POST["text"]}')";
if (!mysql_query($sql)) {
//display error message
}
}
form (html):
<form action="post.php" method="POST" enctype="multipart/form-data">
<label>Image: </label><input type="file" name="image" />
<br />
<label>Text: </label><input type="text" name="text" />
<input type="submit" />
</form>
I check the files via ftp after posting, the image doesn't exist.
$_FILES['image']['tmp_name'] is an absolute pathname like /var/tmp/something. When you concatenate it to img/, you get a pathname that points into a subdirectory, img//var/tmp/something. Since the subdirectory doesn't exist, move_uploaded_file() fails.
You should use basename() to get just the filename portion.
$filename = 'img/' . basename($_FILES['image']['tmp_name']);
move_uploaded_file($_FILES['image']['tmp_name'], $filename);
$text = mysql_real_escape_string($_POST['text']);
$sql = "INSERT INTO `{$db["posts"]}` (`img`, `text`) VALUES ('$filename', '$text')";
I'm not really sure how safe using the name of the temp file this way is, though. I don't think there's any guarantee that it will never repeat the same name for different uploads.

Store path to uploaded Image in database

I'm trying to add a path of an uploaded image to the database in order to use it to display it as a thumbnail for a post. I found a tutorial and I used this code to upload the image. However it gets to the else statement and I just get the exit("Error While uploading image on the server"); I have a form to collect the data:
<form action='' method='post' enctype="multipart/form-data">
<p><label>Title</label><br />
<input id="title-input" type='text' name='postTitle' value='<?php if(isset($error)){ echo $_POST['postTitle'];}?>'></p>
<p><label>Description</label><br />
<textarea id="textarea" name='postDesc' cols='20' rows='5'><?php if(isset($error)){ echo $_POST['postDesc'];}?></textarea></p>
<p><label>Content</label><br />
<textarea name='postCont' cols='20' rows='5'><?php if(isset($error)){ echo $_POST['postCont'];}?></textarea></p>
<p><label>Image</label><input type="file" name="uploadedimage">
</p>
<input type='submit' name='submit' value='Submit'>
<input type='reset' name='submit' value='Reset'>
</form>
<?php include 'add-post-handler.php' ?>
And here is the code I used to upload the image:
function GetImageExtension($imagetype)
{
if(empty($imagetype)) return false;
switch($imagetype)
{
case 'image/bmp': return '.bmp';
case 'image/gif': return '.gif';
case 'image/jpeg': return '.jpg';
case 'image/png': return '.png';
default: return false;
}
}
if (!empty($_FILES["uploadedimage"]["name"])) {
$file_name=$_FILES["uploadedimage"]["name"];
$temp_name=$_FILES["uploadedimage"]["tmp_name"];
$imgtype=$_FILES["uploadedimage"]["type"];
$ext= GetImageExtension($imgtype);
$imagename=$_FILES["uploadedimage"]["name"];
$target_path = "../img/".$imagename;
if(move_uploaded_file($temp_name, $target_path)) {
$query_upload="INSERT INTO blog_images (imgPath) VALUES
('$target_path')";
mysqli_query($link, $query_upload) or die("error in $query_upload == ----> ".mysql_error());
}else{
exit("Error While uploading image on the server");
}
}
PS: I also have some doubts on how can I get the imageID to be related with the postID considering that are both submitted from the same form.(I made a relation between the two tables but it's on the primary keys so I'm not sure if it's correct)
Thanks for your help!
Looking at the Code:
move_uploaded_file returns FALSE on two premises (stated in the PHP Docs):
If filename is not a valid upload file, then no action will occur, and
move_uploaded_file() will return FALSE.
If filename is a valid upload file, but cannot be moved for some
reason, no action will occur, and move_uploaded_file() will return
FALSE. Additionally, a warning will be issued.
My best guess is, with the information you provided:
Your path is not writeable by your application/webserver, so it won't be moved
Make sure the application (the webserver) can write in your path: '../img/' by issuing a chmod to give the directory the correct rights for the webserver user.
Security Advice (not related to question):
Your application has in this state a potential SQLi in $target_path. You should think about using prepared statements
https://dev.mysql.com/doc/apis-php/en/apis-php-mysqli.quickstart.prepared-statements.html
Your form writes POST Data directly to output. This leads to XSS. You should always encode special characters in your output.
https://www.owasp.org/index.php/Cross-site_Scripting_%28XSS%29
Make sure, only images can be uploaded and scripts can't be executed in this '../img' path. Somebody could exploit your upload to upload a script and execute it.
easiest way to prevent SQLi in this case would be hashing the imagename and setting the extension with the $ext variable:
[...]
$ext=GetImageExtension($imgtype);
if($ext === FALSE) {
exit("Couldn't determine the filetype correctly. Please upload pictures only.");
}
$imagename=md5($_FILES["uploadedimage"]["name"].time()).$ext;
$target_path = "../img/".$imagename;
[...]
The time() is only included, so somebody can upload pictures with the same name.
you could always give your images a specific class that you know directs to all images you want to thumbnail and apply a CSS rule/code that will automatically make them img-thumbnail.
<div class="imgT">
then set your CSS thumbnail
Thanks everyone for answering. In the end I got it. I found that the problem was with the php.ini settings. This is the link that helped me -> Why would $_FILES be empty when uploading files to PHP?. Thanks PaulF for posting it. The problem was that the limit for uploading files was just 2MB or something like that.
For everyone having the same issues make sure you check that link and check this settings in your php.ini file.
file_uploads = On
post_max_size = 100M
upload_max_filesize = 100M

PHP Image Upload Script Not Uploading But Not Failing

I am trying to enter some data into a database and upload an image to a specific directory. I am using the following script which is a modified version of the top voted answer to this question: How to store file name in database, with other info while uploading image to server using PHP?
require($_SERVER['DOCUMENT_ROOT']."/settings/functions.php");
// This is the directory where images will be saved
$target = $_SERVER['DOCUMENT_ROOT']."/safetyarticles/images/";
$target = $target . basename( $_FILES['article_img']['name']);
date_default_timezone_set("America/Chicago");
// This gets all the other information from the form
$article_name = $_POST['article_title'];
$article_date = date("m/d/Y");
$article_creator = $_POST['article_creator'];
$article_views = "0";
$article_content = $_POST['article_content'];
$article_content_2 = $_POST['article_content_2'];
$article_img = ($_FILES['article_img']['name']);
$article_credit = $_POST['article_credit'];
// Connect to database
$conn = getConnected("safetyArticles");
// moves the image
if(move_uploaded_file($_FILES['article_img']['tmp_name'], $target))
{
// if upload is a success query data into db
mysqli_query($conn, "INSERT INTO currentArticles (article_name, article_date, article_creator, article_content, article_content_2, article_img, article_credit)
VALUES ('$article_name', '$article_date', '$article_creator', '$article_views', '$article_content', '$article_content_2', '$article_img', '$article_credit')") ;
echo "The file ". basename( $_FILES['article_img']['name']). " has been uploaded, and your information has been added to the directory";
}
else {
echo "Sorry, there was a problem uploading your file.";
}
I have successfully connected to my database since my getConnected() function contains error handling for if the connection fails.
For some reason I keep getting the Sorry, there was a problem uploading your file. error from the bottom of the script.
Am I missing something? All I did was change some minor lines here and there such as how the database connects, and the variables. I also moved the query to only happen if the file uploads.
I'm not sure what I'm missing.
Is it also possible to modify this current script to rename the image to whatever the value of $article_name is? For example if the article name is "This Is The First Article" then the image would be this-is-the-first-article.jpg?
My HTML form is:
<form method="post" action="http://example.com/admin/articleCreate.php" enctype='multipart/form-data'>
<input type="text" name="article_title" placeholder="What Is The Name Of This Article?" id="article_title_input">
<textarea name="article_content" placeholder="Write The Top Half Of Your Article Here." id="article_content_input"></textarea>
<input type="file" name="article_img" placeholder="If The Article Has An Image, Upload It Here." id="article_img_input">
<textarea name="article_content_2" placeholder="Write The Bottom Half Of Your Article Here." id="article_content_2_input"></textarea>
<input type="text" name="article_creator" placeholder="Who Is Writing This Article?" id="article_creator_input">
<input type="text" name="article_credit" placeholder="If This Article Is Copied, What Website Was It Taken From?" id="article_credit_input">
<input type="submit" value="Submit">
</form>
And I did var_dump(is_uploaded_file($_FILES['article_img']['tmp_name'])); and it's returnign true.
Sidenote edit: This being before you edited your question with only one of them being renamed. https://stackoverflow.com/revisions/36367407/4
$_FILES['photo']
$_FILES['uploadedfile']
are two different file arrays and you're using name="article_img" as the name attribute.
You need to use the same one for all of them.
Error reporting http://php.net/manual/en/function.error-reporting.php would have told you about it.
Add error reporting to the top of your file(s) which will help find errors.
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
// Then the rest of your code
Sidenote: Displaying errors should only be done in staging, and never production.
Additional edit:
$target = $target . basename( $_FILES['photo']['name']);
if that's your real edit, still the wrong array name.
I think the problem is in this line:
if(move_uploaded_file($_FILES['photo']['tmp_name'], $target))
Change it to this:
if(move_uploaded_file($_FILES['article_img']['tmp_name'], $target))
Your html has:
<input type="file" name="article_img" placeholder="If The Article Has An Image, Upload It Here." id="article_img_input">
And your php is waiting for $_FILES['photo']['tmp_name']
Change your html file input to:
<input type="file" name="photo" placeholder="If The Article Has An Image, Upload It Here." id="article_img_input">

PHP move_uploaded_file function very picky

I having trouble with the move_uploaded_file function on my website.
The whole idea is that in a form, i insert the title, description and a screenshot of a project. Everything is working just fine. It saves the title and description with an id and the creation date in a mysql database and moves the file to a folder on the server.
The problem however is that some files are transferred to folder and some aren't. The problem seems to be in the files, but i can't seem to figure out what the problem is.
It is not the filesize; i have files of 5/6MB that are placed in the folder without any problems, and i have files that are around 3MB that arent. The extension isn't the problem either, they are both .jpg.
Are there any other requirements that a .jpg file should meet, in order to be uploaded?
I'm 99% certain the problem isn't in my code, as it uploads some files without a problem, but here is my code anyway.
The HTML part:
<form action="" method="post" enctype="multipart/form-data">
<h2>Title*</h2>
<input type="text" id="title" name="title">
<h2>Description*</h2>
<textarea id="descr" name="descr" cols="40" rows="4"></textarea>
<h2>Add file*</h2>
<input type="file" id="file" name="file">
<h2><input type="submit" id="submit" name="submit" value="Uploaden"></h2>
<p id="requirements">Fields marked with * are required.</p>
</form>
And this is the PHP part:
if (isset($_POST['submit'])) {
$destination = "../uploadedfiles/" . basename($_FILES['file']['name']);
if (move_uploaded_file($_FILES['file']['tmp_name'], $destination)) {
echo '<p id="succes">File has been uploaded</p>';
} else {
echo '<p id="error">File has not been uploaded</p>';
}
$title = $_POST['title'];
$descr = $_POST['descr'];
$name = ($_FILES['file']['name']);
include "../connect/connect.php";
if ($title == "" || $descr == "") {
echo '<p id="error">Fill in the required fields</p>';
} else {
$query = "INSERT INTO file(title, descr, name, created) VALUES ('{$title}', '{$descr}', '{$name}', NOW())";
$upload = $connect->query($query);
if ($upload) {
echo '<p id="succes">Info is stored in database</p>';
} else {
echo '<p id=error>Failed to store info in database</p>';
}
}
}
A bunch of stuff might be going wrong. move_uploaded_file is very pick and sometimes doesn't behave how it is documented. I had problems with it once and honestly, copy archive the same result in most cases if properly implemented.
There are reports of lone filenames causing trouble. 249 chars on $destination seems to be the limit.
not only upload_max_filesize must be set but also post_max_size
utf-8 names might be a problem
If you have problems where the uploaded file seems unaccessible, try to use copy() instead. There are reports of people not being able to find the file just after upload, move_uploaded_file just limits path over copy, the results are the same if you dont input any user var.

Javascript and PHP upload system

Thanks in advance for any help, I hope my explanation of my request is understandable.
I have a website where I upload various HTML pages with scripts, websites etc. that I have found useful over time... For the purpose of 1) a reference for myself, and 2) to share what I've found with others.
The website consists of 2 sections. A search page to find the script, and an admin page to upload it. The uploaded HTML file gets placed in a "docs/" directory on my server, and the details are added to a MySQL database for the search page.
The form looks like this:
<form name="upload" enctype="multipart/form-data" action="includes/add.php"
method="post" onsubmit="return validateForm();">
<label for="scriptname">Script Name</label><input class="inputarea" type="text"
name="scriptname"><br>
<label for="category">Category</label><input class="inputarea" type="text"
name="category"><br>
<label for="keywords">Keywords</label><input class="inputarea" type="text"
name="keywords"><br>
<label for="content">HTML File</label><input class="inputarea" type="file"
name="content"><br>
<input class="submit" type="submit" value="Add">
</form>
My question is this... Is there any way with JavaScript or PHP to do the following:
generate an automatic file name for the uploaded file (a few random digits would do)
In the "scriptname" input field, add text on submit so that it makes the Script name and file name into a hyperlink that's added to the database as text... eg. When submit button is pressed, the following is added to the database:
"scriptname_input"
Where the bold section is taken from the generated file name and the italic section is from the input field...
The purpose of this is so that in the search results, when the database column with the script name comes up, the script name is a link to the actual file. I have the search feature ready, and it is able to make a link from a database entry, but I just need to simplify the upload process.
If this is not possible, is there a different way to achieve this?
---EDIT---
Thank you all for your help! Much appreciated, I've worked it out using a combination of a few of the suggestions. However, I gave the credit to Ibere as his solution was the closest.
Here is the final code I used for the 'add.php' file that processed the upload and database addition, just in case it ever comes up again (I doubt it) :P
<?php
$filename = md5($_FILES['content']['name']);
$labelForUrl = $_POST['scriptname'];
$url = "$labelForUrl";
$target = "../docs/";
//This gets all the other information from the form
$name=$_POST['scriptname'];
$cat=$_POST['category'];
$key=$_POST['keywords'];
$link=$_POST['link'];
$file=($_FILES['content']['scriptname']);
// Connects to your Database
mysql_connect("localhost", "username", "password") or
die(mysql_error()) ;
mysql_select_db("scripts") or die(mysql_error()) ;
//Writes the information to the database
mysql_query("INSERT INTO scripttable (scriptname,category,keywords,link,content)
VALUES ('$url', '$cat', '$key', '$link', '$file')") ;
if(move_uploaded_file($_FILES['content']['tmp_name'], $target . $filename)) {
echo "The file ". $labelForUrl.
" has been uploaded";
}
else {
echo "There was an error uploading the file, please try again!";
}
?>
You can do something like this for the filename.
$filename = md5($_FILES['content']['name']);
$labelForUrl = $_POST['scriptname'];
md5 is not Random, but is good enough for generating a unreadable string for a filename.
Then you can create a url like this
<a href="docs/<?php echo $filename; ?>" ><?php echo $labelForUrl; ?></a>
Hope this helps.
EDIT: I forgot to add the extension to the filname. So the right code would be something like:
$filename = md5($_FILES['content']['name']).$_FILES['content']['type']
I recommend using uploadify for uploads. But, to do what you asked:
$randomFileName = rand(1000, 9999);
if (file_exists("upload/" . $_FILES["file"]["name"]))
{
echo $_FILES["file"]["name"] . " already exists. ";
}
else
{
move_uploaded_file($_FILES["file"]["tmp_name"],
"upload/" . $randomFileName . $_FILES["file"]["type"]);
// update your db with the location
$loc = "upload/" . $randomFileName . $_FILES["file"]["type"];
mysqli_query("insert into `myTable` (`loc`) values ('$loc')");
echo "Stored in: " . "upload/" . $_FILES["file"]["name"];
}
}
For file uploading help, look at http://www.w3schools.com/php/php_file_upload.asp
This is very easy, if you know codeigniter ( PHP Framework ).
You can use the Upload Class
You can easily create forms and submit them and also display them.
I would do it that way. If you are familiar with MVC you can do that in 10-15 mins.
To generate random file names, I usually find this does the work quite well: md5( rand( 0, 100000 ) );. If you wish to limit the size of the file name, you may use the substr function.
(Assuming a MySQL database), make the connection and then query the database using the INSERT command. This link shows how to do all of this.

Categories