Why doesn't my file upload function work properly? PHP - php

Hi I have a file upload function. Controls file size and file type. If the file is in PDF format and is smaller than 10MB, everything works as it should.
If the file is not PDF, it should show me the message: "ERROR: You can just upload PDF files." but no message.
If the file size is larger than 10MB, it should show me the message: "ERROR: Max file size 10MB." but no message.
If the file is PDF but larger than 10MB, it shows me: "ERROR: All fields must be filled."
What is wrong with my code?
Function :
<?php
function file_create($file) {
if(isset($file)){
$errors = array();
$target_dir = "../files/";
$file_name = uniqid();
$file_size = $file['size'];
$file_tmp = $file['tmp_name'];
$file_type = $file['type'];
$file_ext = strtolower(end(explode('.',$file['name'])));
if($file_type != "application/pdf") {
$error = "ERROR : You can upload just PDF files.";
array_push($errors, $error);
}
if($file_size > 1024*1024*10) {
$error = "ERROR : Max file size 10MB.";
array_push($errors, $error);
}
if(empty($errors) == true) {
move_uploaded_file($file_tmp,$target_dir.$file_name.".".$file_ext);
$errors['status'] = true;
$errors['patch'] = substr($target_dir.$file_name.".".$file_ext, 3);
} else {
$errors['status'] = false;
}
return $errors;
}
}
?>
Another File :
<?php
$errors = array();
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$notice_title = secured_post("notice-title");
$notice_content = secured_post("notice-content");
// if there is empty field in form.
if (multi_empty($notice_title, $notice_content)) {
// if a file submitted.
if (isset($_FILES['notice-file'])) {
$notice_file = $_FILES['notice-file'];
// upload the file.
$upload = file_create($notice_file);
if ($upload['status'] == false) {
$size = count($upload);
for ($i=0; $i < $size; $i++) {
array_push($errors, $upload[$i]);
}
}
notice_create($conn, $notice_title, $notice_content, $upload['patch']);
} else {
notice_create($conn, $notice_title, $notice_content);
}
} else {
$error = "ERROR : All fields must be filled.";
array_push($errors, $error);
}
}
if ($errors) {
foreach ($errors as $error) {
echo "<div class='error'>".$error."</div></br>";
}
}
?>

Here's the problem. If your file is larger than 10MB then it can take some time to upload the file so you have to check if the $_FILES array is empty or not.
Try this:
<?php
$errors = array();
if ($_SERVER['REQUEST_METHOD'] == 'POST' && !empty($_FILES)) { //I've made changes to this line
$notice_title = secured_post("notice-title");
$notice_content = secured_post("notice-content");
// if there is empty field in form.
if (multi_empty($notice_title, $notice_content)) {
// if a file submitted.
if (isset($_FILES['notice-file'])) {
$notice_file = $_FILES['notice-file'];
// upload the file.
$upload = file_create($notice_file);
if ($upload['status'] == false) {
$size = count($upload);
for ($i=0; $i < $size; $i++) {
array_push($errors, $upload[$i]);
}
}
notice_create($conn, $notice_title, $notice_content, $upload['patch']);
} else {
notice_create($conn, $notice_title, $notice_content);
}
} else {
$error = "ERROR : All fields must be filled.";
array_push($errors, $error);
}
}
if ($errors) {
foreach ($errors as $error) {
echo "<div class='error'>".$error."</div></br>";
}
}
?>
And:
<?php
function file_create($file) {
if(!empty($file)){ //I've made changes to this line
$errors = array();
$target_dir = "../files/";
$file_name = uniqid();
$file_size = $file['size'];
$file_tmp = $file['tmp_name'];
$file_type = $file['type'];
$file_ext = strtolower(end(explode('.',$file['name'])));
if($file_type != "application/pdf" || $file_ext != ".pdf") { //I've made changes to this line
$error = "ERROR : You can upload just PDF files.";
array_push($errors, $error);
}
if($file_size > (1024*1024*10)) {
$error = "ERROR : Max file size 10MB.";
array_push($errors, $error);
}
if(empty($errors) == true) {
move_uploaded_file($file_tmp,$target_dir.$file_name.".".$file_ext);
$errors['status'] = true;
$errors['patch'] = substr($target_dir.$file_name.".".$file_ext, 3);
} else {
$errors['status'] = false;
}
return $errors;
}
}
?>
Note: The $_FILES array can be set and empty at the same time so isset() can't help you here.

