is_dir not working as expected - php

I've got a problem when using is_dir while I iterate over all the files in a certain directory.
The code is kind of small so I think you'll better understand what I mean if I post it:
$files = array();
if ($dir = #opendir($folder)){
while($file = readdir($dir)){
if (is_dir($file)) $files[] = $file;
}
closedir($dir);
}
print_r($files)
It dumps:
( [0] => . )
Otherwise, if I don't check wether the file is a dir by using this code:
$files = array();
if ($dir = #opendir($folder)){
while($file = readdir($dir)){
$files[] = $file;
}
closedir($dir);
}
print_r($files)
It dumps what expected:
( [0] => .. [1] => bla [2] => blablabla [3] =>index.php [4] => styles.css [5] => . )
I guess it's just some noob problem with using the $file var as a parameter but don't know how to make it work.
Thanks for reading!

As Kolink said in the comments, you're probably better off going the glob route, but if you decide to stick with opendir:
The path will be $folder . '/' . $file, not just $file. opendir() returns relative paths. So is_dir is returning false in your loop.
if ($dir = opendir($folder)){
while(false !== ($file = readdir($dir))) {
if ($file == '.' || $file == '..') {
continue;
} else if (is_dir($folder . '/' . $file)) {
$files[] = $file;
}
}
closedir($dir);
}
Also, note the false !==. This is necessary because a folder named "0" would evaluate to false (or a few other edge cases). Also, you'll very rarely actually care about . and .., so that code is in there to filter . and .. out.

Problem is: $file contains only the basename, not the absolute filename. So prepend the path to the folder:
is_dir($folder . '/' . $file)

<? // findfiles.php - what is in directory "videoarchive"
$dir = 'images/videoarchive/'; // path from top
$files = scandir($dir);
$files_n = count($files);
echo '<br>There are '.$files_n.' records in directory '.$dir.'<br>' ;
$i=0;
while($i<=$files_n){
// "is_dir" only works from top directory, so append the $dir before the file
if (is_dir($dir.'/'.$files[$i])){
$MyFileType[$i] = "D" ; // D for Directory
} else{
$MyFileType[$i] = "F" ; // F for File
}
// print itemNo, itemType(D/F) and itemname
echo '<br>'.$i.'. '. $MyFileType[$i].'. ' .$files[$i] ;
$i++;
}
?>

Related

how can i return the names of files in a directory using php

lets say I have a folder on a webhost that is called sebis_files and this folder contains some files, maybe pictures, docs...
I want to return the contents of this folder on a separate page, something like:
$row = get dir host/sebis_files*//everything
for ( $row !== 0){ //for every valid file
echo $row . "<br/>"; //return name of file
}
You can use opendir and readdir. Here's a breakdown:
We use __DIR__ to make the path relative to the directory of the current script, just to be safe:
$dir = __DIR__ . '/sebis_files';
Next we open the directory to read it's entries.
We call readdir, which will return a 'resource' object, or false if $dir is not a readable directory:
if ($dh = opendir($dir))
{
The directory is successfully opened.
We now call readdir on that directory. We use the return value of opendir, the mysterious 'resource' object, that will let PHP know what directory we are reading.
Every time we call readdir it will give us the next entry in the directory. When there are no more entries, readdir will return false:
while ( ($entry = readdir($dh)) !== false)
{
We have read a directory $entry: the name of a file or sub-directory inside $dir. So, it's not a full pathname. Let's print it's name, along with whether it is a directory or a file. We will use is_file and is_dir, but we will need to pass the full pathname (hence "$dir/$entry"):
if ( is_dir( "$dir/$entry" ) )
echo "Directory: $entry<br/>";
else if ( is_file( "$dir/entry" ) )
echo "File: $entry<br/>";
}
we are done with the directory, let's close it to free the resource:
closedir($dh);
}
But what if $dir cannot be opened for reading? Let's print a warning:
else
echo "<div class='warning'>cannot open directory!</div>";
you need is to see this
<?php
$dir = "/tmp";
$dh = opendir($dir);
while (false !== ($filename = readdir($dh))) {
$files[] = $filename;
}
sort($files);
print_r($files);
rsort($files);
print_r($files);
?>
You can do it using the glob function :
$dir = "/your/dir/";
if(file_exists($dir))
{
foreach (glob("$dir*") as $file)
{
if(is_file($file))
{
echo basename($file) . "<br />";
}
}
}

