I've noticed when uploading multiple files using php, that the array contains data for all input fields from the form.
Suppose I have a from with 3 input fields, and a user were to upload only 2 files, how can I pick out only those two files from the array, maybe using some array function or anything else, so I can only loop thru those files.
I was trying using array_filer on tmp_name but cannot figure how to proceed.
if($_FILES && isset($_POST['handle'])) {
$numFiles = count(array_filter($_FILES['file']['tmp_name']));
if( $numFiles <= 2 ) {
// files that were uploaded will not have a blank value
$filesUploaded = array_filter($_FILES['file']['tmp_name']);
print_r($filesUploaded);// for testing
// loop through the above array
foreach($filesUploaded as $key) {// stuck
//echo each files attributes
echo $_FILES['file']['tmp_name'][$key].'<br>';
echo $_FILES['file']['name'][$key].'<br>';
echo $_FILES['file']['type'][$key].'<br>';
echo $_FILES['file']['size'][$key].'<br>';
echo $_FILES['file']['error'][$key].'<br>';
// proceed with the rest of the processing
}
} else {
echo 'Too may files uploaded';
}
} else {
echo 'Error A';
}
you are expecting like this?
To check whether the file uploaded or not:
if(is_uploaded_file($_FILES['image']['tmp_name'])) {}
Edited:
$fileUploads=$_FILES['file']['tmp_name'];
$countUpload=0;
foreach($fileUploads as $fileUpload){
if($countUpload>2) {
echo $_FILES['file']['tmp_name'];
//move_upload_file
}
$countUpload=$countUpload+1;
}
Check error status:
if ($_FILES['file']['error'][$key] == 0) {
echo $_FILES['file']['tmp_name'][$key];
}
Related
First off, the upload folder is given 777, and my old upload script works, so the server accepts files. How ever this is a new destination.
I use krajee bootstrap upload to send the files. And I receive a Jason response. The error seems to be around move uploaded file. I bet it's a simple error from my side, but I can't see it.
<?php
if (empty($_FILES['filer42'])) {
echo json_encode(['error'=>'No files found for upload.']);
// or you can throw an exception
return; // terminate
}
// get the files posted
$images = $_FILES['filer42'];
// a flag to see if everything is ok
$success = null;
// file paths to store
$paths= [];
// get file names
$filenames = $images['name'];
// loop and process files
for($i=0; $i < count($filenames); $i++){
$ext = explode('.', basename($filenames[$i]));
$target = "uploads" . DIRECTORY_SEPARATOR . md5(uniqid()) . "." . array_pop($ext);
if(move_uploaded_file($_FILES["filer42"]["tmp_name"][$i], $target)) {
$success = true;
$paths[] = $target;
} else {
$success = false;
break;
}
}
// check and process based on successful status
if ($success === true) {.
$output = [];
$output = ['uploaded' => $paths];
} elseif ($success === false) {
$output = ['error'=>'Error while uploading images. Contact the system administrator'];
// delete any uploaded files
foreach ($paths as $file) {
unlink($file);
}
} else {
$output = ['error'=>'No files were processed.'];
}
// return a json encoded response for plugin to process successfully
echo json_encode($output);
?>
I think field name is the issue. Because you are getting image name with filer42 and upload time, you are using pictures.
Please change
$_FILES["pictures"]["tmp_name"][$i]
to
$_FILES["filer42"]["tmp_name"][$i]
And check now, Hope it will work. Let me know if you still get issue.
The error is not in this script but in the post.
I was using <input id="filer42" name="filer42" type="file">
but it have to be <input id="filer42" name="filer42[]" type="file" multiple>
as the script seems to need an arrey.
It works just fine now.
I know this subject already exist but in my case is a little more difficult.
I'm reading .EDI files (current succeed) on PHP, the process:
1.- I upload a .edi file from a html form.
2.- I send those attributes from the form to read on my php code.
I got the code like this:
if(isset($_FILES['ufile']['name'])){
$tmpName = $_FILES['ufile']['tmp_name'];
$newName = "" . $_FILES['ufile']['name'];
if(!is_uploaded_file($tmpName) ||
!move_uploaded_file($tmpName, $newName)){
echo "<table><tr><td><strong>Failed to read file ".$_FILES['ufile']['name']."</strong></td></tr></table>";
} else {
echo "<br>";
//coloca o conteudo do arquivo para a variavel $arquivo
$ponteiro = fopen ($_FILES['ufile']['name'],"r");
$arquivo = '';
while (!feof ($ponteiro)) {
$arquivo = $arquivo.fgets($ponteiro,4096);
}
fclose ($ponteiro);
if (unlink($_FILES['ufile']['name']) != 1) echo "Erro ao deletar arquivo!";
$padrao = fnc_resgata_padrao($arquivo);
if ($padrao == "COARRI"){
$a = fnc_processa_coarri(trim($arquivo));
prc_mostra_coarri($a);
}
elseif ($padrao == "CODECO") {
$a = fnc_processa_codeco(trim($arquivo));
prc_mostra_codeco($a);
}
else {
echo "<table><tr><td><strong>Invalid file</strong></td></tr></table>";
}
}
} else {
echo "You need to select a file. Please try again.";
}
The problem is, in this way only read the first line of the .EDI file and not all lines. I'm trying to understand that i must print an array but i don't know how to do it because my $a has the values i'm interested.
If the post is hard to understand, please let me know.
update 1
I just deleted some lines of the code, nothing important.
EDIT: got it working, but could still use help. Please see below in edit section.
I've searched all over, but this is really confusing me.
I have a form that allows for multiple file uploads. Each file input is named "track[]" so that way it can get associated into an array. When the form is submitted, I set the file information into an array here:
private $tracks = [];
public function setTracks () {
$length = count($_FILES['track']['name']);
for ($i=0; $i < $length; $i++) {
$this->tracks[$i] = ["file_temp" => $_FILES['track']['tmp_name'][$i],
"file_name" => $_FILES['track']['name'][$i],
"file_size" => $_FILES['track']['size'][$i],
"file_type" => $_FILES['track']['type'][$i],
"target_path" => "tracks/" . $_FILES['track']['name'][$i],
"file_error" => $_FILES['track']['error'][$i]];
}
}
This creates the array just fine, but I'm finding it difficult trying to actually save the file by getting the information I need from this array.
This is my rather basic method for uploading images. How can I adapt this for uploading tracks?
public function uploadImg () {
if ($this->file_size > $this->img_max_size) {
echo "The file size is too large. Please compress it and try again.";
}
if (move_uploaded_file($this->file_temp, "../../" . $this->target_path)) {
echo "The image ". $this->file_name . " has been uploaded successfully!";
}
else {
echo $this->file_error . "There was an error uploading the image, please try again!";
}
}
By the way, I think a foreach loop would be better in both my setTracks and my new uploadTracks methods I'm trying to make, rather than the for loop I am currently implementing, but I wasn't able to figure out how to use one in this case.
EDIT: I'm not sure exactly what I did, but I got this to work. Still, if somebody could help me change my for loop to a foreach it would be greatly appreciated. Here's my method that handles the upload:
public function uploadTrack () {
$length = count($this->tracks);
for ($i=0; $i < $length; $i++) {
if ($this->file_size > $this->track_max_size) {
echo "The file size is too large. Please compress it and try again.";
}
else if (move_uploaded_file($this->tracks[$i]["file_temp"], "../../" . $this->tracks[$i]['target_path'])) {
echo "The image ". $this->file_name . " has been uploaded successfully!";
}
else {
echo $this->file_error . "There was an error uploading the image, please try again!";
}
}
}
I want to copy set of uploaded files from one folder to another folder.From the below code, all the files in one folder is copied.It takes much time. I want to copy only the currently uploaded file to another folder.I have some idea to specify the uploaded files and copy using for loop.But I don't know to implement.I am very new to developing.Please help me.Below is the code.
<?php
// connect to the database
include('connect-db.php');
if (isset($_POST['submit']))
{
// get form data, making sure it is valid
$udate = mysql_real_escape_string(htmlspecialchars($_POST['udate']));
$file_array=($_FILES['file_array']['name']);
// check to make sure both fields are entered
if ($udate == '' || $file_array=='')
{
// generate error message
$error = 'ERROR: Please fill in all required fields!';
// if either field is blank, display the form again
renderForm($udate, $file_array, $error);
}
else
{
$udate = mysql_real_escape_string(htmlspecialchars($_POST['udate']));
if(isset($_FILES['file_array']))
{
$name_arrray=$_FILES['file_array']['name'];
$tmp_name_arrray=$_FILES['file_array']['tmp_name'];
for($i=0;$i <count($tmp_name_arrray); $i++)
{
if(move_uploaded_file($tmp_name_arrray[$i],"test_uploads/".str_replace(' ','',$name_arrray[$i])))
{
// save the data to the database
$j=str_replace(' ','',$name_arrray[$i]);
echo $j;
$udate = mysql_real_escape_string(htmlspecialchars($_POST['udate']));
$provider = mysql_real_escape_string(htmlspecialchars($_POST['provider']));
$existfile=mysql_query("select ubatch_file from batches");
while($existing = mysql_fetch_array( $existfile)) {
if($j==$existing['ubatch_file'])
echo' <script>
function myFunction() {
alert("file already exists");
}
</script>';
}
mysql_query("INSERT IGNORE batches SET udate='$udate', ubatch_file='$j',provider='$provider',privilege='$_SESSION[PRIVILEGE]'")
or die(mysql_error());
echo $name_arrray[$i]."uploaded completed"."<br>";
$src = 'test_uploads';
$dst = 'copy_test_uploads';
$files = glob("test_uploads/*.*");
foreach($files as $file){
$file_to_go = str_replace($src,$dst,$file);
copy($file, $file_to_go);
/* echo "<script type=\"text/javascript\">
alert(\"CSV File has been successfully Uploaded.\");
window.location = \"uploadbatches1.php\"
</script>";*/
}
} else
{
echo "move_uploaded_file function failed for".$name_array[$i]."<br>";
}
}
}
// once saved, redirect back to the view page
header("Location:uploadbatches1.php");
}
}
else
// if the form hasn't been submitted, display the form
{
renderForm('','','');
}
?>
To copy only the uploaded files, there is only a slight change in the coding which I have made. That is instead of using "." from one folder, I passed the array value. So that only the files which are uploaded will be copied to the new folder instead of copying everything which takes long time.Below is the only change made to do:
$files = glob("test_uploads/$name_arrray[$i]");
how can I check that user has selected at-least one file for upload in below code ?
i have tried with in_array, isset, !empty functions but no success
please note that userfile input is array in html
if(!empty($_FILES['userfile']['tmp_name'])){
$upload_dir = strtolower(trim($_POST['name']));
// Create directory if it does not exist
if(!is_dir("../photoes/". $upload_dir ."/")) {
mkdir("../photoes/". $upload_dir ."/");
}
$dirname = "../photoes/".$upload_dir;
for($i=0; $i < count($_FILES['userfile']['tmp_name']);$i++)
{
// check if there is a file in the array
if(!is_uploaded_file($_FILES['userfile']['tmp_name'][$i]))
{
$messages[] = 'No file selected for no. '.$i.'field';
}
/*** check if the file is less then the max php.ini size ***/
if($_FILES['userfile']['size'][$i] > $upload_max)
{
$messages[] = "File size exceeds $upload_max php.ini limit";
}
// check the file is less than the maximum file size
elseif($_FILES['userfile']['size'][$i] > $max_file_size)
{
$messages[] = "File size exceeds $max_file_size limit";
}
else
{
// copy the file to the specified dir
if(#copy($_FILES['userfile']['tmp_name'][$i],$dirname.'/'.$_FILES['userfile']['name'][$i]))
{
/*** give praise and thanks to the php gods ***/
$messages[] = $_FILES['userfile']['name'][$i].' uploaded';
}
}
}
}else{
$messages[] = 'No file selected for upload, Please select atleast one file for upload';
dispform();
}
Here's how I do it its a couple of if's and I use a for loop as I allow multiple file uploads from a single drop down but its the if's that are more important to you
$uploaded = count($_FILES['userfile']['name']);
for ($i=0;$i<$uploaded;$i++) {
if (strlen($_FILES['userfile']['name'][$i])>1) {
// file exists so do something
} else {
//file doesn't exist so do nothing
}
}
You'll note I compare against the name element of the global $_FILES this is because you should never be able to upload a file without a name which also applies for no file uploaded
Don't do it client side thats a dumb place to do validation as the user can simply turn js processing off in the browser or it can be blocked by certain addons etc or intercepted and altered via firebug and various browser search hijacking toolbars etc.
Anything like this should always be done server side!
finally I found the answer, I am giving it here for other users,
I have 5 keys in html input array so array index is up to 4
if(!empty($_FILES['userfile']['tmp_name'][0]) or !empty($_FILES['userfile']['tmp_name'][1]) or !empty($_FILES['userfile']['tmp_name'][2]) or !empty($_FILES['userfile']['tmp_name'][3]) or !empty($_FILES['userfile']['tmp_name'][4])){
//at-least one file is selected so proceed to upload
}else{
//no file selected, notify user
}
There are several methods of doing this with PHP (e.g. Check if specific input file is empty), but with JS it's faster and less expensive on the server. Using jQuery you can do this:
$.fn.checkFileInput = function() {
return ($(this).val()) ? true : false;
}
if ($('input[type="file"]').checkFileInput()) {
alert('yay');
}
else {
alert('gtfo!');
}