Image file not inserting into database - php

I'm trying to get an image file to send to a file I have in my host server called productpics/ and then send the file's name into my database with all of my other data in my form. I'm getting the image file to send to the productpics folder, but then my prepared statement breaks and nothing else happens. Nothing is sent to the db. I believe it is because of the way I'm trying to send the image file to the db.
The line I believe is breaking this is....
I'm getting this error with it when I submit the form, but regardless I'm not sure if I am trying to send this to the db correctly. Am I doing this the proper way or based on what I have, how can I structure this?
Fatal error: Function name must be a string in /home4/pfarley1/public_html/addproduct.php on line 110
//Create
$filename = $_FILES['file']['name'];
//$filesize = $_FILES['file']['size'];
//$filetype = $_FILES['file']['type'];
$tmp_name = $_FILES['file']['tmp_name'];
$file_error = $_FILES['file']['error'];
if (isset($filename )) {
if (!empty($filename)) {
$destinationFolder = 'productpics/';
if (move_uploaded_file($tmp_name, $destinationFolder.$filename)) {
echo 'Uploaded!';
} else {
echo 'There was an error!';
}
} else {
echo 'Please choose a file.';
}
}
if($validation->passed()) {
if(isset($_POST['create'])){
$product_id = trim( $_POST['product_id'] );
$product_name = trim( $_POST['product_name'] );
$price = trim( $_POST['price'] );
$saleprice = trim( $_POST['saleprice'] );
$final_price = trim( $_POST['final_price'] );
$shippingprice = trim( $_POST['shippingprice'] );
$category = trim( $_POST['category'] );
$item_details = trim( $_POST['item_details'] );
$item_details2 = trim( $_POST['item_details2'] );
$description = trim( $_POST['description'] );
$viewproduct_type = trim( $_POST['viewproduct_type'] );
$file = $_POST ($filename['img']);
}else {
foreach($validation->errors() as $error) {
echo $error, '<br>';
}
//Connection
$con = mysqli_connect("localhost","root","","bfb");
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
/* create a prepared statement */
if ($stmt = mysqli_prepare($con, "INSERT INTO products (product_id, product_name, price, saleprice, final_price, shippingprice, category, item_details, item_details2, description, viewproduct_type, date_created, img) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW(), ?)")) {
/* bind parameters for markers */
$stmt->bind_param('isiiiissssss', $product_id, $product_name, $price, $saleprice, $final_price, $shippingprice, $category, $item_details, $item_details2, $description, $viewproduct_type, $file);
/* execute query */
$stmt->execute();
//if(!$stmt->execute()){trigger_error("there was an error....".$con->error, E_USER_WARNING);}
/* close statement */
mysqli_stmt_close($stmt);
echo "Success!";
} else {
echo "Failed!";
}
}
With all of that said, I am not getting anything to echo with my else statement for my prepared statement's query. I am not getting a 'Success!' or 'Failed!'. Why aren't any results of that showing?
My form for this(the img file part is at the bottom of it...
<form action="" method="POST" enctype="multipart/form-data">
<div class="field">
<label for="product_id">Product ID</label>
<input type="text" name="product_id" class="smallinputbar" required>
</div>
<div class="field">
<label for="product_name">Product Name</label>
<input type="text" class="inputbar" name="product_name" required>
</div>
<div class="field">
<label for="price">Product Price</label>
<input type="text" class="smallinputbar" name="price" required>
</div>
<div class="field">
<label for="saleprice">Sale Price</label>
<input type="text" class="smallinputbar" name="saleprice">
</div>
<div class="field">
<label for="final_price">Final Price</label>
<input type="text" class="smallinputbar" name="final_price" required>
</div>
<div class="field">
<label for="shippingprice">Shipping Price</label>
<input type="text" class="smallinputbar" name="shippingprice" required>
</div>
<div class="field">
<label for="category">Category</label>
<input type="text" class="inputbar" name="category" required>
</div>
<div class="field">
<label for="item_details">Item Details</label>
<input type="message" class="messageinput" name="item_details" required>
</div>
<div class="field">
<label for="item_details2">Item Details 2</label>
<input type="message" class="messageinput" name="item_details2">
</div>
<div class="field">
<label for="description">Description</label>
<input type="message" class="messageinput" name="description" required>
</div>
<div class="field">
<label for="viewproduct_type">View Product Type</label>
<select class="optionbar" name="viewproduct_type">
<option value="Not Selected">Not Selected</option>
<option value="a href='./viewProduct.php?view_product=$id">Standard</option>
<option value="Option">Option</option>
</select>
</div>
<span class="floatright">
<input type="file" name="file" class="inputbarfile">
<!--<input type="submit" name="create" id="signinButton" value="Upload">-->
</span>
<input type="hidden" name="token" value="<?php echo Token::generate(); ?>">
<label for="button">
<input type="submit" id="button" name="create" value="Create New Product">
</label>
</form>
UPDATE:
//Create
$filename = $_FILES['file']['name'];
//$filesize = $_FILES['file']['size'];
//$filetype = $_FILES['file']['type'];
$tmp_name = $_FILES['file']['tmp_name'];
$file_error = $_FILES['file']['error'];
if (isset($filename )) {
if (!empty($filename)) {
$destinationFolder = 'productpics/';
if (move_uploaded_file($tmp_name, $destinationFolder.$filename)) {
echo 'Uploaded!';
} else {
echo 'There was an error!';
}
} else {
echo 'Please choose a file.';
}
}
if($validation->passed()) {
if(isset($_POST['create'])){
$product_id = trim( $_POST['product_id'] );
$product_name = trim( $_POST['product_name'] );
$price = trim( $_POST['price'] );
$saleprice = trim( $_POST['saleprice'] );
$final_price = trim( $_POST['final_price'] );
$shippingprice = trim( $_POST['shippingprice'] );
$category = trim( $_POST['category'] );
$item_details = trim( $_POST['item_details'] );
$item_details2 = trim( $_POST['item_details2'] );
$description = trim( $_POST['description'] );
$viewproduct_type = trim( $_POST['viewproduct_type'] );
$file = $filename;
FULL PHP code for this question.
//Validation
if(Input::exists()) {
if(Token::check(Input::get('token'))) {
$validate = new Validate();
$validation = $validate->check($_POST, array(
'product_id' => array(
'required' => true,
'min' => 1,
'max' => 50,
'unique' => 'products'
),
'product_name' => array (
'required' => true,
'min' => 2,
'max' => 50
),
'price' => array (
'required' => true,
'min' => 1,
'max' => 50
),
'saleprice' => array (
'min' => 1,
'max' => 50
),
'final_price' => array (
'required' => true,
'min' => 1,
'max' => 50
),
'shippingprice' => array (
'max' => 50
),
'category' => array (
'required' => true,
'min' => 2,
'max' => 50
),
'item_details' => array (
'required' => true,
'min' => 2,
'max' => 1550
),
'item_details2' => array (
'max' => 1550
),
'description' => array (
'required' => true,
'min' => 2,
'max' => 1550
)
)
);
//Create
if($validation->passed()) {
$filename = $_FILES['file']['name'];
//$filesize = $_FILES['file']['size'];
//$filetype = $_FILES['file']['type'];
$tmp_name = $_FILES['file']['tmp_name'];
$file_error = $_FILES['file']['error'];
if (isset($filename )) {
if (!empty($filename)) {
$destinationFolder = 'productpics/';
if (move_uploaded_file($tmp_name, $destinationFolder.$filename)) {
echo 'Uploaded!';
} else {
echo 'There was an error!';
}
} else {
echo 'Please choose a file.';
}
}
if(isset($_POST['create'])){
$product_id = trim( $_POST['product_id'] );
$product_name = trim( $_POST['product_name'] );
$price = trim( $_POST['price'] );
$saleprice = trim( $_POST['saleprice'] );
$final_price = trim( $_POST['final_price'] );
$shippingprice = trim( $_POST['shippingprice'] );
$category = trim( $_POST['category'] );
$item_details = trim( $_POST['item_details'] );
$item_details2 = trim( $_POST['item_details2'] );
$description = trim( $_POST['description'] );
$viewproduct_type = trim( $_POST['viewproduct_type'] );
$file = $filename;
$file = $_POST['img'];
}else {
foreach($validation->errors() as $error) {
echo $error, '<br>';
}
//Connection
$con = mysqli_connect("localhost","root","","bfb");
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
/* create a prepared statement */
if ($stmt = mysqli_prepare($con, "INSERT INTO products (product_id, product_name, price, saleprice, final_price, shippingprice, category, item_details, item_details2, description, viewproduct_type, date_created, img) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW(), ?)")) {
/* bind parameters for markers */
$stmt->bind_param('isiiiissssss', $product_id, $product_name, $price, $saleprice, $final_price, $shippingprice, $category, $item_details, $item_details2, $description, $viewproduct_type, $file);
/* execute query */
$stmt->execute();
//if(!$stmt->execute()){trigger_error("there was an error....".$con->error, E_USER_WARNING);}
/* close statement */
mysqli_stmt_close($stmt);
echo "Success!";
} else {
echo "Failed!";
}
}
}
}
}

Commenting back and forth is getting to be too long at this point and am submitting the following answer, since it is too long to be a comment.
Although this may not be a solution (or possibly could, or it may lead to one), is nonetheless an answer to the problem/error message you posted.
The problem is with this line $file = $_POST ($filename['img']); and I have no idea what you're trying to do here.
You told me earlier in comments "The column I have for 'img' is text".
POST has nothing to do with a column.
POST arrays use this syntax $_POST[] using square brackets, and not $_POST() with round brackets.
That is why you're getting the following error:
Fatal error: Function name must be a string in /home4/pfarley1/public_html/addproduct.php on line 110
It's looking for a "function()" and you're trying to use $_POST as a function.
$_POST is a superglobal (pre-defined/built-in variable), and not a function.
http://php.net/manual/en/language.variables.superglobals.php
I don't know if you want to insert that uploaded file as a binary in your column, or a text-based pointer to that file, only you know the exact intention for it.
If you want to enter it as a binary, then you will need to set the associated column for it as a BLOB.
When using BLOB as a column type, then that data needs to be escaped, otherwise it will throw an error.
You will also want to check what your upload max size is set/allowed in your system files.
By default, PHP sets it to 2M. If the file exceeds that size, it will fail; increase it and anything else relative to it such as max timeout time.
You're also not doing anything with error checking in:
$file_error = $_FILES['file']['error'];
it's a stray/unused variable.
Consult:
http://php.net/manual/en/features.file-upload.errors.php
to check for errors and to use it.
As far as I'm concerning, I would get rid of $file = $_POST ($filename['img']); and use $filename for the variable you're wanting to enter in your database, since it is going inside the img column as you've set it in your query.
Check your column length to see if it's long enough to accommodate the entry.
"The column I have for 'img' is text."
You may also want to change it from TEXT to VARCHAR and set a long enough length for it. MySQL may be failing silently because of it.
Another thing I suggest you do, is to place your $filename = $_FILES['file']['name']; and other variables below that, inside your conditional statement.
If you want to use similar syntax to replace $file = $_POST ($filename['img']);, then you could add an additional input and give it the img name attribute and then do:
$file = $_POST['img'];
which would be valid.
Another thing I spotted in your first piece of code, and if that is your entire code, you're missing a closing brace } for your if($validation->passed()) { conditional statement.
The final/last brace } is associated with this block of code:
else {
foreach($validation->errors() as $error) {
echo $error, '<br>';
}
Therefore, you will need to check the bracing matches/pairs.
Edit:
In this line that you added in an edit:
$file = $filename;
$file = $_POST['img'];
You're overwriting your first variable, and you stated in comments that you do not have a form element name img.
But that is a file not text. Use $file = $_FILES['img']; or $file = $_FILES['file']; - at this point, I've no idea what your file input in the form is called.
If it still gives you trouble, use $file = $_FILES['file']['name'];
MySQL and PHP are two different animals and do not know which column is to be used for insertion.
You cannot rely on a POST array to determine the column it is to be inserted in. You need to specify that in your query.
Make sure the img column does in fact exist, and then use the $_FILES array with its related variable as the value in VALUES, being $file.
However, use $filename in your VALUES, instead of $file. Or, whatever variable; I am very confused at this point as to which variable and/or input name you're using.
and you may need to add that parameter in your $validation = $validate->check($_POST, array(... function/array.
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);
// rest of your code
Sidenote: Error reporting should only be done in staging, and never production.

Related

How to upload files from two html input fields in the same form using php?

Hi I am facing a problem while uploading two files using php.
I have this html input form with two files field
<form class="form-group" method="post" enctype="multipart/form-data">
<input type="file" accept=".jpg, .jpeg, .png" id="img" name="displaypic" required/>
<input type="file" accept=".pptx" name="presentation" required>
<button name="submit>Submit</submit>
</form>
This is my php code. Here I take the file data from the form but only the first one is uploaded, second file is not.
<?php
if(isset($_POST['submit'])){
$file = $_FILES['displaypic'];
$fileName = $_FILES['displaypic']['name'];
$tempName = $_FILES['displaypic']['tmp_name'];
$size = $_FILES['displaypic']['size'];
$error = $_FILES['displaypic']['error'];
$format = $_FILES['displaypic']['type'];
$fileExt = explode('.', $fileName);
$fileActualExt = strtolower(end($fileExt));
$allowed = array('jpg', 'jpeg','png');
if(in_array($fileActualExt, $allowed)) {
if ($error === 0) {
if ($size<2e6) {
$newname = $tid.".".$fileActualExt;
$location = 'displays/'.$newname;
move_uploaded_file($tempName,$location);
}}}
Similarly when I write the same code for file two it doesn't work. Only the first file is uploaded not the second file.
$file_ppt = $_FILES['presentation'];
$fileName = $_FILES['presentation']['name'];
$tempName = $_FILES['presentation']['tmp_name'];
$size = $_FILES['presentation']['size'];
$error = $_FILES['presentation']['error'];
$format = $_FILES['presentation']['type'];
$fileExt = explode('.', $fileName);
$fileActualExt = strtolower(end($fileExt));
$allowed = array('pptx');
if(in_array($fileActualExt, $allowed)) {
if ($error === 0) {
if ($size<10e6) {
$newname = $tid.".".$fileActualExt;
$location = 'presentations/'.$newname;
move_uploaded_file($tempName,$location);
}}}
}
?>
If you use the same name for the file input field but use the array style syntax for the name you can assign your own identifier within the square braces which will be available in the POST / FILES array later. This identifier can be used to separate the different types of files so you can fork the logic as appropriate to your needs.
The following shows a basic usage of this methodology - it might prove of interest but it might not.
<?php
$field='xfiles'; // Whatever you wish to name your file input elements
$errors=array();
$status=array();
$maxfs=pow(1024,2) * 5; //5Mb or whatever.... 10e6?
if( $_SERVER['REQUEST_METHOD']=='POST' && isset( $_FILES[ $field ] ) ){
$obj=$_FILES[ $field ];
foreach( $obj['name'] as $index => $void ){
$name=$obj['name'][ $index ];
$tmp=$obj['tmp_name'][ $index ];
$error=$obj['error'][ $index ];
$type=$obj['type'][ $index ];
$size=$obj['size'][ $index ];
$ext=strtolower(pathinfo($name,PATHINFO_EXTENSION));
$allowed=(object)array(
'displaypic' => array('jpg','jpeg','png'),
'presentation' => array('ppt','pptx')
);
if( $error!==UPLOAD_ERR_OK )$errors[]=sprintf('An error [code:%d] occurred with file %s',$error,$name);
if( !in_array( $ext, $allowed->$index ) )$errors[]=sprintf('Incorrect file extension %s for %s',$ext,$name);
if( $size > $maxfs )$errors[]=sprintf('The file %s is too large #%d',$name,$size);
if( empty( $errors ) ){
$status[]=sprintf('<div>%s uploaded successfully - save to db, do a happy little dance or whatever else you need to do!</div>', $name );
#move_uploaded_file($tmp,'/path/to/new/folder/'.$name);
#$sql='insert into ....';
}
}
}
?>
<!DOCTYPE html>
<html lang='en'>
<head>
<title>PHP: Multiple file uploads</title>
<meta charset='utf-8' />
</head>
<body>
<form class='form-group' method='post' enctype='multipart/form-data'>
<label>Display - [accept:jpg,png]<input type='file' accept='.jpg, .jpeg, .png' name='xfiles[displaypic]' required /></label>
<label>Presentation - [accept:ppt,pptx] <input type='file' accept='.ppt, .pptx' name='xfiles[presentation]' required /></label>
<input type='submit' />
<?php
if( $_SERVER['REQUEST_METHOD']=='POST' && !empty( $status ) ){
echo '<h1>Success</h1>';
foreach($status as $msg)printf('<div>%s</div>',$msg);
}
if( $_SERVER['REQUEST_METHOD']=='POST' && !empty( $errors ) ){
echo '<h1>Error</h1>';
foreach($errors as $error)printf('<div>%s</div>',$error);
}
?>
</form>
</body>
</html>

PHP unable to echo the text after a condition is met

I am not getting the desired result from the code below. Everything works fine But there is one main problem:
When there is no song in the database it shows empty result just with back button. It fails to show echo 'Sorry! This song is not available on our database.';
I cant figure out where the mistake is. So plz help.
Thanks in advance!!!
<?php
// Php code that fetches audio from the database in server and shows the audio files with singers available for the submitted data
// In submission page DROPDOWN consists of Playlist name and TEXTBOX allows to type the song number for that playlist.
// Standard format for the audio file stored in the databse is Songnumber-Playlistname-Singer's Shortname.mp3
// MP3 files will be inside the AUDIO folder and this PHP code runs from the root folder where there is index.html file for data submission.
// Valid song Numbers of Each Playlists that user choose
$validsongnumbers = [
'Rock' => 3,
'Pop' => 5,
'Jazz' => 6
];
// Data captured from dropdown submitted by a user in homepage
$PlaylistName = $_POST['Dropdown'];
$songNumber = $_POST['songnumber'];
// Check the playlist exists
if (!array_key_exists($PlaylistName, $validsongnumbers)) {
echo 'Invalid playlist provided.';
exit;
}
// Check the song number is not greater than what is allowed
if ((int)$songNumber > $validsongnumbers[$PlaylistName]) {
echo 'Invalid song number provided.';
exit;
}
$userselectedsong=sprintf('%s-%s', $songNumber, $PlaylistName );
$audiofilelocation = 'audio/' .$userselectedsong. ".mp3";
// check for user entered song in entire audio folder
$files = glob("audio/" .$userselectedsong. "*.{mp3,wav,wma,mp4}", GLOB_BRACE);
$count= count ($files);
if ($count == 0) {
echo '<span style="color: red;"/>Sorry! This song is not available on our database.</span>'; //Why this part is not wotking??? Rest all is ok
}else
$arr=outputFiles( $audiofilelocation , $userselectedsong );
foreach( $arr as $obj ) {
printf(
'<link rel="stylesheet" type="text/css" href="audio/css/main.css"><div class="wrap-login100 p-l-85 p-r-85 p-t-55 p-b-55"><br><br><audio width="100%" height="100%" controls="controls" src="%1$s" controlslist="nodownload" type="audio/mp3" style="visibility: visible;">
</audio><br /><font size="4" color="#000080"><b>Singer : <font size="4" color="#B22222">%2$s<br></b></font></font></div>',
$obj->file,
$obj->name
);
}
function singeractualname( $ssn ) {
switch( $ssn ){
case 'RI':return 'Rihanna';
case 'MJ':return 'Michael Jackson';
default:return 'Singer name not available !!!';
}
}
function outputFiles( $path, $song ){
$output=[];
if( file_Exists( $path ) ){
$dirItr=new RecursiveDirectoryIterator( $path, RecursiveDirectoryIterator::KEY_AS_PATHNAME );
foreach( new RecursiveIteratorIterator( $dirItr, RecursiveIteratorIterator::CHILD_FIRST ) as $obj => $info ) {
if( $info->isFile() ){
$pttn=sprintf( '#%s-\w+\.\w+#i', $song );
preg_match( $pttn, $info->getFileName(), $col );
if( !empty( $col ) ){
foreach( $col as $file ){
$ext=pathinfo( $file, PATHINFO_EXTENSION );
list( $int, $cat, $code )=explode( '-', pathinfo( $file, PATHINFO_FILENAME ) );
$output[]=(object)[
'ext' => $ext,
'code' => $code,
'name' => singeractualname( $code ),
'file' => 'audio/' . $info->getFileName(),
'index' => $int,
'category' => $cat
];
}
}
}
}
}
return $output;
}
First you have doubled "if if":
if if(count($files) < 0
Second, number of files can never be negative. You should compare if number is equal 0 (zero), not less than 0.
UPDATE:
Still wrong code:
if ($count=0)
This is not comparison, but assignment. You are giving $count value 0. For comparison you must use:
if ($count == 0)

Uploading multiple images and text input with php

I am working on a form which allows users upload text, location and 4 multiple images for a project, I have successfully written a code that uploads form data into my database but the problem I do face is that whenever I upload more than 1 image with this form, the form text and location input are been inserted into my database more than 1 times (to match the number of images I have uploaded). For example I Uploaded 3 images using the form and text "Hello World" and location "NY", output should be;
Hello World
NY
[image 1] [image 2] [image 3]
But instead output is
Hello World NY
Hello World NY
Hello World NY
[image 1] [image 2] [image 3]
I will like to stop the duplicate of the form text to match the number of images uploaded using the form for I have tried removing my query from the foreach statement but get no result after upload. Below is my code
<?php
// start session
session_start();
// db
include db.php";
// random_char
include "random_char.php";
// compress image
include "compress_image.php";
// from user id
$id = $_SESSION["id"];
$user = $_SESSION["name"];
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// post validations
if (empty(trim($_POST['photo_post_box']))) {
// $post_box = null; // post box
$post_box_error = true; // post box is empty
} elseif (strlen($_POST['photo_post_box']) > 500) {
$post_box_error = true; // characters is greater than 500
} else {
$post_box = $_POST['photo_post_box'];
$post_box_error = false;
}
// location validation
if (empty(trim($_POST['photo_location']))) {
$location = ""; // location
$location_error = false; // location is empty
} elseif (strlen(preg_replace('/[^a-zA-Z]/m', '', $_POST["photo_location"])) < 2) {
$location_error = true; // location is less than 2
} elseif (strlen(preg_replace('/[^a-zA-Z]/m', '', $_POST["photo_location"])) > 20) {
$location_error = true; // location is greater than 20
} elseif (!preg_match("/^[A-Za-z-,\s]+$/ ", $_POST["photo_location"])) {
$location_error = true; // location has unwanted characters
} else {
$location = trim($_POST['photo_location']); // location
$location_error = false;
}
// image validations
$accepted_extensions = array(
"gif",
"png",
"jpg",
"jpeg"
); // extensions
$img = $_FILES["img"]; // images
foreach($img['name'] as $key => $name) {
$files = $_FILES['img'];
$img_extension = pathinfo($files["name"][$key], PATHINFO_EXTENSION); // image extention
$img_extension = strtolower($img_extension); // image extension
if (!file_exists($files['tmp_name'][$key])) {
$img_error = true;
} elseif (!in_array($img_extension, $accepted_extensions)) {
echo "<font color='red'>Invalid format</font>";
$img_error = true;
} elseif ($files["size"][$key] > 10485760) {
$img_error = true; // image is larger than 10mb
} else {
$img_error = false;
}
if ($post_box_error == false && $location_error == false && $img_error == false) {
$time = md5(microtime()); // micro time hashed with md5
$name_file = $project_name.".com(#".$user.")_".$time.$id; // rename image
$ext = substr($name, strrpos($name, '.') + 1); // extension
$uploaded_img = $name_file.'.'.$ext; // uploaded image
$save_to_dir = __DIR__."/../../img/".$uploaded_img; // save image to directory
$post_id = random_alphanumeric_string(8).'b'.$id; // post id
// `users_post`
$insert = "INSERT INTO users_post(post_id, by_user_id, post, post_location, date_n_time) VALUES(?, ?, ?, ?, NOW())";
$stmt = mysqli_prepare($db, $insert);
mysqli_stmt_bind_param($stmt, "siss", $post_id, $id, $post_box, $location);
mysqli_stmt_execute($stmt);
// `users_post_images`
$insert = "INSERT INTO users_post_images(post_id, image) VALUES(?, ?)";
$stmt = mysqli_prepare($db, $insert);
mysqli_stmt_bind_param($stmt, "ss", $post_id, $uploaded_img);
mysqli_stmt_execute($stmt);
// compress and save uploaded image in directory
compressImage($files['tmp_name'][$key], $save_to_dir, 60);
}
// close statement
mysqli_stmt_close($stmt);
}
}
// close db connection
mysqli_close($db);
?>
<form id="photo_post_box" method="POST" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" name="post_box" enctype="multipart/form-data" accept-charset="utf-8">
<textarea class="form-control" name="photo_post_box" placeholder="Write something..."></textarea>
<div class="mt-1">
<input class="form-control" type="text" name="photo_location" placeholder="City, State">
</div>
<div class="mt-1">
<input type="file" name="img[]" id="img1" accept=".gif, .jpg, .png" required="required">
<input type="file" name="img[]" id="img2" accept=".gif, .jpg, .png">
<input type="file" name="img[]" id="img3" accept=".gif, .jpg, .png">
<input type="file" name="img[]" id="img4" accept=".gif, .jpg, .png">
</div>
<div class="mt-1">
<button name="upload">
<b>Upload</b>
</button>
</div>
</form>
Without going into code in great detail, here is generally what you are doing wrong and how you should do it.
The global $_FILES will contain all the uploaded file information. Its contents from the example form is as follows.
Array
(
[img] => Array
(
[name] => Array
(
[0] => bears.jpeg
[1] => big cat.jpeg
[2] => butterfly2.jpeg
[3] => chipmunk.jpeg
)
[type] => Array
(
[0] => image/jpeg
[1] => image/jpeg
[2] => image/jpeg
[3] => image/jpeg
)
[tmp_name] => Array
(
[0] => /tmp/phpNKGKa2
[1] => /tmp/phpOCopiT
[2] => /tmp/phphEGfqK
[3] => /tmp/phpguKfyB
)
[error] => Array
(
[0] => 0
[1] => 0
[2] => 0
[3] => 0
)
[size] => Array
(
[0] => 162804
[1] => 133032
[2] => 118203
[3] => 164941
)
)
)
When you upload files, on the PHP side you will get a structure something like this:
So you have to walk through this structure to get all the files. The form data on the other hand is only stored once in $_POST.
So you must insert the form data once and the files you must use a loop to go through them all.
// INSERT form data first outside the loop
// Then go through the files in a loop
foreach ($_FILES["img"]["error"] as $key => $error) {
if ($error == UPLOAD_ERR_OK) {
// INSERT file here
$tmp_name = $_FILES["pictures"]["tmp_name"][$key];
$name = basename($_FILES["pictures"]["name"][$key]);
// Usually you have to do this
move_uploaded_file($tmp_name, "some/real/dir");
}
}

Issue with adding to cart with json and php

I am trying to make a simple shop cart and add products from my modal to it by submitting the values with onclick add to cart function
Inside my details modal I have a form with option value attributes
<form action="add_cart.php" method="post" id="add_product_form">
<input type="hidden" name ="product_id" value ="<?=$id;?>">
<input type="hidden" name="available" id="available" value ="">
<div class="form-group">
<div class="large-3 columns">
<label for="quantity">Quantity:</label>
<input type="number" class="form-control" id="quantity" name="quantity">
</div>
</div>
<div class="large-3 columns">
<label for="size">Size:</label>
<select name="size" id="size" class="form-control">
<option value=""></option>
<?php foreach($size_array as $string) {
$string_array = explode(':', $string);
$size = $string_array[0];
$available = $string_array[1];
echo '<option value="'.$size.'" data‐available="'.$available.'">'.$size.' ('.$available.'Available)</option>';
}?>
I send the user inputs from my modal with Ajax Function add_to_cart with method post to do the processing, ajax redirects me back to products page.
I get "was added to card" from add_cart.php
code line:
$_SESSION['success_launch'] = $product['title']. 'was added to your cart.';
But only empty strings inserted inside my database table cart
Inside my developer tools in browser I am getting Notice: Undefined index: product_id in add_cart.php on line 6 , also size ,available and quantity are also undefined. I can't find the solution to it.
This is what I tried in add_cart.php :
<?php
require_once $_SERVER['DOCUMENT_ROOT'].'/EcomApp/konfiguracija.php';
require_once $_SERVER['DOCUMENT_ROOT'].'/EcomApp/config.php';
$product_id = sanitize($_POST['product_id']);
$size = sanitize($_POST['size']);
$available = sanitize($_POST['available']);
$quantity = sanitize($_POST['quantity']);
$item = array();
$item[] = array (
'id' => $product_id,
'size' => $size,
'quantity' => $quantity,
);
$domain = ($_SERVER['HTTP_HOST'] != 'localhost')?'.'.$_SERVER['HTTP_HOST']:false;
$query = $veza->prepare("SELECT * FROM products WHERE id = '{$product_id}'");
$query ->execute();
$product = $query->fetch(PDO::FETCH_ASSOC);
$_SESSION['success_launch'] = $product['title']. 'was added to your cart.';
//check does cookie cart exist
if($cart_id != ''){
$cartQ= $veza->prepare("SELECT * FROM cart WHERE id = '{$cart_id}'");
$cart = $cartQ->fetch(PDO::FETCH_ASSOC);
$previous_items = json_decode($cart['items'],true);
$item_match = 0;
$new_items = array();
foreach ($prevous_items as $pitem){
if($item[0]['id']==$pitem['id'] && $item[0]['size'] == $pitem['size']){
$pitem ['quantity']= $pitem['quantity']+$item[0]['quantity'];
if ($pitem['quantity']>$available){
$pitem['quantity'] = $available;
}
$item_match = 1;
}
$new_items[] = $pitem;
}
if($item_match != 1){
$new_items = array_merge($item,$previous_items);
}
$items_json = json_encode($new_items);
$cart_expire = date("Y-m-d H:i:s", strtotime("+30 days"));
$something=$veza->prepare("UPDATE cart SET items = '{$items_json}',expire_date= '{$cart_expire}'WHERE id ='{$cart_id}'");
$something ->execute();
setcookie(CART_COOKIE,'',1,'/',$domain,false);
setcookie(CART_COOKIE,$cart_id,CART_COOKIE_EXPIRE,'/',$domain,false);
}else {
//add cart inside database
$items_json = json_encode($item);
$cart_expire = date("Y-m-d H:i:s",strtotime("+30 days"));
$smth=$veza->prepare("INSERT INTO cart (items,expire_date) VALUES ('{$items_json}','{$cart_expire}')");
$smth->execute();
$cart_id = $veza>lastInsertId();
setcookie(CART_COOKIE,$cart_id,CART_COOKIE_EXPIRE,'/',$domain,false);
}
?>
That warning message means that there was an attempt to access keys in an array that do not exist.
To see the content of the $_POST array, try to do:
<?php
var_dump($_POST);
If it's empty, most probably you're using the wrong form method or the wrong HTTP method. Try this:
<?php
var_dump($_GET);
You may also debug HTTP messages using the browser development tools or something like Insomnia.
Anyway, always check if the keys exist before trying to use them:
<?php
$requiredKeys = ['product_id', 'size', 'available', 'quantity'];
foreach ($requiredKeys as $key) {
if (!isset($_POST[$key])) {
// handle error here
}
}
ADDED:
Make this change:
<?php
$requiredKeys = ['product_id', 'size', 'available', 'quantity'];
foreach ($requiredKeys as $key) {
if (!isset($_POST[$key])) {
http_response_code(400);
header('Content-Type: application/json');
echo json_encode(
[
'errorMsg' => "Missing key: $key",
'missingKey' => $key,
'receivedPost' => $_POST,
]
);
die();
}
}
require_once $_SERVER['DOCUMENT_ROOT'].'/EcomApp/konfiguracija.php';
require_once $_SERVER['DOCUMENT_ROOT'].'/EcomApp/config.php';
$product_id = sanitize($_POST['product_id']);
// The rest of the code
Keep the added validation code. Never assume $_POST is not empty.
I also noticed there's something wrong here:
var data = jQuery('add_product_from').serialize();
It should have been something like this:
var data = jQuery('#add_product_from').serialize();
Notice that I added the "#". You were sending an empty POST data.
I believe it's better to put the attribute "id" in all the "input" fields, fetch each of their values, check that was done successfully and use the values to build an object that could be used by the jQuery.ajax function. If you have done that, validating everything, most probably you would have easily noticed the mistake.
ADDED
Also, if you read the jQuery.ajax documentation, you'll notice that the success function can have parameters. Add at least the first one in order to receive the response data. Use it to check if there's an unexpected response and debug.

Uploading images and inserting filename to MySQL

xxxHow can I fix this script so that it actually posts 3 separate images rather than the same image 3 times. Any help would be much appreciated. I will provide the code html code to encase that's relevant.
html:
<form method="post" action="insert.php" enctype="multipart/form-data">
<input type="text" name="caseName"><br>
<input type="file" name="upload[]"/>
<input type="file" name="upload[]"/>
<input type="file" name="upload[]"/>
<input type="submit" value="Submit" >
</form>
php:
if ( isset( $_FILES['upload'] ) ) {
$name_array = $_FILES['upload']['name'];
$tmp_name_array = $_FILES['upload']['tmp_name'];
for ( $i = 0; $i < count( $name_array ); $i++ ) {
if ( move_uploaded_file( $tmp_name_array[$i], "uploaded/" . $name_array[$i] ) ) {
echo $name_array[$i];
} else {
echo "failed";
}
}
$dsn = 'mysql:host=localhost;dbname=GLO12408958DB';
$username = 'root';
$password = 'yt987210d';
//
// DB connection was made
//
$pdo = new PDO($dsn, $username, $password);
//loop over array to get names. Make sure we have actual content.
if ( count( $name_array ) > 0 && $name_array !== false ) {
//Prepare query
$statement = $pdo->prepare( 'INSERT INTO caseStudies(caseImage,caseImage2,caseImage3) VALUES (?,?,?)' );
//use a different index in the event that the numeric keys in the name array are not ordered correctly
$index = 1;
foreach ( $name_array as $key => $filename ) {
$statement->bindParam( $index, $filename, PDO::PARAM_STR );
$index++;
}
$statement->execute();
//etc....
}
}
According to the manual, bindParam() "Binds a PHP variable to a corresponding named or question mark placeholder in the SQL statement that was used to prepare the statement. Unlike PDOStatement::bindValue(), the variable is bound as a reference and will only be evaluated at the time that PDOStatement::execute() is called."

Categories