cannot upload images to mysql using php - php

I want to upload images to mysql server using php.
I have created html and sql connectivity but the image upload shows error.
I cant upload the image, it shows error of valid image i.e. you must upload jpeg,bmp,gif; and read/write in directory.
Can any1 help me solving this problem
the php file is
<?php
//Start session
session_start();
//Array to store validation errors
$errmsg_arr = array();
//Validation error flag
$errflag = false;
// Check to see if the type of file uploaded is a valid image type
function valid($file)
{
// This is an array that holds all the valid image MIME types
$valid_types = array("image/jpg", "image/jpeg", "image/bmp", "image/gif");
//echo $file['type'];
if (in_array($file['type'], $valid_types))
return 1;
return 0;
}
// Build our target path full string. This is where the file will be moved do
// i.e. images/picture.jpg
$TARGET_PATH = "image/";
$TARGET_PATH = $TARGET_PATH . basename( $_FILES['image']['name']);
$pimage = $_FILES['image']['name'];
// Check to make sure that our file is actually an image
// You check the file type instead of the extension because the extension can easily be faked
if (!valid($pimage))
{
$_SESSION['ERRMSG_ARR'] = array('You must upload a jpeg, gif, or bmp');
header("Location: admin.php");
exit;
}
// Here we check to see if a file with that name already exists
// You could get past filename problems by appending a timestamp to the filename and then continuing
if (file_exists($TARGET_PATH))
{
$_SESSION['ERRMSG_ARR'] = array('A file with that name already exists');
header("Location: admin.php");
exit;
}
// Lets attempt to move the file from its temporary directory to its new home
if (move_uploaded_file($_FILES['image']['tmp_name'], $TARGET_PATH))
{
// NOTE: This is where a lot of people make mistakes.
// We are *not* putting the image into the database; we are putting a reference to the file's location on the server
$sql = "insert into people (p_category, p_name, p_quantity, p_desc, p_image) values ('$pcategory', '$pname','$pquantity','pdesc', '" . $pimage['name'] . "')";
$result = mysql_query($sql);
//Check whether the query was successful or not
if($result) {
$_SESSION['ERRMSG_ARR'] = array('Product added');;
$_SESSION['MSG_FLAG'] = 0;
session_write_close();
header("location: admin.php");
exit();
}else {
die("Query failed: ".mysql_error());
}
}
else
{
// A common cause of file moving failures is because of bad permissions on the directory attempting to be written to
// Make sure you chmod the directory to be writeable
$_SESSION['ERRMSG_ARR'] = array('Could not upload file. Check read/write persmissions on the directory');
header("Location: admin.php");
exit;
}
?>

I think
$pimage = $_FILES['image']['name'];
should be
$pimage = $_FILES['image'];
You probably missed this because your code is quite inconsistent - sometimes you use $pimage, while elsewhere you reference the $_FILES array directly. This makes it harder to maintain should the file field's name change. You could also type hint the valid() function to make PHP complain if $file isn't an array:
function valid(array $file) { ... }
What level of error reporting do you have set? It would highlight errors like trying to access undefined array keys.

See you are passing the image type in the line if (!valid($pimage))
But in the valid() function you are again trying to get the type of image $file['type'].
What George said should also work, but since you are making variables for the image type $ptype and name $pimage, you can use them itself.
So the changes should be $file['type'] becomes $file and $file['type'] & in the insert query $pimage['name'] becomes $pimage
I'm sure this solves it, Bahua ;)

Related

How can I validate multiple files first and add the rest of the form data to the database only if they're valid?