Related

File name too long while uploading image in database

I have written a line of codes to upload an image in the database, however, trying to upload image gives me this error
File name too long
Following is my code to upload an image to database:
if($_SERVER['REQUEST_METHOD']=="POST")
{
$pid = rand(1000,9000);
$title = $_POST['title'];
$descpt = $_POST['description'];
$push = isset($_POST['send_push']) ? $_POST['send_push'] : "";
$feature_image = array();
$fy = $_POST['fy'];
if(empty($title) || empty($descpt) || empty($fy))
{
array_push($this->errors, MEND_FIELD_ERROR);
return;
}
if(!empty($_FILES['feature_image']['name'][0]))
{
$image = $_FILES['feature_image'];
$allowed_ext = array('jpeg','jpg','png','pdf','docx');
$allowed_size = 20000000;
foreach($image['name'] as $pos=>$image_name)
{
$dir = "./cdn/uploads/notice/".$title;
$tmp = $image['tmp_name'][$pos];
$img_size = $image['size'][$pos];
$img_error = $image['error'][$pos];
$img_ext = explode('.', $image_name);
$img_name = $img_ext[0];
$img_ext = strtolower(end($img_ext));
if(in_array($img_ext, $allowed_ext))
{
if($img_size <= $allowed_size)
{
if(!file_exists($dir))
{
mkdir($dir);
}
$image_new_name = $img_name.'$$'.uniqid('', true).'.'.$img_ext;
$upload_destination = $dir.'/'.$image_new_name;
if(move_uploaded_file($tmp, $upload_destination))
{
array_push($feature_image, $image_new_name);
}
else
{
array_push($this->errors, $img_error);
return;
}
}
}
else
{
array_push($this->errors, $img_ext.' is not an allowed file extension.');
return;
}
}
}
$s_feature_image = json_encode($feature_image, JSON_UNESCAPED_UNICODE);
$statement = $this->db->prepare("INSERT INTO `notice` (`pid`,`title`,`descpt`,`date`,`photo`,`fy`)
VALUES (?,?,?,?,?,?)");
if($statement->execute([$pid,$title,$descpt,DAT, $s_feature_image, $fy]))
{
if($push == "checked")
{
$descpt = strip_tags($descpt);
$tek = array("message"=>$descpt,"title"=>$title);
$tokens = $this->getTokens();
$this->push_notification($tokens,$tek);
}
ExitThis::send_to(URL.'notice?id='.$pid);
}
else
{
array_push($this->errors, DATABASE_ERROR);
return;
}
}
Is it because of permission issue or something else? If so, what is causing me this problem and how do I fix this?
this is how I upload the file into the server and save the file name + extension into the database.
<?php
include 'connection.php';
$id = $_POST['id'];
$imgFile = $_FILES['photo']['name'];
$tmp_dir = $_FILES['photo']['tmp_name'];
$imgSize = $_FILES['photo']['size'];
$folder = 'images/'; // upload directory
$imgExt = strtolower(pathinfo($imgFile, PATHINFO_EXTENSION)); // get image extension
// valid image extensions
$valid_extensions = array('jpeg', 'jpg', 'png', 'gif'); // valid extensions
// rename uploading image
$img = rand(1000, 1000000) . "." . $imgExt;
// allow valid image file formats
if (in_array($imgExt, $valid_extensions)) {
// Check file size '5MB'
if ($imgSize < 5000000) {
move_uploaded_file($tmp_dir, $folder . $img);
} else {
$errMSG = "Sorry, your file is too large.";
}
} else {
$errMSG = "Sorry, only JPG, JPEG, PNG & GIF files are allowed.";
}
$query = mysqli_query($con, "UPDATE `profile` SET `photo` = '$img' WHERE `id` = '$id'");
if ($query) {
echo "<script>alert('Profile Updated'); window.location ='index.php?data=profile' </script>";
} else {
echo "<script>alert('Failed'); window.location ='index.php?data=profile' </script>";
}
?>
Hope this helps.
Cheers.

Compress image php with move_uploaded_files

I have a php script which upload a photo from an Ajax call, and i want to upload the photo two times, one with standard size and another one compressed. Does anyone know how to do it with this following code? I tried to compress the image with scripts that I found on stackoverflow, but I can't do it correctly. Everytime appears an black photo.
I got this code:
$data = array();
if (isset($_GET['files'])) {
$error = false;
$files = array();
$uniqid = uniqid();
$uploaddir = '../../images/'.$uniqid;
foreach($_FILES as $file) {
if (move_uploaded_file($file['tmp_name'], $uploaddir.basename($file['name']))) {
$files[] = $uploaddir.$file['name'];
} else {
$error = true;
}
}
$data = ($error) ? array('error' = > 'There was an error uploading your files') : array('files' = > $files);
} else {
$arr - > image = $file['name'];
$_SESSION['image'] = "img-".$file['name'];
$arr - > ok = "ok";
$data = array('success' = > 'Form was submitted', 'formData' = > $file['name']);
}
Thank you all!
Try using basename() also in your $files[] array insertion:
Change this:
foreach($_FILES as $file) {
if (move_uploaded_file($file['tmp_name'], $uploaddir.basename($file['name']))) {
$files[] = $uploaddir.$file['name'];
} else {
$error = true;
}
}
To this:
foreach($_FILES as $file) {
if (move_uploaded_file($file['tmp_name'], $uploaddir.basename($file['name']))) {
$files[] = $uploaddir.basename($file['name']);
} else {
$error = true;
}
}

Reusing code (function?) in PHP

Got this bit of code:
if ($_FILES["file1"]["error"] == 0) {
move_uploaded_file($_FILES["file1"]["tmp_name"], "path/".$_FILES["file1"]["name"]);
}
I would like to reuse it for more files being uploaded. Was thinking function with some params but it seems i can't get the vars correctly.
Ok fixed it like this:
function upload($file) {
$allowedExts = array("pdf, jpg, gif, png");
$extension = end(explode(".", $_FILES[$file]["name"]));
if (in_array($extension, $allowedExts)) && ($_FILES[$file]["error"] == 0) {
move_uploaded_file($_FILES[$file]["tmp_name"], "img/new/".$_FILES[$file]["name"]);
}
}
And calling via:
upload("file1");
Not sure about the $_FILES loop...
You can loop through the $_FILES array and execute your code for each file, like this:
foreach($_FILES as $file)
{
if ($file["error"] == 0) {
move_uploaded_file($file["tmp_name"], "path/".$file["name"]);
}
}
You could do this
function upload_file($file, $upload_path)
{
if($file["error"] == 0){
$moved = move_uploaded_file($file["tmp_name"], $upload_path.$file["name"]);
if($moved){
return true;
}
}
return false;
}
simple but works for your needs.
Documentation: PHP File Uploads
This works:
<?php
if(isset($_FILES['file']['tmp_name']))
{
$num_files = count($_FILES['file']['tmp_name']);
for($i=0; $i < $num_files;$i++)
{
if(!is_uploaded_file($_FILES['file']['tmp_name'][$i]))
{
$messages[] = 'No file uploaded';
}
else
{
if(move_uploaded_file(($_FILES['file']['tmp_name'][$i],$upload_dir.'/'.$_FILES['file']['name'][$i]))
{
$messages[] = $_FILES['file']['name'][$i].' uploaded';
}
else
{
$messages[] = 'Uploading '.$_FILES['file']['name'][$i].' Failed';
}
}
}
}
?>
Note: It's a good idea to validate the files using exif_imagetype(), getimagesize() and similar.. Every other value than $_FILES['image']['tmp_name'] and $_FILES['image']['error'] shouldn't be trusted. It takes whatever is sent from the browser and can easily be faked.

hide input field if upload succeed

I would like to hide the input field if upload succeed. I tried to hide it by putting $sub =1; and if($sub==0) as below but it hides the input whenever submit is pressed not when the upload succeed. any ideas?
<?php
function uploadFile ($file_field = null, $check_image = false, $random_name = false) {
//Config Section
//Set file upload path
$path = 'productpic/'; //with trailing slash
//Set max file size in bytes
$max_size = 2097152;
//Set default file extension whitelist
$whitelist_ext = array('jpg','png','gif');
//Set default file type whitelist
$whitelist_type = array('image/jpeg', 'image/png','image/gif');
//The Validation
// Create an array to hold any output
$out = array('error'=>null);
if (!$file_field) {
$out['error'][] = "Please specify a valid form field name";
}
if (!$path) {
$out['error'][] = "Please specify a valid upload path";
}
if (count($out['error'])>0) {
return $out;
}
//Make sure that there is a file
if((!empty($_FILES[$file_field])) && ($_FILES[$file_field]['error'] == 0)) {
// Get filename
$file_info = pathinfo($_FILES[$file_field]['name']);
$name = $file_info['filename'];
$ext = $file_info['extension'];
//Check file has the right extension
if (!in_array($ext, $whitelist_ext)) {
$out['error'][] = "Invalid file Extension";
}
//Check that the file is of the right type
if (!in_array($_FILES[$file_field]["type"], $whitelist_type)) {
$out['error'][] = "Invalid file Type";
}
//Check that the file is not too big
if ($_FILES[$file_field]["size"] > $max_size) {
$out['error'][] = "We are sorry, the image must be less than 2MB";
}
//If $check image is set as true
if ($check_image) {
if (!getimagesize($_FILES[$file_field]['tmp_name'])) {
$out['error'][] = "The file you trying to upload is not an Image, we only accept images";
}
}
//Create full filename including path
if ($random_name) {
// Generate random filename
$tmp = str_replace(array('.',' '), array('',''), microtime());
if (!$tmp || $tmp == '') {
$out['error'][] = "File must have a name";
}
$newname = $tmp.'.'.$ext;
} else {
$newname = $name.'.'.$ext;
}
//Check if file already exists on server
if (file_exists($path.$newname)) {
$out['error'][] = "The image you trying to upload already exists, please upload only once";
}
if (count($out['error'])>0) {
//The file has not correctly validated
return $out;
}
if (move_uploaded_file($_FILES[$file_field]['tmp_name'], $path.$newname)) {
//Success
$out['filepath'] = $path;
$out['filename'] = $newname;
return $out;
} else {
$out['error'][] = "Server Error!";
}
} else {
$out['error'][] = "Please select a photo";
return $out;
}
}
?>
<?php
if (isset($_POST['submit'])) {
$sub=1;
$file = uploadFile('file', true, false);
if (is_array($file['error'])) {
$message = '';
foreach ($file['error'] as $msg) {
$message .= '<p>'.$msg.'</p>';
}
} else {
$message = "File uploaded successfully";
}
echo $message;
}
?>
<form action="" method="post" enctype="multipart/form-data" name="form1" id="form1">
<?php
ini_set( "display_errors", 0);
if($sub==0)
{
?>
<input name="file" type="file" size="20" />
<input name="submit" type="submit" value="Upload" />
<?php
}
?>
</form>
Try this
if (is_array($file['error'])) {
$message = '';
foreach ($file['error'] as $msg) {
$message .= '<p>'.$msg.'</p>';
}
} else {
$message = "File uploaded successfully";
$sub=1; // keep here sub=1
}
The $sub=1 is executing when the submit is pressed since it is given in if (isset($_POST['submit'])) this means if submit is set.It should be given when upload completes.

how can I add imaging handling got this script effectively

hopefully someone can help me here. been up all night browsing and nothing I try seems to work, but im new to php so im slow. I need to upload 6 images, and this works great. but then I realized you can upload not only images but all other file types. Im trying to be able to limit it to just images under 100kb each. heeeeelllllllpppppp!!!! please!
function findexts ($filename) { $filename = strtolower('$filename') ;
$exts = preg_split("[/\\.]", $filename) ;
$n = count($exts)-1;
$exts = $exts[$n];
return $exts;
}
$ext = findexts ($_FILES['images']['name']) ;
$ran = rand ();
$ran2 = $ran.".";
while(list($key,$value) = each($_FILES['images']['name']))
{
if(!empty($value))
{
$filename = $ran.$value;
$filename=str_replace(" "," _ ",$filename);// Add _ inplace of blank space in file name, you can remove this line
$add = "media/".$ran."$filename";
$insert_query = "INSERT INTO ....VALUES ...";
//echo $_FILES['images']['type'][$key];
// echo "<br>";
copy($_FILES['images']['tmp_name'][$key], $add);
chmod("$add",0777);
mysql_query($insert_query);
}
}
See the answer to both your questions here:
https://stackoverflow.com/a/9153419/723855
Add this function to your script (modified from link):
function acceptFileUpload($thefile){
if(isset($_FILES[$thefile])) {
$errors = array();
$maxsize = 2097152;
$acceptable = array(
'application/pdf',
'image/jpeg',
'image/jpg',
'image/gif',
'image/png'
);
if(($_FILES[$thefile]['size'] >= $maxsize) || ($_FILES[$thefile]["size"] == 0)) {
$errors[] = 'File too large. File must be less than 2 megabytes.';
}
if(!in_array($_FILES[$thefile]['type'], $acceptable)) && (!empty($_FILES[$thefile]["type"]))) {
$errors[] = 'Invalid file type. Only PDF, JPG, GIF and PNG types are accepted.';
}
if(count($errors) !== 0) {
return true;
} else {
foreach($errors as $error) {
echo '<script>alert("'.$error.'");</script>';
return false;
}
die(); //Ensure no more processing is done
}
}
}
Then in your script change your while loop to use this function to check for a valid file:
while(list($key,$value) = each($_FILES['images']['name']))
{
if(!empty($value))
{
if(acceptFileUpload('images'))
{
$filename = $ran.$value;
$filename=str_replace(" "," _ ",$filename);// Add _ inplace of blank space in file name, you can remove this line
$add = "media/".$ran."$filename";
$insert_query = "INSERT INTO ....VALUES ...";
//echo $_FILES['images']['type'][$key];
// echo "<br>";
copy($_FILES['images']['tmp_name'][$key], $add);
chmod("$add",0777);
mysql_query($insert_query);
}
}
}
I might not have that parameter right that is getting passed to acceptFileUpload().
Four functions to run on the processing script on each file, if all tests pass then the file meets your conditions and can be safely stored (png / jpg / gif + non-zero + 10Kb limit + is uploaded file)
//Example Call: checkFileExtension($_FILES['fieldname']['name']);
function checkFileExtension($filename) {
$filename = strtolower($filename) ;
$filenamePartsArray = preg_split("[/\\.]", $filename) ;
$extension = $filenamePartsArray[count($filenamePartsArray) - 1];
if (($extension == 'gif') || ($extension == 'jpeg') || ($extension == 'jpg') || ($extension == 'png')) {
return true;
} else {
return false;
}
}
//Example Call: checkFileMIME($_FILES['fieldname']['type']);
function checkFileMIME($filetype) {
if (($filetype == 'image/png') || ($filetype == 'image/jpeg') || ($filetype == 'image/gif')) {
return true;
} else {
return false;
}
}
//Example Call: checkFileSize($_FILES['fieldname']['size'], 10);
function checkFileSize($filesize, $limitKb = 0) {
if ($filesize == 0) {
return false;
}
if ($limitKb != 0) {
if ($filesize > ($limitKb * 1024)) {
return false;
}
}
return true;
}
//Native Call: is_uploaded_file($_FILES['fieldname']['tmp_name']);
Edit: pseudo example use
foreach ($_FILES as $fieldname => $file) {
if ((checkFileExtension($file['name'])) && (checkFileMIME($file['type'])) && (checkFileSize($file['size'], 10)) && (is_uploaded_file($file['tmp_name']))) {
//Move the image with move_uploaded_file
//Save the file location with DB insert
}
}
you can check the file type with
$_FILES['image']['type']
or if you want to check the extension too
$extension = explode('.',(string)$_FILES['image']['name']);
//then check if its "jpg", "gif" or "png"
the file size can be checked with
$_FILES['image']['size']
so your script should be like this for each of your image updates:
$extension = explode('.',$_FILES['image']['name']);
$imgextensions = array();
$size = $_FILES['image']['size'];
if(($extension == 'jpg' || $extension == 'gif' || $extension == 'png') &&
$size < 100000 ){
// upload your file to your filesystem
}else{
//inform the user
}

Categories