PHP cannot upload multiple images - php

I have a form in which I want to upload at most five images. The name and extension of the images are supposed to be inserted in the database table 'images' and then uploaded to the _uploads/name_of_the_album/ directory.
The problem is, when I choose some images and hit upload, only the first image is uploaded correctly, the other images fail.
Here is my code:
if(isset($_FILES['image']) === true){
$files = $_FILES['image'];
$allowed_ext = array('jpg', 'jpeg', 'png', 'gif');
$album_id = (int)$_GET['album_id'];
$album_name = $_GET['album_name'];
for($i=0; $i<count($files['name']); $i++){
$name = $files['name'][$i];
$tmp_name = $files['tmp_name'][$i];
$size = $files['size'][$i];
$ext = explode('.', $files['name'][$i]);
$ext = strtolower(end($ext));
$img_name = explode('.', $files['name'][$i]);
$img_name = strtolower(current($img_name));
//do some testing echos to see the result
//echo $img_name."<br>";
//here i'm going to add some validation as soon as
// i fix the multi-upload problem
//insert image into database
$query_insert_image = "INSERT INTO `images` (album_id, image_name, image_ext) VALUES ({$album_id}, '{$img_name}', '{$ext}') ";
$insert_image = mysql_query($query_insert_image, $connection) or die(mysql_error());
if(mysql_affected_rows() == 1){
move_uploaded_file($tmp_name, '../_uploads/'.$album_name.'/'.$name);
}
//redirect
redirect_to("view_album.php?succeed=1");
}//end the for loop
//echo '<pre>',print_r($files, true),'</pre>';
}
And here is some of the code of the form:
<form action="" method="post" enctype="multipart/form-data" name="formUploadImages" id="formUploadImages">
<p>
<label for="image">Choose one or more Image(s):</label><br />
<input type="file" name="image[]" id="image" /><br />
<input type="file" name="image[]" id="image" /><br />
<input type="file" name="image[]" id="image" /><br />
<input type="file" name="image[]" id="image" /><br />
<input type="file" name="image[]" id="image" />
</p>
......
Any ideas what I'm doing wrong?

I think you're cutting the branch from under your own feet.
redirect_to("view_album.php?succeed=1");
Redirecting means refreshing the page which means the end of execution. When that redirect is triggered after the first for loop ends and first image is uploaded the for will not continue to the next iteration.
And the fix of course is to push that line after the for loop (and never expect anything after a redirect to ever execute - unless the headers are already sent).
Most functions that do what redirect_to() does (it's not a core function it's based on another function header()) also make sure execution stops (have a line calling header() and another line calling die()/exit()).

try this php code ,working for me:
for($i=1;$i<6;$i++)
{
if(!empty($_FILES['image_upload'.$i])):
$target = "images/".$_FILES['image_upload'.$i]['name'];
$image_upload.= ",".mysql_real_escape_string(($_FILES['image_upload'.$i]['name']));
move_uploaded_file($_FILES['image_upload'.$i]['tmp_name'], $target);
endif;
}
create a folder in your root named "images" ,all the images will be moved in this folder.
html form may be looks like:
<form action="" method="post" enctype="multipart/form-data" name="formUploadImages" id="formUploadImages">
<p>
<label for="image">Choose one or more Image(s):</label><br />
<input type="file" name="image_upload1" id="image_upload1" /><br />
<input type="file" name="image_upload2" id="image_upload2" /><br />
<input type="file" name="image_upload3" id="image_upload3" /><br />
<input type="file" name="image_upload4" id="image_upload4" /><br />
<input type="file" name="image_upload5" id="image_upload5" />
</p>
......
this code is running on my end ,and after some editing as according to your needs may be useful for you.
Happy coding!

foreach($_POST['image'] as $report_id){
$sql="INSERT INTO images (album_id, image_name, image_ext) VALUES ('{$album_id}', '{$report_id}', '{$ext}') ";
$queryExe=mysql_query($sql);
}
replace this code in the place of your code after "//insert image into database" .

http://php.net/manual/en/features.file-upload.multiple.php
Read the Warning block 'Since PHP 5.2.12, the max_file_uploads configuration...'. Maybe that's the problem.
And there are some good examples and maybe You should use foreach instead of for.