I'm not very experienced in coding PHP and MySQL, and am therefore looking for help. I'd like to do the following:
I have a form where users enter their contact details and at the end of the form there is a multiple file upload button.
Now if they submit the form, the following should happen:
First, I wanna check if all of the uploaded files are valid (file types are ok), if this is true, then the contact details should be entered to table_X of db_Z.
Then, all files should be moved/uploaded to the server and in table_Y of db_Z the file name, the (let's call it) eventID and date and time of the upload should be inserted, whereas the eventID is a foreignkey of the ID of the entry of the contact details.
The code I have until now is close, but the final step is missing. It adds the contact details to the database regardless of the result of the validation of the files.
How can I change it, so that it only adds something to the database if all files are valid? And also that it adds the contact details only once to database regardless of how many files are being uploaded?
Thanks in advance
Here's my code:
<?php
if(isset($_POST['submit'])){
$obs_fname = filter_input(INPUT_POST, 'firstname');
$obs_lname = filter_input(INPUT_POST, 'lastname');
$obs_address = filter_input(INPUT_POST, 'adresse');
// Include the database configuration file
include_once 'dbConfig.php';
$query = "INSERT INTO bear (obs_fname, obs_lname, obs_address)
values ('$obs_fname','$obs_lname','$obs_address')";
$result=$db->query($query);
// verify results
if(!$result) {
$message = "ERROR SAVING POST : ".$db->error . "\n";
$db->close();
echo ($message);
return false;
}
/**
* get the last inster id of the Post
**/
$post_id = $db->insert_id;
echo "Post id=".$post_id ."<br>\n";
// File upload configuration
$targetDir = "uploads/";
$allowTypes = array('jpg','png','jpeg','gif');
if(isset($_FILES['files'])) {
foreach($_FILES['files']['name'] as $key => $name) {
$image_tmp = $_FILES['files']['tmp_name'][$key];
move_uploaded_file($image_tmp, './uploads/' . $name);
/**
* now insert the image with the post_id
**/
$query = "INSERT INTO images (eventID, file_name, uploaded_on)
VALUES ('$post_id', '$name', NOW())";
$result=$db->query($query);
// verify results
if(!$result) {
$message = "ERROR INSERT IMAGE : ".$db->error . "\n";
$db->close();
echo ($message);
return false;
}
}
}
header("Location: upload-complete.php");
}
You need to validate the MIME type on the server-side using mime_content_type() or using an image function that will return FALSE if it is not an image such getimagesize()
you gonna need a function like this + you need to validate the size $_FILES['files]['size] and the file extension $file_ext = strtolower(pathinfo($_FILES['files']['name'], PATHINFO_EXTENSION))
function validate_images($image_tmp){
foreach($_FILES['files']['tmp_name'] as $key => $name) { // you need the tmp_name here and not "name" name is the one was when the file was in the client computer, After the form sent, the file will be in `/tmp` on the server and that is where php is accessing it.
$image_tmp = $_FILES['files']['tmp_name'][$key];
if(strpos(mime_content_type($image_tmp),"image")){
return true;
}else{
return false;
}
}
if(validate_images($image_tmp)){
// do the rest
}else{
die("no no no");
}
Also look here w3school image upload

Cannot find file path (invalid url)

I have problem to find file path. I have a form that can insert file or image.
Below code shows how the file or images save
if($_FILES["lampiran"]["name"][$i] != "")
{
$my_folder = "./files";
$location = $my_folder.'/'.$pname;
$imageFileType = pathinfo($tname,PATHINFO_EXTENSION);
move_uploaded_file($tname,$location);
$query2 = "INSERT into list_lampiran (id_aduan, folder, lampiran, nama_asal, type, size, time_create) VALUES ('$id_aduan', '$my_folder', '$location', '$pname', '$file_type', '$file_size', '$time_create')";
mysqli_query($con, $query2);
$id_lampiran=mysqli_insert_id($con);
if($query2){
$myfile_rename = $id_lampiran.'_'.$pname;
rename($location, './files/'.$myfile_rename);
$query3 ="UPDATE list_lampiran SET lampiran = '$myfile_rename' WHERE id = '$id_lampiran'";
mysqli_query($con,$query3);
}
}
Then the file or image will sent through an email and appear as a link. But the link have invalid URL
Code to display the file or image in email
if(mysqli_num_rows($resultlampiran) > 0){
$rowlampiran = mysqli_fetch_array($resultlampiran,
MYSQLI_ASSOC);
$folder_name = $rowlampiran['folder'];
$lampiran = $rowlampiran['lampiran'];
$lampiran1 = $folder_name.'/'.$lampiran;
$nama_asal = $rowlampiran['nama_asal'];
$file = "<ul><li><a href='".$lampiran1."'>".$nama_asal."</a></li></ul>"; }
Redirect notice
You missed to include the URL of your website in the file link. You need to update the file path in your email template or so as:
$website = "https://example.com/";
$file = "<ul><li><a href='".$website.$lampiran1."'>".$nama_asal."</a></li</ul>";
and you're good to go :)
Also, you have coded without caring about the security of your application. Anyone could easy upload backdoor or any other PHP
scripts and destroy all the data and files on your server. You must
validate file extension and then save to your database
Example:
$validExt = array("jpg", "png", "pdf", "txt"); // valid extensions that should only be allowed.
// and then check if upload file's extension matches in our valid list
if(in_array(strtolower($imageFileType), $validExt) === false) {
// some other file extension found, show error message
} else {
// upload your file here and save to database
}
This is your file url
$location = "www.sitename.com/". $my_folder.'/'.$pname;
echo $location;

Image upload to mysql

My site is able to upload a file but I don't understand how to get the path to the file for the database query. When someone uploads an image, the path to the image should get directly inserted into the users table in the userpic field. How can I achieve this?
<?PHP
if(isset($_FILES['file'])) {
move_uploaded_file($_FILES['file']['tmp_name'],'files/'.$_FILES['file']['name']);
session_start();
$username = $_SESSION['user'];
$userpic = ???? // <-- what am i supposed to call here to put the path to my image file
include ("connect.php");
$sql = $con->prepare('INSERT INTO users (username,userpic) VALUES (?,?)');
$sql->bind_param("ss",$username,$userpic);
$sql->execute();
$sql->close();
$con->close();
} else {
echo "no files";
}
?>
If you store files using the name provided by the client when the file is uploaded, you will potentially overwrite images (e.g. if two users upload me.png) - it would be much better to use the username to store the images, and then you don't even need the mysql table to connect users to their pics..
<?php
session_start();
$username = $_SESSION['user'];
if(empty($username)){
echo "Error: no username found";
}
else if(isset($_FILES['file']) ){
//create a path to move file to
$newpath = 'files/'.$username;
if (move_uploaded_file($_FILES['file']['tmp_name'], $newpath)) {
echo "File is valid, and was successfully uploaded.\n";
} else {
echo "Error: Possible file upload attack!\n";
}
}
else{
echo "No Files to save";
}
In this code we use the username from the session, and check its not blank.
We then use this to store the image in your files folder.
Note this ignores a number of security issues:
Including ../ in your username which would cause the file to be saved outside of the files directory.
This may not be an issue if you have already validated the username, another solution would be to create a hash of the username and using this instead: $newpath = 'files/'.md5($username);
Not checking for errors, or verifying the file is indeed an image.
http://php.net/manual/en/features.file-upload.errors.php
PHP image upload security check list
How are these images going to be used after this?
If the files directory is within your htdocs, the contents will be available for all - it would probably be better to store it outside of your htdocs
e.g. $newpath = '/var/myappdata/userimages/'.md5($username);
You could then create another file userimage.php which reads the file:
<?php
session_start();
$username = $_SESSION['user'];
$path = '/var/myappdata/userimages/'.md5($username);
readfile($path);
This allows you to do additional checks e.g. that the user is allowed to see the image.
There is still a huge amount that could be covered here, hopefully this gives you enough to move forward, but do please read more about file upload security before putting this into production.
Your original question
If you did want to store information about the image in your database you could do something like this:
<?php
session_start();
include ("connect.php");
$username = $_SESSION['user'];
if(empty($username)){
echo "Error: no username found";
}
else if(isset($_FILES['file']) ){
//create a path to move file to
$filename = basename($_FILES['file']['name']);
$newpath = 'files/'.$filename;
if (move_uploaded_file($_FILES['file']['tmp_name'], $newpath)) {
echo "File is valid, and was successfully uploaded.\n";
$sql = $con->prepare('INSERT INTO users (username,userpic) VALUES (?,?)');
$sql->bind_param("ss",$username,$filename);
$sql->execute();
$sql->close();
$con->close();
} else {
echo "Error: Possible file upload attack!\n";
}
}
else{
echo "No Files to save";
}
As I said though - you will run into conflicts if two users upload the same file.
You aren't going to want to store the entire URL in the database. You just need the path to where it is on the server. That is the part where you are moving the tmp file to a new location. In your case it would be the following.
$userpic = 'files/'.$_FILES['file']['name'];

PHP - Renaming a file to disallow duplicates

So I am using this script to upload a file to a directory and show it live.
<?php
function UploadImage($settings = false)
{
// Input allows you to change where your file is coming from so you can port this code easily
$inputname = (isset($settings['input']) && !empty($settings['input']))? $settings['input'] : "fileToUpload";
// Sets your document root for easy uploading reference
$root_dir = (isset($settings['root']) && !empty($settings['root']))? $settings['root'] : $_SERVER['DOCUMENT_ROOT'];
// Allows you to set a folder where your file will be dropped, good for porting elsewhere
$target_dir = (isset($settings['dir']) && !empty($settings['dir']))? $settings['dir'] : "/uploads/";
// Check the file is not empty (if you want to change the name of the file are uploading)
if(isset($settings['filename']) && !empty($settings['filename']))
$filename = $settings['filename'] . "sss";
// Use the default upload name
else
$filename = preg_replace('/[^a-zA-Z0-9\.\_\-]/',"",$_FILES[$inputname]["name"]);
// If empty name, just return false and end the process
if(empty($filename))
return false;
// Check if the upload spot is a real folder
if(!is_dir($root_dir.$target_dir))
// If not, create the folder recursively
mkdir($root_dir.$target_dir,0755,true);
// Create a root-based upload path
$target_file = $root_dir.$target_dir.$filename;
// If the file is uploaded successfully...
if(move_uploaded_file($_FILES[$inputname]["tmp_name"],$target_file)) {
// Save out all the stats of the upload
$stats['filename'] = $filename;
$stats['fullpath'] = $target_file;
$stats['localpath'] = $target_dir.$filename;
$stats['filesize'] = filesize($target_file);
// Return the stats
return $stats;
}
// Return false
return false;
}
?>
<?php
// Make sure the above function is included...
// Check file is uploaded
if(isset($_FILES["fileToUpload"]["name"]) && !empty($_FILES["fileToUpload"]["name"])) {
// Process and return results
$file = UploadImage();
// If success, show image
if($file != false) { ?>
<img src="<?php echo $file['localpath']; ?>" />
<?php
}
}
?>
The thing I am worried about is that if a person uploads a file with the same name as another person, it will overwrite it. How would I go along scraping the filename from the url and just adding a random string in place of the file name.
Explanation: When someone uploads a picture, it currently shows up as
www.example.com/%filename%.png.
I would like it to show up as
www.example.com/randomstring.png
to make it almost impossible for images to overwrite each other.
Thank you for the help,
A php noob
As contributed in the comments, I added a timestamp to the end of the filename like so:
if(isset($settings['filename']) && !empty($settings['filename']))
$filename = $settings['filename'] . "sss";
// Use the default upload name
else
$filename = preg_replace('/[^a-zA-Z0-9\.\_\-]/',"",$_FILES[$inputname]["name"]) . date('YmdHis');
Thank you for the help

If file doesnt exist loop (PHP)

I want people to upload photos on my website, and save each photo as a random file name. I created the upload form. and this is the uploading php function:
if($_FILES['myprofilepicture']['type']!='image/jpeg' && $_FILES['photo']['type']!='image/jpg' && $_FILES['photo']['type']!='image/png'){header("location:wrongfile.php");}else{
$info = pathinfo($_FILES['photo']['name']);
$randomfile = substr(str_shuffle("abcdefghijklmnopqrstuvwxyz0123456789"),0,$length);
$target = 'picture/'.$randomfile; $now=time();
move_uploaded_file( $_FILES['myprofilepicture']['tmp_name'], $target);
mysql_query("Insert into photos(name,photo,date)values('$myname','$randomfile','$now')")or die('database error occured');
header("location:home.php");
the problem is, if there was a picture uploaded with the same filename before, it will get overwritten, I want to improve the code so that
if no photo was uploaded with the same file name before->save photo
if a photo was uploaded with the same file name before->generate another random string and continue this loop until no photo was previously uploaded with the same name and then save the photo
any help?
Use file_exists() function to check if a file exists:
if($_FILES['myprofilepicture']['type'] != 'image/jpeg' &&
$_FILES['photo']['type'] != 'image/jpg' &&
$_FILES['photo']['type'] != 'image/png')
{
header("location: wrongfile.php");
}
else
{
$info = pathinfo($_FILES['photo']['name']);
$randomfile = substr(str_shuffle("abcdefghijklmnopqrstuvwxyz0123456789"),0,$length);
$target = 'picture/'.$randomfile;
if(!file_exists($target)) //if file doesn't exist
{
$now = time();
move_uploaded_file( $_FILES['myprofilepicture']['tmp_name'], $target);
mysql_query("Insert into photos(name,photo,date)values('$myname','$randomfile','$now')")or die('database error occured');
header("location:home.php");
}
}
The if conditional statement in the above piece of code will check if the file already exists, and if not, execute the statements in the block. However, if you want to repeat the process until a unique file path is found, you can use a loop instead:
while(!file_exists($target))
{
# code ...
}
As a sidenote: you're currently inserting user input directly into your SQL query. This is a very bad practice and it makes your query vulnerable to SQL injection. You should stop using the deprecated mysql_* functions and start using PDO or MySQLi.

Categories