trying to find a way to copy entire directory but exclude certain files, in this case just need to exclude a directory which will always contain just 1 file a png... figured could use something similar to this code but have absolutely no clue as to how to exclude a file only
function xcopy($source, $dest, $permissions = 0755)
{
// 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, $permissions);
}
// Loop through the folder
$dir = dir($source);
while (false !== $entry = $dir->read()) {
// Skip pointers
if ($entry == '.' || $entry == '..') {
continue;
}
// Deep copy directories
xcopy("$source/$entry", "$dest/$entry", $permissions);
}
// Clean up
$dir->close();
return true;
}
Here is a function that may work for you. I have notated for clarification:
<?php
function CopyDirectory($settings = false)
{
// The script may take some time if there are lots of files
ini_set("max_execution_time",3000);
// Just do some validation and pre-sets
$directory = (isset($settings['dir']) && !empty($settings['dir']))? $settings['dir'] : false;
$copyto = (isset($settings['dest']) && !empty($settings['dest']))? $settings['dest'] : false;
$filter = (isset($settings['filter']) && !empty($settings['filter']))? $settings['filter'] : false;
// Add the copy to destinations not to copy otherwise
// you will have an infinite loop of files being copied
$filter[] = $copyto;
// Stop if the directory is not set
if(!$directory)
return;
// Create a recursive directory iterator
$dir = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory),RecursiveIteratorIterator::CHILD_FIRST);
try{
foreach($dir as $file) {
$copydest = str_replace("//","/",$copyto."/".str_replace($_SERVER['DOCUMENT_ROOT'],"",$file));
$compare = rtrim($file,".");
if(is_dir($file)) {
if(!is_dir($copydest)) {
if(!in_array($compare,$filter)) {
if(isset($skip) && !preg_match("!".$skip."!",$file) || !isset($skip))
#mkdir($copydest,0755,true);
else
$record[] = $copydest;
}
else {
$skip = $compare;
}
}
}
elseif(is_file($file) && !in_array($file,$filter)) {
copy($file,$copydest);
}
else {
if($file != '.' && $file != '..')
$record[] = $copydest;
}
}
}
// This will catch errors in copying (like permission errors)
catch (Exception $e)
{
$error[] = $e;
}
}
// Copy from
$settings['dir'] = $_SERVER['DOCUMENT_ROOT'];
// Copy to
$settings['dest'] = $_SERVER['DOCUMENT_ROOT']."/tester";
// Files and folders to not include contents
$settings["filter"][] = $_SERVER['DOCUMENT_ROOT'].'/core.processor/';
$settings["filter"][] = $_SERVER['DOCUMENT_ROOT'].'/config.php';
$settings["filter"][] = $_SERVER['DOCUMENT_ROOT'].'/client_assets/images/';
// Create instance
CopyDirectory($settings);
?>
Related
I want to copy all files from one folder to another folder using PHP scripts. So if I have a file demo/index.php then I would like to copy index.php to test/index.php
You can use this function to recursively copy files and folders:
function smartCopy($source, $dest, $options=array('folderPermission'=>0755,'filePermission'=>0755))
{
$result=false;
if (is_file($source)) {
if ($dest[strlen($dest)-1]=='/') {
if (!file_exists($dest)) {
cmfcDirectory::makeAll($dest,$options['folderPermission'],true);
}
$__dest=$dest."/".basename($source);
} else {
$__dest=$dest;
}
$result=copy($source, $__dest);
#chmod($__dest,$options['filePermission']);
} elseif(is_dir($source)) {
if ($dest[strlen($dest)-1]=='/') {
if ($source[strlen($source)-1]=='/') {
//Copy only contents
} else {
//Change parent itself and its contents
$dest=$dest.basename($source);
if(!file_exists($dest)) mkdir($dest);
#chmod($dest,$options['filePermission']);
}
} else {
if ($source[strlen($source)-1]=='/') {
//Copy parent directory with new name and all its content
if(!file_exists($dest)) mkdir($dest,$options['folderPermission']);
#chmod($dest,$options['filePermission']);
} else {
//Copy parent directory with new name and all its content
if(!file_exists($dest)) mkdir($dest,$options['folderPermission']);
#chmod($dest,$options['filePermission']);
}
}
$dirHandle=opendir($source);
while($file=readdir($dirHandle))
{
if($file!="." && $file!="..")
{
if(!is_dir($source."/".$file)) {
$__dest=$dest."/".$file;
} else {
$__dest=$dest."/".$file;
}
//echo "$source/$file ||| $__dest<br />";
$result=smartCopy($source."/".$file, $__dest, $options);
}
}
closedir($dirHandle);
} else {
$result=false;
}
return $result;
}
Then execute in this way, for files:
smartCopy('demo/index.php', 'test/index.php');
or for folders:
smartCopy('demo/', 'test/');
Use scandir() to scan all the files in directory and then foreach file copy them into new directory using copy()
Here is the code to copy all the files, try this...
<?php
$dir = 'img';
$files = scandir($dir);
///path to new directory..
$new_dir = 'img2';
foreach($files as $file)
{
if(!empty($file) && $file != '.' && $file != '..')
{
$source = $dir.'/'.$file;
$destination = $new_dir.'/'.$file;
if(copy($source, $destination))
{
echo "Copied $file...\n";
}
}
}
?>
This is my script:
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);
}
// If the source is a symlink
if (is_link($source)) {
$link_dest = readlink($source);
return symlink($link_dest, $dest);
}
// 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;
}
And I call function like this:
<?php copyr("D:/ahmad","E:"); ?>
When I call the function copyr always loading pages long.
And how to display the loading bar when the copy process?
What's the fastest way to delete all files in all sub-folders except those whose filename is 'whatever.jpg' in PHP?
Why not use iterators? This is tested:
function run($baseDir, $notThis)
{
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($baseDir), RecursiveIteratorIterator::LEAVES_ONLY) as $file) {
if ($file->isFile() && $file->getFilename() != $notThis) {
#unlink($file->getPathname());
}
}
}
run('/my/path/base', 'do_not_cancel_this_file.jpg');
This should be what youre looking for, $but is an array holding exceptions.
Not sure if its the fastest, but its the most common way for directory iteration.
function rm_rf_but ($what, $but)
{
if (!is_dir($what) && !in_array($what,$but))
#unlink($what);
else
{
if ($dh = opendir($what))
{
while(($item = readdir($dh)) !== false)
{
if (in_array($item, array_merge(array('.', '..'),$but)))
continue;
rm_rf_but($what.'/'.$item, $but);
}
}
#rmdir($what); // remove this if you dont want to delete the directory
}
}
Example use:
rm_rf_but('.', array('notme.jpg','imstayin.png'));
Untested:
function run($baseDir) {
$files = scandir("{$baseDir}/");
foreach($files as $file) {
$path = "{$badeDir}/{$file}";
if($file != '.' && $file != '..') {
if(is_dir($path)) {
run($path);
} elseif(is_file($path)) {
if(/* here goes you filtermagic */) {
unlink($path);
}
}
}
}
}
run('.');
I wrote recursive PHP function for folder deletion. I wonder, how do I modify this function to delete all files and folders in webhosting, excluding given array of files and folder names (for ex. cgi-bin, .htaccess)?
BTW
to use this function to totally remove a directory calling like this
recursive_remove_directory('path/to/directory/to/delete');
to use this function to empty a directory calling like this:
recursive_remove_directory('path/to/full_directory',TRUE);
Now the function is
function recursive_remove_directory($directory, $empty=FALSE)
{
// if the path has a slash at the end we remove it here
if(substr($directory,-1) == '/')
{
$directory = substr($directory,0,-1);
}
// if the path is not valid or is not a directory ...
if(!file_exists($directory) || !is_dir($directory))
{
// ... we return false and exit the function
return FALSE;
// ... if the path is not readable
}elseif(!is_readable($directory))
{
// ... we return false and exit the function
return FALSE;
// ... else if the path is readable
}else{
// we open the directory
$handle = opendir($directory);
// and scan through the items inside
while (FALSE !== ($item = readdir($handle)))
{
// if the filepointer is not the current directory
// or the parent directory
if($item != '.' && $item != '..')
{
// we build the new path to delete
$path = $directory.'/'.$item;
// if the new path is a directory
if(is_dir($path))
{
// we call this function with the new path
recursive_remove_directory($path);
// if the new path is a file
}else{
// we remove the file
unlink($path);
}
}
}
// close the directory
closedir($handle);
// if the option to empty is not set to true
if($empty == FALSE)
{
// try to delete the now empty directory
if(!rmdir($directory))
{
// return false if not possible
return FALSE;
}
}
// return success
return TRUE;
}
}
Try something like this:
$it = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator('%yourBaseDir%'),
RecursiveIteratorIterator::CHILD_FIRST
);
$excludeDirsNames = array();
$excludeFileNames = array('.htaccess');
foreach($it as $entry) {
if ($entry->isDir()) {
if (!in_array($entry->getBasename(), $excludeDirsNames)) {
try {
rmdir($entry->getPathname());
}
catch (Exception $ex) {
// dir not empty
}
}
}
elseif (!in_array($entry->getFileName(), $excludeFileNames)) {
unlink($entry->getPathname());
}
}
I'm using this function to delete the folder with all files and subfolders:
function removedir($dir) {
if (substr($dir, strlen($dir) - 1, 1) != '/')
$dir .= '/';
if ($handle = opendir($dir)) {
while ($obj = readdir($handle)) {
if ($obj != '.' && $obj != '..') {
if (is_dir($dir . $obj)) {
if (!removedir($dir . $obj))
return false;
}
else if (is_file($dir . $obj)) {
if (!unlink($dir . $obj))
return false;
}
}
}
closedir($handle);
if (!#rmdir($dir))
return false;
return true;
}
return false;
}
$folder_to_delete = "folder"; // folder to be deleted
echo removedir($folder_to_delete) ? 'done' : 'not done';
Iirc I got this from php.net
You could provide an extra array parameter $exclusions to recursive_remove_directory(), but you'll have to pass this parameter every time recursively.
Make $exclusions global. This way it can be accessed in every level of recursion.
I have this code:
<?php
$allowed = array('file1', 'file2', 'file3');
if (in_array($_GET["url"], $allowed)) {
// You can include
} else {
// Error message and dont include
}
?>
But instead of writing all the filenames in the array, how can i do so that the files in for example my folder FILES/ is accepted an no other files. How to do that?
Use the file_exists function like this:
if (file_exists('FILES/'.basename($_GET["url"]))) {
// You can include
} else {
// Error message and dont include
}
Function to retrieve files in a folder:
<?
function fGetFilesInFolder($sFolder) {
$aFiles = array();
if(file_exists($sFolder)) {
if ($handle = opendir($sFolder)) {
while (false !== ($sFile = readdir($handle))) {
if ($sFile != "." && $sFile != "..") $aFiles[] = $sFile;
}
closedir($handle);
}
}
return $aFiles;
}
?>