I have the next code but i need scan multiple dir on array.
public static function scanFiles($directory, $recursive = true, $listDirs = false, $listFiles = true, $exclude = '') {
$arrayItems = array();
$skipByExclude = false;
$handle = opendir($directory);
if ($handle) {
while (false !== ($file = readdir($handle))) {
preg_match("/(^(([\.]){1,2})$|(\.(svn|git|md))|(Thumbs\.db|\.DS_STORE|\.html))$/iu", $file, $skip);
if($exclude){
preg_match($exclude, $file, $skipByExclude);
}
if (!$skip && !$skipByExclude) {
if (is_dir($directory. DS . $file)) {
if($recursive) {
$arrayItems = array_merge($arrayItems, self::scanFiles($directory. DS . $file, $recursive, $listDirs, $listFiles, $exclude));
}
if($listDirs){
$file = $directory . DS . $file;
$arrayItems[] = $file;
}
} else {
if($listFiles){
$file = $directory . DS . $file;
$arrayItems[] = $file;
}
}
}
}
closedir($handle);
}
return $arrayItems;
}
Your use is: scanFiles('path/to/folder')
But I need the path to be an array, example: scanFiles(array('path/to/folder1', 'path/to/folder2')).
Some one help...?
Thank you in advance and sorry for my bad english.
you can change the function like this, just adding foreach with the code block that you have for scanning directory
public static function scanFiles($directories, $recursive = true, $listDirs = false, $listFiles = true, $exclude = '') {
$arrayItems = array();
$skipByExclude = false;
foreach($directories as $directory) {
$handle = opendir($directory);
if ($handle) {
while (false !== ($file = readdir($handle))) {
preg_match("/(^(([\.]){1,2})$|(\.(svn|git|md))|(Thumbs\.db|\.DS_STORE|\.html))$/iu", $file, $skip);
if ($exclude){
preg_match($exclude, $file, $skipByExclude);
}
if (!$skip && !$skipByExclude) {
if (is_dir($directory. DS . $file)) {
if ($recursive) {
$arrayItems = array_merge($arrayItems, self::scanFiles($directory. DS . $file, $recursive, $listDirs, $listFiles, $exclude));
}
if ($listDirs) {
$file = $directory . DS . $file;
$arrayItems[] = $file;
}
} else {
if ($listFiles) {
$file = $directory . DS . $file;
$arrayItems[] = $file;
}
}
}
}
closedir($handle);
}
}
return $arrayItems;
}
I have an action in my cakephp controller with zip function (from How to [recursively] Zip a directory in PHP?) :
public function documents() {
// PAGE VIERGE
$this->layout = null;
$this->autoRender = false;
// CALL TEST If data is sended
if (!empty($this->request->data) && ($this->request->data['call'] == 'yes')) {
$zip = new ZipArchive();
// callOrigin separate way
if ($this->request->data['callOrigin'] == 'dmc') {
$filename = $_SERVER['DOCUMENT_ROOT'] . '/resources/data/documents/documentMC.zip';
if ($zip->open($filename, ZipArchive::CREATE)!==TRUE) {
exit ('Impossible d\'ouvrir le fichier '.$filename.'');
}
// SEE http://php.net//manual/fr/ziparchive.addfile.php
$zip->addFile($_SERVER['DOCUMENT_ROOT'] . '/resources/data/documents/documentMC.html', "document/megacolon.html");
} elseif ($this->request->data['callOrigin'] == 'dsc') {
$filename = $_SERVER['DOCUMENT_ROOT'] . '/resources/data/documents/documentSC.zip';
if ($zip->open($filename, ZipArchive::CREATE)!==TRUE) {
exit ('Impossible d\'ouvrir le fichier '.$filename.'');
}
// SEE http://php.net//manual/fr/ziparchive.addfile.php
$zip->addFile($_SERVER['DOCUMENT_ROOT'] . '/resources/data/documents/documentSC.html', "document/suicide.html");
} else {
return false;
}
function Zip($source, $destination)
{
if (!extension_loaded('zip') || !file_exists($source)) {
return false;
}
$zip = new ZipArchive();
if (!$zip->open($destination, ZIPARCHIVE::CREATE)) {
return false;
}
$source = str_replace('\\', '/', realpath($source));
if (is_dir($source) === true)
{
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);
foreach ($files as $file)
{
$file = str_replace('\\', '/', $file);
// Ignore "." and ".." folders
if( in_array(substr($file, strrpos($file, '/')+1), array('.', '..')) )
continue;
$file = realpath($file);
if (is_dir($file) === true)
{
$zip->addEmptyDir(str_replace($source . '/', '', $file . '/'));
}
else if (is_file($file) === true)
{
$zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));
}
}
}
else if (is_file($source) === true)
{
$zip->addFromString(basename($source), file_get_contents($source));
}
return $zip->close();
}
// zip libs
Zip($_SERVER['DOCUMENT_ROOT'] . '/resources/libs/font-awesome/', $filename);
Zip($_SERVER['DOCUMENT_ROOT'] . '/resources/libs/jquery/', $filename);
Zip($_SERVER['DOCUMENT_ROOT'] . '/resources/libs/bootstrap/', $filename);
// zip individuals
$zip->addFile($_SERVER['DOCUMENT_ROOT'] . '/resources/data/documents/README.md', "README.md");
$zip->addFile($_SERVER['DOCUMENT_ROOT'] . '/resources/css/DOCS/baseDocs.css', "resources/css/DOCS/baseDocs.css");
// close zip
$zip->close();
}
}
With no errors msg in my logs, only the files .html, README and css are in the zip, zip function seems to be not performed... what is my mistake ?
rmdir("./uploads/temp/".$user."/");
I have many files in a directory I wish to remove in my PHP script, however these is no way for me to unlink() the file first. Is there a way I co do
unlink(* FROM (dir=)) // don't downvote the long shot
// delete all files from the dir first
// then delete that dir
Reference a directory has to be empty in order to delete it, see php.net/manual/en/function.rmdir.php
You can use the DirectoryIterator and unlink together.
use this
function delete_directory($dirname) {
if (is_dir($dirname))
$dir_handle = opendir($dirname);
if (!$dir_handle)
return false;
while($file = readdir($dir_handle)) {
if ($file != "." && $file != "..") {
if (!is_dir($dirname."/".$file))
unlink($dirname."/".$file);
else
delete_directory($dirname.'/'.$file);
}
}
closedir($dir_handle);
rmdir($dirname);
return true;
}
This code can easily be improved upon, as it's a quick hack, but it takes a directory as an argument and then uses functional recursion to delete all files and folders within, and then finally removes the directory. Nice and quick, too.
There is no other way except to delete all files first using one way or another and then remove directory.
public static function deleteDir($dirPath) {
if (! is_dir($dirPath)) {
throw new InvalidArgumentException('$dirPath must be a directory');
}
if (substr($dirPath, strlen($dirPath) - 1, 1) != '/') {
$dirPath .= '/';
}
$files = glob($dirPath . '*', GLOB_MARK);
foreach ($files as $file) {
if (is_dir($file)) {
self::deleteDir($file);
} else {
unlink($file);
}
}
rmdir($dirPath);
}
Try using glob to loop over the files in the directory to delete
foreach (glob('/path/to/directory/*') as $file){
unlink('/path/to/directory/' . $file);
}
Check this http://lixlpixel.org/recursive_function/php/recursive_directory_delete/
function recursive_remove_directory($directory, $empty=FALSE)
{
if(substr($directory,-1) == '/')
{
$directory = substr($directory,0,-1);
}
if(!file_exists($directory) || !is_dir($directory))
{
return FALSE;
}elseif(is_readable($directory))
{
$handle = opendir($directory);
while (FALSE !== ($item = readdir($handle)))
{
if($item != '.' && $item != '..')
{
$path = $directory.'/'.$item;
if(is_dir($path))
{
recursive_remove_directory($path);
}else{
unlink($path);
}
}
}
closedir($handle);
if($empty == FALSE)
{
if(!rmdir($directory))
{
return FALSE;
}
}
}
return TRUE;
}
You can delete it recursively:
public function delete_folder ($path) {
$handle = opendir($path);
while ($file = readdir($handle)) {
if ($file != '..' && $file != '.') {
if (is_file($path . DS . $file))
unlink($path . DS . $file);
else
delete_folder($path . DS . $file);
}
}
closedir($handle);
rmdir($tmp_path);
}
delete_folder('path/to/folder');
On my old VPS I was using the following code to copy the files and directories within a directory to a new directory that was created after the user submitted their form.
function copyr($source, $dest)
{
// Simple copy for a file
if (is_file($source)) {
return copy($source, $dest);
}
// Make destination directory
if (!is_dir($dest)) {
mkdir($dest);
$company = ($_POST['company']);
}
// Loop through the folder
$dir = dir($source);
while (false !== $entry = $dir->read()) {
// Skip pointers
if ($entry == '.' || $entry == '..') {
continue;
}
// Deep copy directories
if ($dest !== "$source/$entry") {
copyr("$source/$entry", "$dest/$entry");
}
}
// Clean up
$dir->close();
return true;
}
copyr('Template/MemberPages', "Members/$company")
However now on my new VPS it will only create the main directory, but will not copy any of the files to it. I don't understand what could have changed between the 2 VPS's?
Try something like this:
$source = "dir/dir/dir";
$dest= "dest/dir";
mkdir($dest, 0755);
foreach (
$iterator = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($source, \RecursiveDirectoryIterator::SKIP_DOTS),
\RecursiveIteratorIterator::SELF_FIRST) as $item
) {
if ($item->isDir()) {
mkdir($dest . DIRECTORY_SEPARATOR . $iterator->getSubPathname());
} else {
copy($item, $dest . DIRECTORY_SEPARATOR . $iterator->getSubPathname());
}
}
Iterator iterate through all folders and subfolders and make copy of files from $source to $dest
Could I suggest that (assuming it's a *nix VPS) that you just do a system call to cp -r and let that do the copy for you.
This function copies folder recursivley very solid. I've copied it from the comments section on copy command of php.net
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);
}
I have changed Joseph's code (below), because it wasn't working for me. This is what works:
function cpy($source, $dest){
if(is_dir($source)) {
$dir_handle=opendir($source);
while($file=readdir($dir_handle)){
if($file!="." && $file!=".."){
if(is_dir($source."/".$file)){
if(!is_dir($dest."/".$file)){
mkdir($dest."/".$file);
}
cpy($source."/".$file, $dest."/".$file);
} else {
copy($source."/".$file, $dest."/".$file);
}
}
}
closedir($dir_handle);
} else {
copy($source, $dest);
}
}
[EDIT] added test before creating a directory (line 7)
The Symfony's FileSystem Component offers a good error handling as well as recursive remove and other useful stuffs. Using #OzzyCzech's great answer, we can do a robust recursive copy this way:
use Symfony\Component\Filesystem\Filesystem;
// ...
$fileSystem = new FileSystem();
if (file_exists($target))
{
$this->fileSystem->remove($target);
}
$this->fileSystem->mkdir($target);
$directoryIterator = new \RecursiveDirectoryIterator($source, \RecursiveDirectoryIterator::SKIP_DOTS);
$iterator = new \RecursiveIteratorIterator($directoryIterator, \RecursiveIteratorIterator::SELF_FIRST);
foreach ($iterator as $item)
{
if ($item->isDir())
{
$fileSystem->mkdir($target . DIRECTORY_SEPARATOR . $iterator->getSubPathName());
}
else
{
$fileSystem->copy($item, $target . DIRECTORY_SEPARATOR . $iterator->getSubPathName());
}
}
Note: you can use this component as well as all other Symfony2 components standalone.
Here's what we use at our company:
static public function copyr($source, $dest)
{
// recursive function to copy
// all subdirectories and contents:
if(is_dir($source)) {
$dir_handle=opendir($source);
$sourcefolder = basename($source);
mkdir($dest."/".$sourcefolder);
while($file=readdir($dir_handle)){
if($file!="." && $file!=".."){
if(is_dir($source."/".$file)){
self::copyr($source."/".$file, $dest."/".$sourcefolder);
} else {
copy($source."/".$file, $dest."/".$file);
}
}
}
closedir($dir_handle);
} else {
// can also handle simple copy commands
copy($source, $dest);
}
}
function recurse_copy($source, $dest)
{
// Check for symlinks
if (is_link($source)) {
return symlink(readlink($source), $dest);
}
// Simple copy for a file
if (is_file($source)) {
return copy($source, $dest);
}
// Make destination directory
if (!is_dir($dest)) {
mkdir($dest);
}
// Loop through the folder
$dir = dir($source);
while (false !== $entry = $dir->read()) {
// Skip pointers
if ($entry == '.' || $entry == '..') {
continue;
}
// Deep copy directories
recurse_copy("$source/$entry", "$dest/$entry");
}
// Clean up
$dir->close();
return true;
}
OzzyCheck's is elegant and original, but he forgot the initial mkdir($dest);
See below. No copy command is ever provided with contents only. It must fulfill its entire role.
$source = "dir/dir/dir";
$dest= "dest/dir";
mkdir($dest, 0755);
foreach (
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS),
RecursiveIteratorIterator::SELF_FIRST) as $item) {
if ($item->isDir()) {
mkdir($dest . DIRECTORY_SEPARATOR . $iterator->getSubPathName());
} else {
copy($item, $dest . DIRECTORY_SEPARATOR . $iterator->getSubPathName());
}
}
Here's a simple recursive function to copy entire directories
source: http://php.net/manual/de/function.copy.php
<?php
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);
}
?>
Why not just ask the OS to take care of this?
system("cp -r olddir newdir");
Done.
<?php
/**
* code by Nk (nk.have.a#gmail.com)
*/
class filesystem
{
public static function normalizePath($path)
{
return $path.(is_dir($path) && !preg_match('#/$#', $path) ? '/' : '');
}
public static function rscandir($dir, $sort = SCANDIR_SORT_ASCENDING)
{
$results = array();
if(!is_dir($dir))
return $results;
$dir = self::normalizePath($dir);
$objects = scandir($dir, $sort);
foreach($objects as $object)
if($object != '.' && $object != '..')
{
if(is_dir($dir.$object))
$results = array_merge($results, self::rscandir($dir.$object, $sort));
else
array_push($results, $dir.$object);
}
array_push($results, $dir);
return $results;
}
public static function rcopy($source, $dest, $destmode = null)
{
$files = self::rscandir($source);
if(empty($files))
return;
if(!file_exists($dest))
mkdir($dest, is_int($destmode) ? $destmode : fileperms($source), true);
$source = self::normalizePath(realpath($source));
$dest = self::normalizePath(realpath($dest));
foreach($files as $file)
{
$file_dest = str_replace($source, $dest, $file);
if(is_dir($file))
{
if(!file_exists($file_dest))
mkdir($file_dest, is_int($destmode) ? $destmode : fileperms($file), true);
}
else
copy($file, $file_dest);
}
}
}
?>
/var/www/websiteA/backup.php :
<?php /* include.. */ filesystem::rcopy('/var/www/websiteA/', '../websiteB'); ?>
hmm. as that's complicated ))
function mkdir_recursive( $dir ){
$prev = dirname($dir);
if( ! file_exists($prev))
{
mkdir_recursive($prev);
}
if( ! file_exists($dir))
{
mkdir($dir);
}
}
...
$srcDir = "/tmp/from"
$dstDir = "/tmp/to"
mkdir_recursive($dstDir);
foreach( $files as $file){
copy( $srcDir."/".$file, $dstDir."/".$file);
}
$file - somthing like that file.txt
I guess you should check user(group)rights. You should consider chmod for example, depending on how you run (su?)PHP. You could possibly also choose to modify your php configuration.
There were some issues with the functions that I tested in the thread and here is a powerful function that covers everything. Highlights:
No need to have an initial or intermediate source directories. All of the directories up to the source directory and to the copied directories will be handled.
Ability to skip directory or files from an array. (optional) With the global $skip; skipping of files even under sub level directories are handled.
Full recursive support, all the files and directories in multiple depth are supported.
$from = "/path/to/source_dir";
$to = "/path/to/destination_dir";
$skip = array('some_file.php', 'somedir');
copy_r($from, $to, $skip);
function copy_r($from, $to, $skip=false) {
global $skip;
$dir = opendir($from);
if (!file_exists($to)) {mkdir ($to, 0775, true);}
while (false !== ($file = readdir($dir))) {
if ($file == '.' OR $file == '..' OR in_array($file, $skip)) {continue;}
if (is_dir($from . DIRECTORY_SEPARATOR . $file)) {
copy_r($from . DIRECTORY_SEPARATOR . $file, $to . DIRECTORY_SEPARATOR . $file);
}
else {
copy($from . DIRECTORY_SEPARATOR . $file, $to . DIRECTORY_SEPARATOR . $file);
}
}
closedir($dir);
}
Recursively copies files from source to target, with choice of overwriting existing files on the target.
function copyRecursive($sourcePath, $targetPath, $overwriteExisting) {
$dir = opendir($sourcePath);
while (($file = readdir($dir)) !== false) {
if ($file == "." || $file == "..") continue; // ignore these.
$source = $sourcePath . "/" . $file;
$target = $targetPath. "/" . $file;
if (is_dir($source) == true) {
// create the target directory, if it does not exist.
if (file_exists($target) == false) #mkdir($target);
copyRecursive($source, $target, $overwriteExisting);
} else {
if ((file_exists($target) == false) || ($overwriteExisting == true)) {
copy($source, $target);
}
}
}
closedir($dir);
}
I think the title is clear.
$dir = '/some/path/to/delete/';//note the trailing slashes
$dh = opendir($dir);
while($file = readdir($dh))
{
if(!is_dir($file))
{
#unlink($dir.$file);
}
}
closedir($dh);
function Delete($path)
{
if (is_dir($path) === true)
{
$files = array_diff(scandir($path), array('.', '..'));
foreach ($files as $file)
{
Delete(realpath($path) . '/' . $file);
}
return rmdir($path);
}
else if (is_file($path) === true)
{
return unlink($path);
}
return false;
}
http://us.php.net/manual/en/function.unlink.php.
You will find many functions in the comments that does what you need
One example:
function unlinkRecursive($dir, $deleteRootToo)
{
if(!$dh = #opendir($dir))
{
return;
}
while (false !== ($obj = readdir($dh)))
{
if($obj == '.' || $obj == '..')
{
continue;
}
if (!#unlink($dir . '/' . $obj))
{
unlinkRecursive($dir.'/'.$obj, true);
}
}
closedir($dh);
if ($deleteRootToo)
{
#rmdir($dir);
}
return;
}
This function will remove recursively (like rm -r). Be careful!
function rm_recursive($filepath)
{
if (is_dir($filepath) && !is_link($filepath))
{
if ($dh = opendir($filepath))
{
while (($sf = readdir($dh)) !== false)
{
if ($sf == '.' || $sf == '..')
{
continue;
}
if (!rm_recursive($filepath.'/'.$sf))
{
throw new Exception($filepath.'/'.$sf.' could not be deleted.');
}
}
closedir($dh);
}
return rmdir($filepath);
}
return unlink($filepath);
}