1) Create a .htaccess file in the root folder of web server.
2) Put the following code in side the .htaccess file and save it.
php_value upload_max_filesize 20M
php_value post_max_size 20M
php_value max_execution_time 200
php_value max_input_time 200
Now you can upload the file-size up-to 20MB in a simple way using file field in your html form and move_uploaded_file() function available in PHP.

Related

MySQL insert stmt wont loop in file upload foreach loop

The code uploads the files and is supposed to submit the file path to the database so I can use the file paths elsewhere.
All the files upload fine in the loop, but for some reason, after it successfully submits the first MySQL stmt insert, it somehow bypasses the inserts that come after when it goes through the loop again, to upload the next file in the $_FILES[] superglobal
Here is the markup for the form
<?php
session_start();
include 'includes/functions.php';
drawHeader();
echo'
<div class="main_content_container">
';
if ( isset($_SESSION['userId'])) {
$amz_numb = $_GET['amz_numb'];
echo'
<form action="http://Localhost/Tierrashop.ca/includes/upload.php"
method="post" enctype="multipart/form-data">
Send these files
<input name="amz_numb" type="hidden"
value="'. $amz_numb .'"/><br />
<input name="file[]" type="file" /><br />
<input name="file[]" type="file" /><br />
<input name="file[]" type="file" /><br />
<input name="file[]" type="file" /><br />
<input name="file[]" type="file" /><br />
<input name="file[]" type="file" /><br />
<input name="file[]" type="file" /><br />
<input name="file[]" type="file" /><br />
<button type="file">Upload Files</button>
</form>
<a href="http://localhost/Tierrashop.ca/content_upload.php">
<button>Go back to product details... </button></a>
';
} else {
echo '';
}
//close of main content div
echo '</div>';
drawFooter();
?>
PHP file that launches upon form submission
<?php
include 'config.php';
if (isset($_POST['amz_numb'])) {
$uploadlocation = "../product_images/";
$amz_numb = $_POST['amz_numb'];
// Count total files
$countfiles = count($_FILES['file']['name']);
// Looping all files
for ($i = 0; $i < $countfiles; $i++) {
$filename = $_FILES['file']['name'][$i];
// Upload file
move_uploaded_file($_FILES['file']['tmp_name'][$i], $uploadlocation . $filename);
$directory_location = $uploadlocation . basename($filename);
chmod($directory_location, 0644);
//insert amz numb and path into db
$stmt = mysqli_prepare($conn, "INSERT INTO images ( amz_product_code, filepath )
VALUES (?,?)");
mysqli_stmt_bind_param($stmt, 'ss', $amz_numb, $directory_location);
mysqli_stmt_execute($stmt);
mysqli_stmt_close($stmt);
}
mysqli_close($conn);
}
Take a look at this please:
https://www.php.net/manual/en/mysqli-stmt.close.php
The user contributed note might be helpful for your case:
"if you are repeating an statement in an loop using bind_param and so on inside it for a larger operation. i thougt id would be good to clean it with stmt->close. but it broke always with an error after aprox. 250 operations . As i tried it with stmt->reset it worked for me."
This might be the better option: https://www.php.net/manual/de/mysqli-stmt.reset.php
Or - much better - use PDO!
UPDATE: More on PDO
If you don't know how to use the more modern standard "PDO" (if I recall it correctly it stands for "PHP Data Objects") this should be really helpful. I used this myself to make my own database handler.
https://culttt.com/2012/10/01/roll-your-own-pdo-php-class/
The only caveat: The link above is a bit US centric. If you use it like that you will be in trouble if you support other languages in addition to English(US).
In //Define Configuration you should add:
define("DB_CHARSET", "utf8mb4");
Then in the database class itself you should add:
private $charset = DB_CHARSET;
"Set DSN" should consequently be modified like this:
$dsn = 'mysql:host=' . $this->host . ';dbname=' . $this->dbname . ';charset=' . $this->charset;
Apart from these minor changes the example is still very useful.
Yaaaaa, none of that resetting stuff helped.
Figured out you don't have to keep preparing the statement, however not sure if that's what was stopping it.
I had it uploading the file, than was preparing the stmt to then execute.
In the php.ini file I had:
max_file_uploads = 3, which explained why only three files were getting inserted and locking up the script in the loop.
Also I changed post_max_size = 150mb thinking that this allows all those files to be stored in the tmp_name key in the $_FILES superglobal

Not able to upload more than 5 images in PHP

I'm trying to upload some images in my PHP application but I'm unable to do so. After some images, the post doesn't send data. It depends on the file size how many I can send like sometimes it works for 5 images sometimes for 3 images itself it throws this error.
<form action="store.php" method="post" enctype="multipart/form-data">
<div class="form-group">
<label>Top Image:</label><br>
<input type="file" name="topimg" class="form-control-file" style="padding-bottom:15px;">
</div>
<div class="form-group">
<label>Sub Images:</label><br>
<input type="file" name="img[]" class="form-control-file" id="exampleFormControlFile2" multiple required>
</div>
<center>
<button type="submit" class="btn btn-success" name="button">Save</button>
</center>
</form>
This is the form I'm using and it sends data to store.php
$uploaddir = '../../../img/gallery/';
$dirname = "/img/gallery/";
$newname = time() . basename($_FILES['topimg']['name']);
$fileup = $dirname . $newname;
$uploadfile = $uploaddir . $newname;
$img = '';
foreach ($_FILES['img']['name'] as $nam) {
$img = $img.",".$dirname.time().$nam;
}
$img = substr($img,1);
The above part is for setting the name and then the code to insert into my DataBase follows this (I think it's unnecessary so I left it out)
move_uploaded_file($_FILES['topimg']['tmp_name'], $uploadfile);
$count=0;
foreach ($_FILES['img']['name'] as $filename)
{
$tmp=$_FILES['img']['tmp_name'][$count];
$count=$count + 1;
move_uploaded_file($tmp,$uploaddir.time().$filename);
$tmp='';
}
Then this code to upload the files.
So when I try to upload the files it says "Undefined index: topimg" and "Undefined index: img" with errors that relate to these being invalid. I'm I doing the PHP part wrong or is it some setting in the server. I'm using MAMP pro if this info is needed
I think you need to change the upload_max_filesize and post_max_size directives in php.ini. See the php website https://www.php.net/manual/en/ini.core.php#ini.upload-max-filesize for more information on these directives.
To change the php.ini file for mamp pro, check this question.

How to upload multiple files one by one

I need to upload a lot of images at once (e.g. 200 small images) through the browser. I have this code:
<?php
if(isset($_POST['Upload_files']) and $_SERVER['REQUEST_METHOD'] == "POST"){
echo count($_FILES['files']['name']); // Even if I upload more than 20 files, it still displays 20.
$target_directory = "upload/";
foreach ($_FILES['files']['name'] as $file_number => $file_name) {
$file = $_FILES["files"]["tmp_name"][$file_number];
if (mime_content_type($file) != 'image/png' && mime_content_type($file) != 'image/jpeg')
{ $error[] = 'File '.$file_name.' is not in JPG / PNG format!'; continue; }
else
{ if(move_uploaded_file($file, $target_directory.$file_name)) {$count_of_upload_file++;}}
}
}
// If files were uploaded
if($count_of_upload_file != 0){echo 'Your files ('.$count_of_upload_file.' ) were successfully uploaded.';}
// If there was an error
if (isset($error)) {foreach ($error as $display_error) {echo '- '.$display_error.'<br />';}}
?>
<form action="" method="post" enctype="multipart/form-data">
<input type="file" name="files[]" multiple="multiple" accept="image/*">
<input type="submit" name="Upload_files" value="Upload files">
</form>
And it works. However my provider set the 'max_file_uploads' to 20 (and I'm not able to change it). (The Uploadify extension is working for more than 20 files, but I'd like to have my own small solution.) So I presume I need to add here something, which instead of 200 files at once uploads 200 files one by one (or twenty by twenty). But I don't know how to do it. (To use AJAX? -- I never used it, so I really don't know.) Thank you!
If you don't want to use ajax, you need a loop to receive files
for($i = 0; $i < count($_FILES['files']['tmp_name']); $i++){
$tmp = $_FILES['files']['tmp_name'][$i];
$name = md5(microtime());
if(move_uploaded_file($tmp, "dir/$name.jpg")){
echo "Uploaded successfully";
}else{
echo "failed";
}
}
In your form you must name all your input fields as files[], example:
<form action="" method="post" enctype="multipart/form-data">
<input type="file" name="files[]" multiple="multiple" accept="image/*">
<input type="file" name="files[]" multiple="multiple" accept="image/*">
<input type="file" name="files[]" multiple="multiple" accept="image/*">
<input type="submit" name="Upload_files" value="Upload files">
</form>
Or if you want to use ajax here is an example:
Upload multiple image using AJAX, PHP and jQuery

how to count number of uploaded files in php

How can i count the number of uploaded files?
This is my form:
<div id="dragAndDropFiles" class="uploadArea">
<h1>Drop Images Here</h1>
</div>
<form id="sfmFiler" class="sfmform" method="post" enctype="multipart/form-data">
<input type="file" name="file" id="file" multiple />
<input type="submit" name="submitHandler" id="submitHandler" class="buttonUpload" value="Upload">
</form>
and this is the piece of php which uploads the files:
if($_SERVER['REQUEST_METHOD'] == "POST") {
$tmpFilePath = $_FILES['file']['tmp_name'];
$newFilePath = $dir.'/' . $_FILES['file']['name'];
if(move_uploaded_file($tmpFilePath, $newFilePath)) {
echo "xxx files are successfully uploaded";
}
}
In this code you are getting only one file thats why you are getting count result 1. if change your input file name like "file[]"
<input type="file" name="file[]" id="file" multiple />
and then use the below line code you will get your desire result. Cause its needs an array filed to hold the input data.
<?php echo count($_FILES['file']['name']); ?>
Thanks, i tried in my system get the result.
AFriend is correct. The above answers always return 1.
Try:
echo count(array_filter($_FILES['file']['name']))
Worked for me anyway.
_t
Using the array_filter function it works
try
$countfiles = count(array_filter($_FILES['file']['name']));
It returns 0 in case of NULL, 1 in case of 1 file uploaded, etc.
Check this answer
<?php echo count($_FILES['file']['name']); ?>
php multiple file uploads get the exact count of files a user uploaded and not the count of all input fields in the array
You could use the count function:
$no_files = count($_FILES);
If no files are selected and your file count is 1, you can use this line before moving the file:
if (!empty($_FILES['file']['tmp_name'][0])) {
for($i=0;$i<$countfiles;$i++){

var_dump not returning a value

I want to allow a user the upload an image (file) for their profile picture, on my website. They upload the image via an HTML form, but I am having trouble moving the file to the folder I want it to. I don't want to mess with the php.ini file to change the upload path. I want to use move_uploaded_file(). I try and use $tmp= $_FILES['picture']['tmp_name'] and var_dump($tmp), but It keeps returning a value of (0). So, I think the problem has something to do with that. Here is my code,
Here is my HTML:
<form enctype="multipart/form-data" method="post" action="upload_img.php">
<input type="hidden" name="MAX_FILE_SIZE" value="32768"/>
<input type="text" name="name" value=""/>
<input type="file" name="picture" value="picture"/>
<input type="submit" name="submit" value="upload"/>
</form>
And my PHP:
<?php
define('GW_UPLOADPATH', 'images/');
$picture= $_FILES['picture']['name'];
$name= $_POST['name'];
$tmp= $_FILES['picture']['tmp_name'];
var_dump($picture);
var_dump($name);
var_dump($tmp);
$connect= mysqli_connect(//connect params)
or die('error connecting with the database');
$query= "INSERT INTO pics (pic, name) VALUES ('$picture', '$name')";
$target= GW_UPLOADPATH . $picture ;
if (move_uploaded_file($_FILES['picture']['tmp_name'], $target);))
{
mysqli_query($connect, $query)
or die('error with query');
}
?>
Your issue likely has something to do with php's upload_max_filesize and post_max_size. Check those 2 settings in your php.ini and make sure the file you are trying to upload isn't larger than either of them.

Categories