Copy all files from one folder to another Folder using PHP scripts?

Basically, my requirement is, I want to move all files from one folder to another folder using PHP scripts. Any one can help me. I am trying this, but I am getting error
$mydir = dirname( __FILE__ )."/html/images/";
if(!is_dir($mydir)){
mkdir("html/images");
}
// Move all images files
$files = glob("images/*.");
foreach($files as $file){
$file_to_go = str_replace("images/","html/images/",$file);
copy($file, $file_to_go);
}
// images folder creation using php
$mydir = dirname( __FILE__ )."/html/images";
if(!is_dir($mydir)){
mkdir("html/images");
}
// Move all images files
$files = glob("images/*.*");
foreach($files as $file){
$file_to_go = str_replace("images/","html/images/",$file);
copy($file, $file_to_go);
}
Try this :
<?php
$src = 'pictures';
$dst = 'dest';
$files = glob("pictures/*.*");
foreach($files as $file){
$file_to_go = str_replace($src,$dst,$file);
copy($file, $file_to_go);
}
?>
foreach(glob('old_directory/*.*') as $file) {
copy('old_directory/'.$file, 'new_directory/'.$file);
}
Use array_map:
// images folder creation using php
function copyFile($file) {
$file_to_go = str_replace("images/","html/images/",$file);
copy($file, $file_to_go);
}
$mydir = dirname( __FILE__ )."/html/images";
if(!is_dir($mydir)){
mkdir("html/images");
}
// Move all images files
$files = glob("images/*.*");
print_r(array_map("copyFile",$files));
This One Works for me...........
Thanks to this man
http://www.codingforums.com/php/146554-copy-one-folder-into-another-folder-using-php.html
<?php
copydir("admin","filescreate");
echo "done";
function copydir($source,$destination)
{
if(!is_dir($destination)){
$oldumask = umask(0);
mkdir($destination, 01777); // so you get the sticky bit set
umask($oldumask);
}
$dir_handle = #opendir($source) or die("Unable to open");
while ($file = readdir($dir_handle))
{
if($file!="." && $file!=".." && !is_dir("$source/$file"))
copy("$source/$file","$destination/$file");
}
closedir($dir_handle);
}
?>
This should work just fine:
// Get array of all source files
$files = scandir("source");
// Identify directories
$source = "source/";
$destination = "destination/";
// Cycle through all source files
foreach ($files as $file) {
if (in_array($file, array(".",".."))) continue;
// If we copied this successfully, mark it for deletion
if (copy($source.$file, $destination.$file))
{
$delete[] = $source.$file;
}
}
// Delete all successfully-copied files
foreach ($delete as $file)
{
unlink($file);
}
or with rename() and some error checking:
$srcDir = 'dir1';
$destDir = 'dir2';
if (file_exists($destDir)){
if (is_dir($destDir)) {
if (is_writable($destDir)) {
if ($handle = opendir($srcDir)) {
while (false !== ($file = readdir($handle))) {
if (is_file($srcDir . '/' . $file)) {
rename($srcDir . '/' . $file, $destDir . '/' . $file);
}
}
closedir($handle);
} else {
echo "$srcDir could not be opened.\n";
}
} else {
echo "$destDir is not writable!\n";
}
} else {
echo "$destDir is not a directory!\n";
}
} else {
echo "$destDir does not exist\n";
}
You can use this recursice function.
<?php
function copy_directory($source,$destination) {
$directory = opendir($source);
#mkdir($destination);
while(false !== ( $file = readdir($directory)) ) {
if (( $file != '.' ) && ( $file != '..' )) {
if ( is_dir($source . '/' . $file) ) {
copy_directory($source . '/' . $file,$destination . '/' . $file);
}
else {
copy($source . '/' . $file,$destination . '/' . $file);
}
}
}
closedir($directory);
}
?>
Referrence : http://php.net/manual/en/function.copy.php
I had a similar situation where I needed to copy from one domain to another, I solved it using a tiny adjustment to the "very easy answer" given by "coDe murDerer" above:
Here is exactly what worked in my case, you can as well adjust to suit yours:
foreach(glob('../folder/*.php') as $file) {
$adjust = substr($file,3);
copy($file, '/home/user/abcde.com/'.$adjust);
Notice the use of "substr()", without it, the destination becomes '/home/user/abcde.com/../folder/', which might be something you don't want.
So, I used substr() to eliminate the first 3 characters(../) in order to get the desired destination which is '/home/user/abcde.com/folder/'. So, you can adjust the substr() function and also the glob() function until it fits your personal needs. Hope this helps.

How to rename a batch of files in a directory?

I have a bunch of files in a directory that I would like to rename. I have a complete list of existing file names and in the column next to the old name, I have a new name (desired) filename, like below: (the list is in excel so I can apply some syntax to all the rows very easily)
OLD NAME NEW NAME
-------- --------
aslkdjal.pdf asdlkjkl.pdf
adkjlkjk.pdf asdlkjdj.pdf
I would like to keep the old name and old files in their current directory and not disturb them, but just create a copy of the file, with the new filename instead.
Not sure what language to use and how to go about doing this.
http://php.net/manual/en/function.rename.php
<?php
rename("/tmp/tmp_file.txt", "/home/user/login/docs/my_file.txt");
?>
EDIT: in case of copy -
<?php
$file = 'example.txt';
$newfile = 'example.txt.bak';
if (!copy($file, $newfile)) {
echo "failed to copy $file...\n";
}
?>
Something like this should work:
$source = '/files/folder';
$target = '/files/newFolder';
$newnames= array(
"oldfilename" => "newfilename",
"oldfilename1" => "newfilename1",
);
// Copy all files to a new dir
if (!copy($source, $target)) {
echo "failed to copy $source...\n";
}
// Iterate through this dir, rename all files.
$i = new RecursiveDirectoryIterator($target);
foreach (new RecursiveIteratorIterator($i) as $filename => $file) {
rename($filename, $newnames[$filename]);
// You might need to use $file as first parameter, here. Haven't tested the code.
}
RecursiveDirectoryIterator documentation.
Just try with the following example :
<?php
$source = '../_documents/fees';
$target = '../_documents/aifs';
$newnames= array(
"1276.aif.pdf" => "aif.10001.pdf",
"64.aif.20091127.pdf" => "aif.10002.pdf",
);
function recurse_copy($src,$dst) {
$dir = opendir($src);
#mkdir($dst);
while(false !== ( $file = readdir($dir)) ) {
if (( $file != '.' ) && ( $file != '..' )) {
if ( is_dir($src . '/' . $file) ) {
recurse_copy($src . '/' . $file,$dst . '/' . $file);
}
else {
copy($src . '/' . $file,$dst . '/' . $file);
}
}
}
closedir($dir);
}
// Copy all files to a new dir
recurse_copy($source, $target);
// Iterate through this dir, rename all files.
$i = new RecursiveDirectoryIterator($target);
foreach (new RecursiveIteratorIterator($i) as $filename => $file) {
#rename($filename, $target.'/'.$newnames[''.$i.'']);
}
?>
This is pretty easy to do with a shell script. Start with the file list as you presented in files.txt.
#!/bin/sh
# Set the 'line' delimiter to a newline
IFS="
"
# Go through each line of files.txt and use it to call the copy command
for line in `cat files.txt`; do
cp `echo $line | awk '{print $1;}'` `echo $line | awk '{print $2};'`;
done

read files insert text into mysql

myFolderi have thousands of image files that have keyword text for the name. i am trying to read from the list of images and upload the text into a dB field. the problem is that some of the text has utf8 characters like l’Été that show up like this ��t�
how can i read foreign characters so that the accents will insert into the dB field?
this is how im handling it now
function ListFiles($dir) {
if($dh = opendir($dir)) {
$files = Array();
$inner_files = Array();
while($file = readdir($dh)) {
if($file != "." && $file != ".." && $file[0] != '.') {
if(is_dir($dir . "/" . $file)) {
$inner_files = ListFiles($dir . "/" . $file);
if(is_array($inner_files)) $files = array_merge($files, $inner_files);
} else {
array_push($files, $dir . "/" . $file);//$dir = directory name
//array_push($files, $dir);
}
}
}
closedir($dh);
return $files;
}
}
foreach (ListFiles('../../myDirectory') as $key=>$file){
//$file = preg_replace( '#[^\0-\x80]#u',"", $file );
echo $file ."<br />";
}
this is producing the same result
$str = "l’Été";
utf8_decode($str);
echo $str;
This solution may work for you, it will loop through all files in a directoy and then recursivly through any directories found until it ends up with a massive array of files.
Ive added some points you may wish to change, eg either mutli or single dimension arrays ( all depend on if you may want to maintain the folder structure.
and also if you want the file extention to be saved when you save the file name to db.
Code
function recursive_search_dir($dir) {
if ($handle = opendir($dir)) {
while (false !== ($file = readdir($handle))) {
if (in_array($file,array(".","..")))
continue; // We dont want to do anything with parent / current directory.
if (is_dir($file)) {
$result[] = recursive_search_dir($file); // Multi-dimension
# OR
array_merge($result,recursive_search_dir($file));// Single-dimension if you dont care about folder structure.
} else {
$result[] = utf8_decode($file); // full file name ( includes extention )
# OR
$result[] = utf8_decode(filename($file,PATHINFO_FILENAME)); // if you only want to capture the name and not the extention.
}
}
closedir($handle);
}
return $result;
}
$files = recursive_search_dir("."); // recursively searcht the current directory.

PHP: How to list files in a directory without listing subdirectories

This is the starting portion of my code to list files in a directory:
$files = scandir($dir);
$array = array();
foreach($files as $file)
{
if($file != '.' && $file != '..' && !is_dir($file)){
....
I'm trying to list all files in a directory without listing subfolders. The code is working, but showing both files and folders. I added !is_dir($file) as you see in my code above, but the results are still the same.
It should be like this, I think:
$files = scandir($dir);
foreach($files as $file)
{
if(is_file($dir.$file)){
....
Just use is_file.
Example:
foreach($files as $file)
{
if( is_file($file) )
{
// Something
}
}
This will scan the files then check if . or .. is in an array. Then push the files excluding . and .. in the new files[] array.
Try this:
$scannedFiles = scandir($fullPath);
$files = [];
foreach ($scannedFiles as $file) {
if (!in_array(trim($file), ['.', '..'])) {
$files[] = $file;
}
}
What a pain for something so seemingly simple! Nothing worked for me...
To get a result I assumed the file name had an extension which it must in my case.
if ($handle = opendir($opendir)) {
while (false !== ($entry = readdir($handle))) {
$pos = strpos( $entry, '.' );
if ($entry != "." && $entry != ".." && is_numeric($pos) ) {
............ good entry
Use the DIRECTORY_SEPARATOR constant to append the file to its directory path too.
function getFileNames($directoryPath) {
$fileNames = [];
$contents = scandir($directoryPath);
foreach($contents as $content) {
if(is_file($directoryPath . DIRECTORY_SEPARATOR . $content)) {
array_push($fileNames, $content);
}
}
return $fileNames;
}
This is a quick and simple one liner to list ONLY files. Since the user wants to list only files, there is no need to scan the directory and return all the contents and exclude the directories. Just get the files of any type or specific type. Use * to return all files regardless of extension or get files with a specific extension by replacing the * with the extension.
Get all files regardless of extension:
$files = glob($dir . DIRECTORY_SEPARATOR . "*");
Get all files with the php extension:
$files = glob($dir . DIRECTORY_SEPARATOR . "*.php");
Get all files with the js extension:
$files = glob($dir . DIRECTORY_SEPARATOR . "*.js");
I use the following for my sites:
function fileList(string $directory, string $extension="") :array
{
$filetype = '*';
if(!empty($extension) && mb_substr($extension, 0, 1, "UTF-8") != '.'):
$filetype .= '.' . $extension;
else:
$filetype .= $extension;
endif;
return glob($directory . DIRECTORY_SEPARATOR . $filetype);
}
Usage :
$files = fileList($configData->includesDirectory, '');
With my custom function, I can include an extension or leave it empty. Additionally, I can forget to place the . before the extension and it will succeed.

Categories