I'm having problems checking if a dinamically named folder exists using php. I know i can use
file_exists()
to check if a folder or file exists, but the problem is that the name of the folders I'm checking may vary.
I have folders where the first part of the name is fixed, and the part after "_" can vary. As an example:
folder_0,
where every folder will start with "folder_" but after the "_" it can be anything.
Anyway i can check if a folder with this property exists?
Thanks in advance.
SR
You make a loop to go through all the files/folders in the parent folder:
$folder = '/path-to-your-folder-having-subfolders';
$handle = opendir($folder) or die('Could not open folder.');
while (false !== ($file = readdir($handle))) {
if (preg_match("|^folder_(.*)$|", $file, $match)) {
$curr_foldername = $match[0];
// If you come here you know that such a folder exists and the full name is in the above variable
}
}
function find_wildcard_dirs($prefix)
{
return array_filter(glob($prefix), 'is_dir');
}
e.g.
print_r(find_wildcard_dirs("/tmp/santos_*'));
Related
I need a little bit of help. I need to write a script that will look through all directories and sub-directories and delete specific extensions that are modified after specific time. I can get it to delete files from specific path, but I need the script to search inside sub directories. Is there any way to do that?
I have tried this for files but I have no idea on how to make it work with directories and sub directories
$path = '/path/to/file/';
if ($handle = opendir($path)) {
while (false !== ($file = readdir($handle))) {
$filelastmodified = filemtime($path . $file);
if( $filelastmodified > "MY TIME STAMP" )
{
unlink($path . $file);
}
echo "deleted";
}
closedir($handle);
}
Create a recursive function, if it finds a folder it calls itself passing the folder name.
I'm trying to create a folder tree from an array, taken from a string.
$folders = str_split(564);
564 can actually be any number. The goal is to create a folder structure like /5/6/4
I've managed to create all folders in a single location, using code inspired from another thread -
for ($i=0;$i<count($folders);$i++) {
for ($j=0;$j<count($folders[$i]);$j++) {
$path .= $folders[$i][$j] . "/";
mkdir("$path");
}
unset($path);
}
but this way I get all folders in the same containing path.
Furthermore, how can I create these folders in a specific location on disk? Not that familiar with advanced php, sorry :(
Thank you.
This is pretty simple.
Do a for each loop through the folder array and create a string which appends on each loop the next sub-folder:
<?php
$folders = str_split(564);
$pathToCreateFolder = '';
foreach($folders as $folder) {
$pathToCreateFolder .= DIRECTORY_SEPARATOR . $folder;
mkdir($folder);
}
You may also add the base path, where the folders should be created to initial $pathToCreateFolder.
Here you'll find a demo: http://codepad.org/aUerytTd
Or you do it as Michael mentioned in comments, with just one line:
mkdir(implode(DIRECTORY_SEPARATOR, $folders), 0777, TRUE);
The TRUE flag allows mkdir to create folders recursivley. And the implode put the directory parts together like 5/6/4. The DIRECTORY_SEPARATOR is a PHP constant for the slash (/) on unix machines or backslash (\) on windows.
Why not just do:
<?php
$directories = str_split(564);
$path = implode(DIRECTORY_SEPARATOR, $directories);
mkdir($path, 0777, true);
Don't know what you're really trying to do, but here are some hints.
There are recursive mkdir:
if(!file_exists($dir)) // check if directory is not created
{
#mkdir($dir, 0755, true); // create it recursively
}
Path you want can be made in two function calls and prefixed by some start path:
$path = 'some/path/to/cache';
$cache_node_id = 4515;
$path = $path.'/'.join('/', str_split($cache_node_id));
Resulting path can be used to create folder with the code above
So here we come to a pair of functions/methods
function getPath($node_id, $path = 'default_path')
{
return $path.'/'.join('/', str_split($node_id))
}
function createPath($node_id, $path = 'default_path');
{
$path = getPath($node_id, $path);
if(!file_exists($path)) // check if directory is not created
{
#mkdir($path, 0755, true); // create it recursively
}
}
With these you can easily create such folders everywhere you desire and get them by your number.
As mentioned earlier, the solution I got from a friend was
$folders = str_split(564);
mkdir(implode('/',$folders),0777,true);
Also, to add a location defined in a variable, I used
$folders = str_split($idimg);
mkdir($path_defined_earlier. implode('/',$folders),0777,true);
So thanks for all the answers, seems like this was the correct way to handle this.
Now the issue is that I need to the created path, so how can I store it in a variable? Sorry if this breaches any rules, if I need to create a new thread I'll do it...
I have main folder named "gallery". In this folder there are some sub folders like "animal", "tree", etc. folder "animal" contains some pictures and so on. suppose i want to delete "animal" folder with all pictures in it, how can do this?
i tried-
rmdirr($_SERVER['DOCUMENT_ROOT']."admin/gallery/animal");
but in server, it deleted the whole "gallery" folder with all in it. please tell me what i am doing wrong and also give me a solution. thanks in advance.
If there are no subfolders you can use glob() to empty the directory before using rmdir():
foreach( glob( "/path/to/dir/*.*" ) as $filename ) {
unlink( $filename );
}
rmdir( "/path/to/dir" );
By the way, rmdir() shouldn't delete any files. It just fails if the directory isn't empty. You might want to make sure there's nothing else in your code that causes the parent directory to be wiped out.
Just delete the directory recursively with a helper function:
rrmdir($_SERVER['DOCUMENT_ROOT']."admin/gallery/animal");
function rrmdir($path)
{
return is_file($path)
? #unlink($path)
: array_map('rrmdir', glob($path.'/*')) == #rmdir($path)
;
}
When removing a desired directory, you must first remove the files within that directory. Once that is complete, then you may remove the directory -- assuming you have the proper permissions.
Included below is code that removes the files in the directory and will then remove the specified directory itself:
<?php
$dirname = "animal";
function destroy($dir) {
$mydir = opendir($dir);
while(false !== ($file = readdir($mydir))) {
if($file != "." && $file != "..") {
chmod($dir.$file, 0777);
if(is_dir($dir.$file)) {
chdir('.');
destroy($dir.$file.'/');
rmdir($dir.$file) or DIE("Unable to delete $dir$file");
}else{
unlink($dir.$file) or DIE("Unable to delete $dir$file");
}
}
}
closedir($mydir);
}
destroyDir($dirname);
?>
$value can = a folder structure to the language file. Example: languages/english.php
$value can also = the files name. Example: english.php
So I need to get the current folder that $value is in and delete the folder ONLY if there are no other files/folders within that directory (after deleting the actual file as I am doing already, ofcourse).
foreach($module['languages'] as $lang => $langFile)
{
foreach ($langFile as $type => $value)
{
#unlink($module_path . '/' . $value);
// Now I need to delete the folder ONLY if there are no other directories inside the folder where it is currently at.
// And ONLY if there are NO OTHER files within that folder also.
}
}
How can I do this?? And wondering if this can be done without using a while loop, since a while loop within a foreach loop could take some time, and need this to be as quick as possible.
And just FYI, the $module_path should never be deleted. So if $value = english.php, it should never delete the $module_path. Ofcourse, there will always be another file in there, so checking for this is not necessary, but won't hurt either way.
Thanks guys :)
EDIT
Ok, now I'm using this code here and it is NOT working, it is not removing the folders or the files, and I don't get any errors either... so not sure what the problem is here:
foreach($module['languages'] as $lang => $langFile)
{
foreach ($langFile as $type => $value)
{
if (#unlink($module_path . '/' . $value))
#rmdir(dirname($module_path . '/' . $value));
}
}
NEVERMIND, this works a CHARM!!! Cheers Everyone!!
The easyest way is try to use rmdir. This don't delete folder if it is not empty
rmdir($module_path);
also you can check is folder empty by
if(count(glob($module_path.'*'))<3)//delete
2 for . and ..
UPD: as I reviewed maybe you should replace $module_path by dirname($module_path.'.'.$value);
Since the directory you care about might be part of the $value, you need to use dirname to figure out what the parent directory is, you can't just assume that it's $module_path.
$file_path = $module_path . '/' . $value;
if (#unlink($file_path)) {
#rmdir(dirname($file_path));
}
if (is_file($value)) {
unlink($value);
} else if (is_dir($value)) {
if (count(scandir($value)) == 2) }
unlink($value)
}
}
http://php.net/manual/en/function.is-dir.php
http://www.php.net/manual/en/function.scandir.php
The code below will take a path, check if it is a file (i.e. not a directory). If it is a file, it will extract the directory name, then delete the file, then iterate over the dir and count the files in it, if the files are zero it'll delete the dir.
Code is as an example and should work, however privileges and environment setup may result in it not working.
<?php
if(!is_dir ( string $filename )){ //if it is a file
$fileDir = dirname ( $filename );
if ($handle = opendir($fileDir)) {
echo "Directory handle: $handle\n";
echo "Files:\n";
$numFiles=0;
//delete the file
unlink($myFile);
//Loop the dir and count the file in it
while (false !== ($file = readdir($handle))) {
$numFiles = $numFiles + 1;
}
if($numFiles == 0) {
//delete the dir
rmdir($fileDir);
}
closedir($handle);
}
}
?>
I want to move all files from one folder to other. my code is as following. in this I made a folder in which i want to copy all file from templats folder
$doit = str_replace(" ", "", $slt['user_compeny_name']);
mkdir("$doit");
$source = "templat/";
$target = $doit . "/";
$dir = opendir($source);
while (($file = readdir($dir)) !== false) {
copy($source . $file, $target . $file);
}
It working fine . copy all files but give warning that The first argument to copy() function cannot be a directory
can any one help me asap
Readdir will read all children in a directory, including other dirs, and 'virtual' dirs like . and .. (link to root and parent dir, resp.) You'll have to check for these and prevent the copy() function for these instances.
while (($file = readdir($dir)) !== false)
{
if(!is_dir($file))
{
copy($source.$file, $target.$file);
}
}
You are not accounting for the . and the .. files at the top of the directory. This means that the first thing it tries to copy is "\template." which would be the same as trying to copy the directory.
Just add something like:
if ($file !== "." && $file !== "..")
...
opendir() will include items . and .. as per the documentation.
You will need to exclude these by using the code in the other comments.
if ($file != "." && $file != "..") {
// copy
}
I know, this question is pretty old, but also are the answers. I feel the need to show some new methods, which can be used to execute the requested task.
In the mean time Objects were introduced with a lot more features and possibilities. Needless to say, the other answers will still work aswell.
But here we go, using the DirectoryIterator:
$szSrcFolder = 'source_folder';
$szTgtFolder = 'target_folder';
foreach (new DirectoryIterator($szSrcFolder) as $oInfo)
if ($oInfo->isFile())
copy($oInfo->getPathname(), $szTgtFolder . DIRECTORY_SEPARATOR . $oInfo->getBasename());
Remember, within this script, all paths are relative to the working directory of the script itself.
I think it is self explaining, but we will take a look. This few lines will iterate over the whole content of the source folder and check if it is a file and will copy it to the target folder, keeping the original file name.