I have a delete.php in folder abc so I call localhost/abc/delete.php. I want to be able to delete abc folder and all its contents from server when I call localhost/abc/delete.php. How to do such thing?
This function deletes a directory with
all of it's content. Second parameter
is boolean to instruct the function if
it should remove the directory or only
the content
function rmdir_r ( $dir, $DeleteMe = TRUE )
{
if ( ! $dh = #opendir ( $dir ) ) return;
while ( false !== ( $obj = readdir ( $dh ) ) )
{
if ( $obj == '.' || $obj == '..') continue;
if ( ! #unlink ( $dir . '/' . $obj ) ) rmdir_r ( $dir . '/' . $obj, true );
}
closedir ( $dh );
if ( $DeleteMe )
{
#rmdir ( $dir );
}
}
//use like this:
rmdir_r( 'abc' );
http://www.roscripts.com/snippets/show/170
Try something like this:
function deleteDir($dir) {
if (!is_dir($dir)) return unlink($dir);
foreach (scandir($dir) as $item) {
if ($item == '.' || $item == '..') continue;
if (!deleteDir($dir.'/'.$item)) return false;
}
return rmdir($dir);
}
$dir = substr($_SERVER['SCRIPT_FILENAME'], 0, strrpos($_SERVER['SCRIPT_FILENAME'], '/'));
deleteDir($dir);
Related
I have this function which supposed to lead to the correct image folder (images) and shows its images, but it shows the all the images in the root path & the ones in (images) folder. what I have to change to make it shows the images that belongs to (images) folder only?.
function searchSite( $path = 'images', $level = 0 ) {
$skip = array( 'cgi-bin', '.', '..' );
$look_for = array( '.jpg', '.gif', '.png', '.jpeg' );
$dh = #opendir( $path );
while ( false !== ( $file = readdir( $dh ) ) ) {
$file_ext = substr( $file, -4, 4 );
if ( !in_array( $file, $skip ) ) {
if ( is_dir( "$path/$file" ) ) {
searchSite( "$path/$file", ( $level + 1 ) );
} else if ( in_array( $file_ext, $look_for ) ) {
echo "<option value='$path/$file' />$file</option>";
}
}
closedir( $dh );
}
PHP got its own filesystem and filter classes. With these classes you can easily iterator recursivly over a directory tree to get all the files you want. Nowadays it is kinda deprecated to code your own functionality, because the build in iterator and filter classes are much more efficient and it is not necessary to re-invent the wheel.
Here 's a short example how to use the build in filesystem and filter classes.
<?php
declare(strict_types=1);
namespace Marcel;
use FilesystemIterator;
use RecursiveCallbackFilterIterator;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
$directory = new RecursiveDirectoryIterator('../assets/images/', FilesystemIterator::FOLLOW_SYMLINKS);
$filter = new RecursiveCallbackFilterIterator($directory, function($current, $key, $iterator) {
if ($current->isDir()) {
return !in_array($current->getFilename(), ['.', '..', 'bla']);
} else {
return in_array($current->getExtension(), ['jpg', 'png']);
}
});
$iterator = new RecursiveIteratorIterator($filter);
$files = [];
foreach ($iterator as $file) {
$files[] = $file->getPathname();
}
var_dump($files);
So I have seen solutions of this, however my question is slightly different.
I want the file to have a character at the end.
So, for example, there is a directory called imgs:
imgs
contents: div.png, div2.png, divb.png, divab.png
I need to randomly select a file from this folder, but I need it to have a b at the end. So I could only get on either divb.png or divab.png.
If I get one that doesn't end in b, I need to reselect.
I currently have some code that gives me a timeout and doesn't reselect.
function random_pic($dir = 'imgs'){
$files = glob($dir . '/*.png');
$file = array_rand($files);
if(substr($files[$file], -5)==$shortparam.".png"){
return $files[$file];
} else {
return null;
}
}
EDIT -----------------
<?php
function random_pic() {
$files = glob('imgs/*.png' );
do {
if ( isset( $file ) ) {
unset( $files[$file] );
}
$file = array_rand( $files );
} while ( ( substr( $files[ $file ], -5 != ( $shortparam . ".png" ) ) ) AND ( count( $files) > 0 ) );
if ( count( $files ) > 0 ) {
return $files[ $file ];
} else {
echo $file;
return false;
}
}
for ($i = 0 ; $i < 20; $k++){
$image = random_pic();
if($image == false){
} else {
// display image
This times out for some reason.
(Fatal error: Maximum execution time of 10 seconds exceeded in file.php on line 84)
Thanks for any help you can give!
You could achieve that with a blend of glob, array_walk(), array_rand() and preg_match().
<?php
function random_pic($dir='imgs', $extension=".png", $endChar="b"){
$files = glob($dir . "/*{$extension}");
$matches = array();
array_walk($files, function($imgFile, $index) use ($extension, $endChar, &$matches) {
$pixName = preg_replace("#" . preg_quote($extension) . "#", "", basename($imgFile));
if( preg_match("#" . preg_quote($endChar) . "$#", $pixName)){
$matches[] = $imgFile;
}
});
return (count($matches))? $matches[array_rand($matches)] : null;
}
$randomPic = random_pic(__DIR__. "/imgs", ".png", "b");
// OR JUST USE THE DEFAULTS SINCE THEY ARE JUST THE SAME IN YOUR CASE:
// $randomPic = random_pic();
var_dump($randomPic);
I obviously don't have your files and your directory structure to try this code against, but I'm pretty confident it will solve your problem.
function random_pic( $dir = 'imgs' ) {
if ( $files = glob( $dir . '/*.png' ) ) {
do {
if ( isset( $file ) ) {
unset( $files[$file] );
}
if ( count( $files ) > 0 ) {
$file = array_rand( $files );
}
} while ( ( substr( $files[ $file ], -5 != ( $shortparam . ".png" ) ) ) AND ( count( $files ) > 0 ) );
if ( count( $files ) > 0 ) {
return $files[ $file ];
} else {
return NULL;
}
} else {
return NULL;
}
}
You may want to consider returning FALSE instead of NULL if nothing is found since it's more versatile on the parent end.
A php script should list all available "modules". A module is a subdirectory that contains at least an info.php file.
Now I want a list of all subdirectories that contain the "info.php" file (i.e. a list of all modules) and came up with this code:
$modules = array();
if ( $handle = opendir( MODULE_DIR ) ) {
while ( false !== ( $entry = readdir( $handle ) ) ) {
if ( $entry === '.' || $entry === '..' ) { continue; }
$info_file = MODULE_DIR . $entry . '/info.php';
if ( ! is_file( $info_file ) ) { continue; }
$modules[] = $entry;
}
closedir( $handle );
}
Question: Is there a shorter/nicer way to get the list, preferably without the loop?
A nice and clean solution can be achieved using the function glob():
foreach(glob('src/*/info.php') as $path) {
echo basename(dirname($path)) . PHP_EOL;
}
Take a look at the RecursiveDirectoryIterator
http://php.net/manual/en/class.recursivedirectoryiterator.php
In your case the code would look like this:
$it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator('.'));
foreach($it as $key => $item) {
if(basename($key) === 'info.php') {
echo dirname($key) . PHP_EOL;
}
}
I have a set of folders that has a depth of at least 4 or 5 levels. I'm looking to recurse through the directory tree as deep as it goes, and iterate over every file. I've gotten the code to go down into the first sets of subdirectories, but no deeper, and I'm not sure why. Any ideas?
$count = 0;
$dir = "/Applications/MAMP/htdocs/site.com";
function recurseDirs($main, $count){
$dir = "/Applications/MAMP/htdocs/site.com";
$dirHandle = opendir($main);
echo "here";
while($file = readdir($dirHandle)){
if(is_dir($file) && $file != '.' && $file != '..'){
echo "isdir";
recurseDirs($file);
}
else{
$count++;
echo "$count: filename: $file in $dir/$main \n<br />";
}
}
}
recurseDirs($dir, $count);
Check out the new RecursiveDirectoryIterator.
It's still far from perfect as you can't order the search results and other things, but to simply get a list of files, it's fine.
There are simple examples to get you started in the manual like this one:
<?php
$path = realpath('/etc');
$objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path),
RecursiveIteratorIterator::SELF_FIRST);
foreach($objects as $name => $object){
echo "$name\n";
}
?>
There is an error in the call
recurseDirs($file);
and in
is_dir($file)
you have to give the full path:
recurseDirs($main . '/' .$file, $count);
and
is_dir($main . '/' .$file)
However, like other anwerers, I suggest to use RecursiveDirectoryIteretor.
The call to is_dir and recurseDirs is not fully correct. Also your counting didn't work correctly. This works for me:
$dir = "/usr/";
function recurseDirs($main, $count=0){
$dirHandle = opendir($main);
while($file = readdir($dirHandle)){
if(is_dir($main.$file."/") && $file != '.' && $file != '..'){
echo "Directory {$file}: <br />";
$count = recurseDirs($main.$file."/",$count); // Correct call and fixed counting
}
else{
$count++;
echo "$count: filename: $file in $main \n<br />";
}
}
return $count;
}
$number_of_files = recurseDirs($dir);
Notice the changed calls to the function above and the new return value of the function.
So yeah: Today I was being lazy and Googled for a cookie cutter solution to a recursive directory listing and came across this. As I ended up writing my own function (as to why I even spent the time to Google for this is beyond me - I always seem to feel the need to re-invent the wheel for no suitable reason) I felt inclined to share my take on this.
While there are opinions for and against the use of RecursiveDirectoryIterator, I'll simply post my take on a simple recursive directory function and avoid the politics of chiming in on RecursiveDirectoryIterator.
Here it is:
function recursiveDirectoryList( $root )
{
/*
* this next conditional isn't required for the code to function, but I
* did not want double directory separators in the resulting array values
* if a trailing directory separator was provided in the root path;
* this seemed an efficient manner to remedy said problem easily...
*/
if( substr( $root, -1 ) === DIRECTORY_SEPARATOR )
{
$root = substr( $root, 0, strlen( $root ) - 1 );
}
if( ! is_dir( $root ) ) return array();
$files = array();
$dir_handle = opendir( $root );
while( ( $entry = readdir( $dir_handle ) ) !== false )
{
if( $entry === '.' || $entry === '..' ) continue;
if( is_dir( $root . DIRECTORY_SEPARATOR . $entry ) )
{
$sub_files = recursiveDirectoryList(
$root .
DIRECTORY_SEPARATOR .
$entry .
DIRECTORY_SEPARATOR
);
$files = array_merge( $files, $sub_files );
}
else
{
$files[] = $root . DIRECTORY_SEPARATOR . $entry;
}
}
return (array) $files;
}
With this function, the answer as to obtaining a file count is simple:
$dirpath = '/your/directory/path/goes/here/';
$files = recursiveDirectoryList( $dirpath );
$number_of_files = sizeof( $files );
But, if you don't want the overhead of an array of the respective file paths - or simply don't need it - there is no need to pass a count to the recursive function as was recommended.
One could simple amend my original function to perform the counting as such:
function recursiveDirectoryListC( $root )
{
$count = 0;
if( ! is_dir( $root ) ) return (int) $count;
$dir_handle = opendir( $root );
while( ( $entry = readdir( $dir_handle ) ) !== false )
{
if( $entry === '.' || $entry === '..' ) continue;
if( is_dir( $root . DIRECTORY_SEPARATOR . $entry ) )
{
$count += recursiveDirectoryListC(
$root .
DIRECTORY_SEPARATOR .
$entry .
DIRECTORY_SEPARATOR
);
}
else
{
$count++;
}
}
return (int) $count;
}
In both of these functions the opendir() function should really be wrapped in a conditional in the event that the directory is not readable or another error occurs. Make sure to do so correctly:
if( ( $dir_handle = opendir( $dir ) ) !== false )
{
/* perform directory read logic */
}
else
{
/* do something on failure */
}
Hope this helps someone...
I'm trying to find all the files and folders under a specified directory
For example I have /home/user/stuff
I want to return
/home/user/stuff/folder1/image1.jpg
/home/user/stuff/folder1/image2.jpg
/home/user/stuff/folder2/subfolder1/image1.jpg
/home/user/stuff/image1.jpg
Hopefully that makes sense!
function dir_contents_recursive($dir) {
// open handler for the directory
$iter = new DirectoryIterator($dir);
foreach( $iter as $item ) {
// make sure you don't try to access the current dir or the parent
if ($item != '.' && $item != '..') {
if( $item->isDir() ) {
// call the function on the folder
dir_contents_recursive("$dir/$item");
} else {
// print files
echo $dir . "/" .$item->getFilename() . "<br>";
}
}
}
}
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir)) as $f) {
echo "$f \r\n";
}
The working solution (change with your folder name)
<?php
$path = realpath('yourfolder/subfolder');
## or use like this
## $path = '/home/user/stuff/folder1';
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)) as $filename)
{
echo "$filename\n";
}
?>
$dir = "/home/user/stuff/";
$scan = scandir($dir);
foreach ($scan as $output) {
echo "$output" . "<br />";
}
Find all the files and folders under a specified directory.
function getDirRecursive($dir, &$output = []) {
$scandir = scandir($dir);
foreach ($scandir as $a => $name) {
$path = realpath($dir . DIRECTORY_SEPARATOR . $name);
if (!is_dir($path)) {
$output[] = $path;
} else if ($name != "." && $name != "..") {
getDirRecursive($path, $output);
$output[] = $path;
}
}
return $output;
}
var_dump(getDirRecursive('/home/user/stuff'));
Output (example) :
array (size=4)
0 => string '/home/user/stuff/folder1/image1.jpg' (length=35)
1 => string '/home/user/stuff/folder1/image2.jpg' (length=35)
2 => string '/home/user/stuff/folder2/subfolder1/image1.jpg' (length=46)
3 => string '/home/user/stuff/image1.jpg' (length=27)
listAllFiles( '../cooktail/' ); //send directory path to get the all files and floder of root dir
function listAllFiles( $strDir ) {
$dir = new DirectoryIterator( $strDir );
foreach( $dir as $fileinfo ) {
if( $fileinfo == '.' || $fileinfo == '..' ) continue;
if( $fileinfo->isDir() ) {
listAllFiles( "$strDir/$fileinfo" );
}
echo $fileinfo->getFilename() . "<br/>";
}
}
Beside RecursiveDirectoryIterator solution there is also glob() solution:
// do some extra filtering here, if necessary
function recurse( $item ) {
return is_dir( $item ) ? array_map( 'recurse', glob( "$item/*" ) ) : $item;
};
// array_walk_recursive: any key that holds an array will not be passed to the function.
array_walk_recursive( ( recurse( 'home/user/stuff' ) ), function( $item ) { print_r( $item ); } );
You can use the RecursiveDirectoryIterator or even the glob function.
Alternatively, the scandir function will do the job.