I'm trying to add a file upload script in php to a website I'm designing. I've used an online example (I know it's not secure and I plan on making it secure, I just want the basic functionality working first).
Basically what's happening is that when I click the "submit" button, the page stalls and says "loading xyz server.." forever and doesn't ever go to the post action php page! This is very frustrating and I can't see why it won't work!
The code is below and I've tried this on 2 different servers with same results. I'd be very grateful if someone could let me know what I'm possibly doing wrong?
<html>
<body>
<form enctype="multipart/form-data" action="do.php" method="post">
<input type="hidden" name="MAX_FILE_SIZE" value="1000000" />
Choose a file to upload: <input name="uploaded_file" type="file" />
<input type="submit" value="Upload" />
</form>
</body>
</html>
<?php
//Сheck that we have a file
if((!empty($_FILES["uploaded_file"])) && ($_FILES['uploaded_file']['error'] == 0)) {
//Check if the file is JPEG image and it's size is less than 350Kb
$filename = basename($_FILES['uploaded_file']['name']);
$ext = substr($filename, strrpos($filename, '.') + 1);
if (($ext == "jpg") && ($_FILES["uploaded_file"]["type"] == "image/jpeg") &&
($_FILES["uploaded_file"]["size"] < 350000)) {
//Determine the path to which we want to save this file
$newname = dirname(__FILE__).'/upload/'.$filename;
//Check if the file with the same name is already exists on the server
if (!file_exists($newname)) {
//Attempt to move the uploaded file to it's new place
if ((move_uploaded_file($_FILES['uploaded_file']['tmp_name'],$newname))) {
echo "It's done! The file has been saved as: ".$newname;
} else {
echo "Error: A problem occurred during file upload!";
}
} else {
echo "Error: File ".$_FILES["uploaded_file"]["name"]." already exists";
}
} else {
echo "Error: Only .jpg images under 350Kb are accepted for upload";
}
} else {
echo "Error: No file uploaded";
}
?>
Thanks very much for your time, I have searched for hours to fix this with no luck!
If you post to an Iframe it won't lock your page. Then watch the Iframe contents to see what the server response is, or better: use Firebug on Firefox and inspect he NET tab to see what's going on with your post request.
How big of a file are you uploading? Most browsers do not display any kind of upload progress bar, and only recently has PHP supported even bare bones progress reports. For a large file, all you'd see is the "... loading ..." status bar text with no indication that data's actually being uploaded.
As for the rest of the code, here's a few things you need to clean up before putting this into production:
$_FILES['uploaded_file']['error'] == 0
This will evaluate to true if the ['error'] element isn't set. Use === instead, which does forces value and type to be equal, not merely value.
if (($ext == "jpg") && ($_FILES["uploaded_file"]["type"] == "image/jpeg") &&
The filename and filetype values in the $_FILES array are what's supplied by the remote user, and can be easily mainipulated. Best to use a server-side mime-type identifer (getimagesize() for pictures works well) to see what the file really is.
Nevermind! It turns out it was something to do with the wireless network at my University. I got home, refreshed the page and it worked fine. I will have to have words with the system administrator about the time I wasted trying to solve a problem made by them.
Thanks for the help anyway guys,
Scott
Related
I am trying to upload files to server using PHP.
I created a simple file input and a submit button and wrote the PHP function to handle that request.
Initially I tried using this library https://github.com/Gargron/fileupload which worked fine, but I thought I might be missing something so I wrote the php code myself.
It is uploading small files instantly. By small I mean maximum 1Mb.
I am looking to upload files up to 2-3GB or maybe bigger.
So I tried an 150Mb file which transferred nearly instantly as I have a very high uplink bandwidth, so it took few seconds to transfer it, but it never never arrived on the server, I haave no idea why, when I am tried with small files, they go directly on the server folder instantly.
I tried with a 25Mb file and the browser showed that the upload is 100% in less than 5 seconds, but then it took 4 minutes for the file to get on the destination folder on the server.
I am using Ubuntu 20.04 LTS, Apache2, PHP v7.3.20.
I checked PHP ini and I increased post_max_size and upload_max_filesize as per my requirements, so I am not sure what I am missing.
HTML Form
<form action="pages/upload-video" enctype="multipart/form-data" method="post" accept-charset="utf-8">
<input type="file" name="fileToUpload">
<br><br>
<input type="submit" value="upload">
</form>
PHP function
public function upload_video() {
$target_dir = VIDEO_PATH;
$target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
$uploadOk = 1;
$imageFileType = strtolower(pathinfo($target_file, PATHINFO_EXTENSION));
if ($uploadOk == 0) {
echo "Sorry, your file was not uploaded.";
} else {
if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {
echo "The file " . basename($_FILES["fileToUpload"]["name"]) . " has been uploaded.";
} else {
echo "Sorry, there was an error uploading your file.";
}
}
}
Next I tried to leave only
public function upload_video() {
print_r($_FILES['fileToUpload']);
}
And it takes so much time to execute the function. Not sure whats going on here. Never experienced this before.
This is my first post on Stack Overflow so please be patient with me - I've resorted to posting because I can't find an answer via Google/Stack Overflow otherwise.
I'm new to PHP and learning how to add file uploads. I have a very basic html form that leads to a PHP page.
<form action="UploadPage.php" method="post" enctype="multipart/form-data">
<input type="hidden" name="MAX_FILE_SIZE" value="100000"/>
<input type="file" name="uploadedXML"/>
<input type="submit" value="Upload"/>
The PHP code which processes the file upload has a series of if statements to check whether file is the right type size etc. If there is an error, an appropriate error message is generated on an error page.
I've been testing uploading various file types to ascertain whether the error statements are occurring properly and I'm having trouble with the second (check for file type) and third (check for file size).
If the file type check if statement comes first, I'm finding that if I upload an XML file bigger than the max size (100kb) I still get the error message pertaining to the file type check - when I should be getting the error message pertaining to the file size.
However if i swap the IF statements around so the file size check comes before the file type check, if i upload the incorrect file type but of an agreeable size (eg a small image) I get an error message pertaining to the file being too big, when I'm expecting one pertaining to the file type being incorrect.
<?php
const UploadKey = 'uploadedXML';
const AllowedTypes = ['application/xml','text/xml'];
session_start();
/*Checking for errors*/
if (empty($_FILES[UploadKey]['name'])){//check file actually been uploaded
header("Location: ErrorPage.php");
$_SESSION['errorMessage']="You forgot to add your file!";
die();
}
if (!in_array($_FILES[UploadKey]['type'],AllowedTypes)){//Check correct type of file
header("Location: ErrorPage.php");
$_SESSION['errorMessage']="We only accept XML files I'm afraid";
die();
}
if ($_FILES[UploadKey]['error'] == 2) {//Check if size too big
header("Location: ErrorPage.php");
$_SESSION['errorMessage']="Your file is too big for us to handle, awkward! Please choose a file under 100KB.";
die();
}
$tempFileLoc = $_FILES[UploadKey]['tmp_name'];
$destFileLoc = 'Uploads/'.$_FILES[UploadKey]['name'];
if (file_exists($destFileLoc)) {// Check if file already exists
header("Location: ErrorPage.php");
$_SESSION['errorMessage']="We've already got this file, thanks though";
die();
}
if ($_FILES[UploadKey]['error']>0){
header("Location: ErrorPage.php");
$_SESSION['errorMessage']="Unfortunately there's been an error with the uploading process";
die();
}
Please let me know if you need to see any more of my code to help in answering.
Thanks very much in advance!
Best practice is to build up an error array and if its empty continue to your next step or if not return the errors. You could try something like this. In your code you were overwriting error messages so you only saw the last to apply and not all of the messages that upload may have triggered.
<?php
const UploadKey = 'uploadedXML';
const AllowedTypes = ['application/xml','text/xml'];
$errors = array();
session_start();
/*Checking for errors*/
if (empty($_FILES[UploadKey]['name'])){//check file actually been uploaded
$errors[] = "You forgot to add your file!";
}
if (!in_array($_FILES[UploadKey]['type'],AllowedTypes)){//Check correct type of file
$errors[] ="We only accept XML files I'm afraid";
}
if ($_FILES[UploadKey]['error'] == 2) {//Check if size too big
$errors[] ="Your file is too big for us to handle, awkward! Please choose a file under 100KB.";
}
$tempFileLoc = $_FILES[UploadKey]['tmp_name'];
$destFileLoc = 'Uploads/'.$_FILES[UploadKey]['name'];
if (file_exists($destFileLoc)) {// Check if file already exists
$errors[] ="We've already got this file, thanks though";
}
if ($_FILES[UploadKey]['error'] > 0){
$errors[] = "Unfortunately there's been an error with the uploading process";
}
//if errors were found
if(!empty($error)){
header("Location: ErrorPage.php");
//beware this is now an array and not a single string
$_SESSION['errorMessage']= $errors;
die();
}
That issue was caused as a result of the MAX_FILE_SIZE you included in the HTML form.
If the file you are uploading exceeds the MAX_FILE_SIZE set in the form, PHP automatically empties the tmp_name and type and also turns size to 0 for the file ($_FILES).
So $_FILES[UploadKey]['type'] is empty, thereby the condition you are using to check whether the file type is allowed will return false.
To correct that, you should also check to make sure the type is not empty as well
if (!empty($_FILES[UploadKey]['type']) && !in_array($_FILES[UploadKey]['type'],AllowedTypes)
Something like this:
<?php
if (!empty($_FILES[UploadKey]['type']) && !in_array($_FILES[UploadKey]['type'],AllowedTypes)){// Make sure the file type is not empty
header("Location: ErrorPage.php");
$_SESSION['errorMessage']="We only accept XML files I'm afraid";
die();
}
I'm following a tutorial for uploading image files using php on udemy. I can choose an image and upload it to a folder without any problems.
When I click on the image after it has been uploaded to the folder, windows photo viewer says: "photo.png It appears that you don't have permission to view this file. Check the permissions and try again".
When I checked permissions it said "You must have read permissions to view the properties of this file".
I used the chmod function set to 0755, which allows the owner to read and write, and lets everyone else read it. I tried changing the chmod codes but it didn't help.
I'm thinking it has something to do with my server permissions, but can't find any solution on google. My images are uploaded to Abyss Web Server.
Here is the code:
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
function upload_file() {
//setup
$tmp_name = $_FILES['file']['tmp_name'];
$target_dir = 'uploads/';
$target_file = $target_dir . basename($_FILES['file']['name']);
$max_file_size = 5000000; //5mb
$allowed_file_types = array('application/pdf; charset=binary');
$allowed_image_types = array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG);
//check if image type is allowed
$image_check = getimagesize($tmp_name);
if(! in_array($image_check[2], $allowed_image_types)) {
//if not allowed image check if allowed file type
exec('file -bi' . $tmp_name, $file_check);
if(! in_array($file_check[0], $allowed_file_types)) {
return 'This file type is not allowed';
}
}
//check if file already exists
if(file_exists($target_file)) {
return 'Sorry that file already exists';
}
//check file size
if(file_exists($target_file)) {
return 'Sorry this file is too big';
}
//store the file
if(move_uploaded_file($tmp_name, $target_file)) {
chmod($target_file, 0644);
return 'Your file was uploaded';
}
else {
return 'There was a problem storing your file. Try again?';
}
}
if(! empty($_FILES)) {
echo upload_file();
}
?>
<form action="" method="post" enctype="multipart/form-data">
Select image to upload:
<input type="file" name="file">
<input type="submit" Value="upload">
</form>
Since loading the file using a custom made HTML page specifically for testing motives does show the image correctly, then it's most likely a hotlink protection issue. (This was found out after a few comments to the question).
In cPanel, for example, there is a tool to manage this feature and it revolves around the usage of a file called .htaccess. This file is used for a lot of things in the web development world.
Some people don't like their copyrighted images to be accessed, so one way to avoid inexperienced people (let's say, "people in userland") from doing that is to enable this protection. This works for any given file extension that you set it up to.
One way to address this issue is to go to cPanel and disable (or modify accordingly) the Hotlink Protection feature. Another way, is to find the .htaccess file that is causing the issue, which requires understanding the way it works and the syntax it uses.
I want users to be able to upload a profile picture (which can be .jpg or .png) and I also want this to be displayed on their profile. I have written some code, based on sources I found here, on Stackoverflow and Google. However, it does not seem to work and I can't find my mistake.
This is the html
<form action="account_settings.php" method="POST">
<input type="file" name="profilePicture"><br><br>
<input type="submit" value="Change!">
</form>
This is how to uploaded file will be processed.
<?php
include ('inc/header.inc.php');
if(isset($_FILES["profilePicture"]["tmp_name"]) && isset($_FILES["profilePicture"]["name"])) {
$ext = pathinfo($_FILES['profilePicture']['name'], PATHINFO_EXTENSION);
$name = $_SESSION['user_login'];
$tmp_name = $_FILES["profilePicture"]["tmp_name"];
if($ext == 'png' || $ext == 'jpg') {
if (isset($tmp_name)) {
if(!empty($tmp_name)) {
$location = '../profielfotos/';
$full_name = $name.'.'.$ext;
if(move_uploaded_file($tmp_name, $location.$full_name)) {
echo 'Photo uploaded!';
}
Down here are just some else statements with error reports.
The code below is used to display the image. I have tested it by putting an image in the profile pictures folder and it did display the image. However, there is still a problem. People are allowed to upload .jpg or .png, how can I make the website display the picture (find the profile picture with the right extension).
I have put this code inside the src attribute of the <img>tag.
<?php if ($handle = opendir('profielfotos/')) {
$file = mysql_real_escape_string($_GET['u']);
echo 'profielfotos/'.$file.'.png';
}
closedir($handle);
I hope someone can help, thanks in advance!
ps. this is my first post ever on stack overflow :-D!
Since you are not storing any info about the file uploaded, you just have check which file exists, using he file_exists() method. See here:
http://php.net/manual/en/function.file-exists.php
So your code will become something like this (Not tested):
<?php if ($handle = opendir('profielfotos/')) {
$file = mysql_real_escape_string($_GET['u']);
if (file_exists('profielfotos/'.$file.'.png')) {
echo 'profielfotos/'.$file.'.png';
} else if (file_exists('profielfotos/'.$file.'.jpg')) {
echo 'profielfotos/'.$file.'.jpg';
}
}
closedir($handle);
You need to add the following to your form:
<form action="account_settings.php" method="POST" enctype="multipart/form-data">
Otherwise it won't allow a file upload as it expects only text.
This is totally insecure. Files uploaded by a user shall never ever be stored within the root of the web server.
Instead, put the files somewhere outside of the doc root.
Write a handler, which takes control of he files
check the mime type by checking the content, not the extension
have arbitrary names, not the name from the upload, that might interfer (imagine 5 people uploading a "profile.png")
let the handler deliver the image by an id ("...imagloader?file=4711"),
name of the file (and extension and location) is stored in a database (with the user record?)
i am having trouble checking the file type of flv files with php. Here's my code
if($_FILES["file"]["type"] == "video/x-flv")
{ echo "true"; }
else{ echo "false"; }
But my problem is that its getting into the else statements when i upload a flv... I'm unable to figure out the problem.. Please help..
EDITED->
Having the same problem for
($_FILES["file"]["type"] == "application/x-shockwave-flash")
as well.. while it works fine for images..
Use finfo_file();
Try
$finfo = finfo_open(FILEINFO_MIME_TYPE);
if (finfo_file($finfo, $filename) == "video/x-flv" ){}
Probably the file itself is not a valid FLV file.
Edited.
1st: Are you sure $_FILES["file"]["error"] is zero? If not, check Error Messages Explained. Usually the most common error is not to have enctype="multipart/form-data" on the form tag of your upload page.
2nd: Never trust $_FILES["file"]["type"]. This is given by the browser. You might want to check the filename extension.
if (strtoupper(substr($_FILES["file"]["name"], -4)) == ".FLV") {
...
}
Testing the filename extension is just as insecure as trusting $_FILES["file"]["type"] - they are BOTH set at the client side. The only reliable solution is to use fileinfo.
You can use gettype() or finfo functions to get the type of the files.