how to count number of files which already exists in a folder - php

In a filemanagement, for moving files to another folder, i am trying to count the number of files which already exists in a folder.
foreach($checkboxfiles as $checkboxfile) {
$src_file = $checkboxfile;
$fileName = basename($src_file);
$new_dest = $_POST['cbdestination'];
/* New path for this file */
$dest_file = $MainFolderName.'/'. $new_dest . '/' . $fileName;
echo count(file_exists($dest_file)); //this should give me the number of files which already exists
As 2 files are already exists, the echo produces
11
11
as output.
How can i achieve the number 2 as output?

You're using count wrong. file_exists returns true or false. count is used for counting arrays.
Ir order to achieve what you want you can do:
$count = 0;
foreach($checkboxfiles as $checkboxfile) {
$src_file = $checkboxfile;
$fileName = basename($src_file);
$new_dest = $_POST['cbdestination'];
/* New path for this file */
$dest_file = $MainFolderName.'/'. $new_dest . '/' . $fileName;
if(file_exists($dest_file)){
$count++;
}
}
echo $count;

You can count number of files in a folder by FilesystemIterator(requires PHP 5 >= 5.3.0, PHP 7)
$fi = new FilesystemIterator('directory/location', FilesystemIterator::SKIP_DOTS);
printf("Number of files: %d ", iterator_count($fi));

Related

PHP file_exists is not recognizing a file name with a version number

So I apologize if this is a duplicate question but I haven't found an answer. Below I have a bit of PHP code that doesn't work like expected.
Basically i'm performing a file upload to the server, the first conditional returns true, hits the foreach loop and executes the second conditional and renames the file with the version number
the loop continues on but the second conditional never evaluates to true so the counter is never updated and the file is pushed to the server with a duplicate name.
the original file name is: file name.pdf
the second file name is: file name_2.pdf
the third file name is: file name_2.pdf
why is it not evaluating the file exists as true????
$dir = new DirectoryIterator(dirname($file_path));
$counter = 1;
if (file_exists($file_path . "/" . $filename)) {
foreach ($dir as $fileinfo) {
if (file_exists($file_path . "/" . $filename)) {
eo($filename);
$counter += 1;
$filename = pathinfo($filename, PATHINFO_FILENAME)."_$counter.".strtolower(pathinfo($filename, PATHINFO_EXTENSION));
}
}
}
Remove the first if (file_exists($file_path . "/" . $filename)) {...} and use $fileinfo inside the second if .

PHP - include files from array only if all exist in directory

I'm trying to create a script for including (through require_once) multiple files, but I'm expecting from it following behavior:
all file names of required files are defined as values in array
script check if all files from array exist in given directory
if yes, require them and continue (only if each of them exist)
if no, terminate script and show error message (if any file is missing)
UPDATE
After taking a closer look at my original script I found why it didn't work. Second IF statement ($countMissing == 0) was inside FOR loop and it produced empty arrays for files which were found. Taking that IF statement out of the loop sorted the problem.
WORKING VERSION (with few tiny modifications):
// Array with required file names
$files = array('some_file', 'other_file', 'another_file');
// Count how many files is in the array
$count = count($files);
// Eampty array for catching missing files
$missingFiles = array();
for ($i=0; $i < $count; $i++) {
// If filename is in the array and file exist in directory...
if (in_array($files[$i], $files) && file_exists(LIBRARIES . $files[$i] . '.php')) {
// ...update array value with full path to file
$files[$i] = LIBRARIES . $files[$i] . '.php';
} else {
// Add missing file(s) to array
$missingFiles[] = LIBRARIES . $files[$i] . '.php';
}
}
// Count errors
$countMissing = count($missingFiles);
// If there was no missing files...
if ($countMissing == 0) {
foreach ($files as $file) {
// ...include all files
require_once ($file);
}
} else {
// ...otherwise show error message with names of missing files
echo "File(s): " . implode(", ", $missingFiles) . " wasn't found.";
}
If this thread won't be deleted I hope it will help somebody.
Try this:
$files = array(
'some_file',
'other_file',
'another_file',
);
// create full paths
$files = array_map(function ($file) {
return ROOT_DIR . $file . '.php')
}, $files);
// find missing files
$missing = array_filter($files, function ($file) {
return !file_exists($file);
});
if (0 === count($missing)) {
array_walk($files, function ($file) {
require_once $file;
});
} else {
array_walk($missing, function ($file) {
echo "File: " . $file " wasn't found.";
});
}
For reference, see:
http://php.net/manual/en/function.array-map.php
http://php.net/manual/en/function.array-filter.php
http://php.net/manual/en/function.array-walk.php
Try this, prevent loop inside the loop.
for ($i=0; $i < $count; $i++) {
// If filename is in the array but file not exist in directory...
if (in_array($files[$i], $files) && !file_exists(ROOT_DIR . $files[$i] . '.php')) {
// ...add name of missing file to error array
$errors[] = $files[$i];
}
else{
require_once (ROOT_DIR . $file[$i] . '.php');
}
}
The code from localheinz and jp might be fine, but I wouldn't code things like that because it makes things complicated. Assuming you don't want a list of missing files (which would be slightly different) I'd do it like this:
$filesOK=true;
foreach($files as $file)
{
$path = ROOT_DIR . $file . ".php";
if(!file_exists($path ))
{
$filesOK=false; // we have a MIA
break; // quit the loop, one failure is enough
}
}
if($filesOK)
foreach($files as $file)
require_once($file);
else
echo "We have a problem";
For me this is much easier to see at a glance. Easier to debug, and the CPU is going to do the same job one way or anther. Probably not much difference in execution speed - if that even mattered.
If you need the list of missing files, then:
$filesOK=true;
foreach($files as $file)
{
$path = ROOT_DIR . $file . ".php";
if(!file_exists($path)) // assume each file is given with proper path
{
$filesOK=false; // we have a MIA
$mia[]=$path; // or $file if you just want the name
}
}
if($filesOK)
foreach($files as $file)
require_once($file);
else
{
if(is_array(#$mia)) // I always make sure foreach is protected
foreach($mia as $badfile) // even if it seems obvious that its ok
echo "Missing in action: $badfile<br>";
}

Losing variable value when trying to copy file using mailReader.php

I'm using the mailReader script found here: https://github.com/stuporglue/mailreader
I am trying to copy the file(s) after upload to another folder.
The file(s) upload correctly to the folder where the script resides.
When I try to run a copy command, the filename variable is empty.
Here is the portion of the code I am working with: The last three lines are what I added.
private function saveFile($filename,$contents,$mimeType = 'unknown'){
$filename = preg_replace('/[^a-zA-Z0-9_-]/','_',$filename);
$unlocked_and_unique = FALSE;
while(!$unlocked_and_unique){
// Find unique
$name = time() . "_" . $filename;
$name = substr_replace($name,".pdf",-4); // added 1-19-2016
while(file_exists($this->save_directory . $name)) {
$name = time() . "_" . $filename;
$name = substr_replace($name,".pdf",-4);
}
// Attempt to lock
$outfile = fopen($this->save_directory.$name,'w');
if(flock($outfile,LOCK_EX)){
$unlocked_and_unique = TRUE;
}else{
flock($outfile,LOCK_UN);
fclose($outfile);
}
}
fwrite($outfile,$contents);
fclose($outfile);
if (copy($this->save_directory.$name, "/attachments/" . TRANS_ID . "/". $name)) {
unlink( $this->save_directory.$name );
}
I receive confirmation by email that the file(s) are uploaded, then another email with the error message.
Warning: copy(/attachments/W7652222-546/1453406138_residential-print_from_td.pdf): failed to open stream: No such file or directory in /home/myhost/public_html/mailreader/mailReader.php on line 224
224 being the line number of my added code.
The source filename is missing from in front of /attachments...
Anyone have any thoughts?
$name is defined in the while loop and may not be accessible on the upper scopes my suggestion is to change your code to this:
private function saveFile($filename,$contents,$mimeType = 'unknown'){
$filename = preg_replace('/[^a-zA-Z0-9_-]/','_',$filename);
$unlocked_and_unique = FALSE;
$name = '';
while(!$unlocked_and_unique){
// Find unique
$name = time() . "_" . $filename;
$name = substr_replace($name,".pdf",-4); // added 1-19-2016
while(file_exists($this->save_directory . $name)) {
$name = time() . "_" . $filename;
$name = substr_replace($name,".pdf",-4);
}
// Attempt to lock
$outfile = fopen($this->save_directory.$name,'w');
if(flock($outfile,LOCK_EX)){
$unlocked_and_unique = TRUE;
}else{
flock($outfile,LOCK_UN);
fclose($outfile);
}
}
fwrite($outfile,$contents);
fclose($outfile);
if (copy($this->save_directory.$name, "/attachments/" . TRANS_ID . "/". $name)) {
unlink( $this->save_directory.$name );
}
I hope this solves your problem
I ended up defining a constant of email_id in the private function saveToDb, then running a script after everything else is finished to query the table using the email_id and looping through the records moving the files.

Copy file to folder if exist +1

I'm new in php.
Every 17 seconds my php code generates id1.php and id2.php in this folder:"sitename.com/"
So, every 17 seconds i've got this:
sitename.com/master.php
sitename.com/id1.php
sitename.com/id2.php
sitename.com/filebag/id1.php
sitename.com/filebag/id2.php
sitename.com/filebag/id3.php
after script generates id1.php and id2.php i need to copy this files to sitename/filebag/ and if filename exist add +1. so in the end, i must get this situation:
sitename.com/
sitename.com/master.php
sitename.com/filebag/id1.php
sitename.com/filebag/id2.php
sitename.com/filebag/id3.php
sitename.com/filebag/id4.php
sitename.com/filebag/id5.php and so on...
i use master.php to do a replace
<?php
$idname = "id1";
copy ("./id1.php","./filebag/$idname.php");
?>
question is how can i rename file if filename exist in this folder "sitename.com/filebag/"
This code delivers what you want:
<?php
$stringName = "id";
$numName = "1";
$file_orig = './' . $stringName . $numName . '.php';
$file_dest = './filebag/' . $stringName . $numName . '.php';
if(file_exists($file_dest))
{
$count = (int)$numName;
while(file_exists($file_dest))
{
$count = $count + 1;
$file_dest = './filebag/' . $stringName . $count . '.php';
}
}
copy ($file_orig, $file_dest);
?>

Filepaths and Recursion in PHP

I'm trying to recursively iterate through a group of dirs that contain either files to upload or another dir to check for files to upload.
So far, I'm getting my script to go 2 levels deep into the filesystem, but I haven't figured out a way to keep my current full filepath in scope for my function:
function getPathsinFolder($basepath = null) {
$fullpath = 'www/doc_upload/test_batch_01/';
if(isset($basepath)):
$files = scandir($fullpath . $basepath . '/');
else:
$files = scandir($fullpath);
endif;
$one = array_shift($files); // to remove . & ..
$two = array_shift($files);
foreach($files as $file):
$type = filetype($fullpath . $file);
print $file . ' is a ' . $type . '<br/>';
if($type == 'dir'):
getPathsinFolder($file);
elseif(($type == 'file')):
//uploadDocsinFolder($file);
endif;
endforeach;
}
So, everytime I call getPathsinFolder I have the basepath I started with plus the current name of the directory I'm scandirring. But I'm missing the intermediate folders in between. How to keep the full current filepath in scope?
Very simple. If you want recursion, you need to pass the whole path as a parameter when you call your getPathsinFolder().
Scanning a large directory tree might be more efficient using a stack to save the intermediate paths (which would normally go on the heap), rather than use much more of the system stack (it has to save the path as well as a whole frame for the next level of the function call.
Thank you. Yes, I needed to build the full path inside the function. Here is the version that works:
function getPathsinFolder($path = null) {
if(isset($path)):
$files = scandir($path);
else: // Default path
$path = 'www/doc_upload/';
$files = scandir($path);
endif;
// Remove . & .. dirs
$remove_onedot = array_shift($files);
$remove_twodot = array_shift($files);
var_dump($files);
foreach($files as $file):
$type = filetype($path . '/' . $file);
print $file . ' is a ' . $type . '<br/>';
$fullpath = $path . $file . '/';
var_dump($fullpath);
if($type == 'dir'):
getPathsinFolder($fullpath);
elseif(($type == 'file')):
//uploadDocsinFolder($file);
endif;
endforeach;
}

Categories