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?
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";
}
}
}
?>
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);
?>
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 the following function when i try and return the vaule its only shows 1 folder but when i echo the function it show the correct informaion.
PHP Code:
$FolderList = "";
function ListFolder($path) {
$path = str_replace("//","/",$path);
//using the opendir function
$dir_handle = #opendir($path) or die("Unable to open $path");
//Leave only the lastest folder name
$dirname = end(explode("/", $path));
//display the target folder.
$FolderList .= ('<option value="">'.$path.'</option>');
while(false !== ($file = readdir($dir_handle))) {
if($file!="." && $file!="..") {
if(is_dir($path."/".$file)) {
//Display a list of sub folders.
ListFolder($path."/".$file);
}
}
}
//closing the directory
closedir($dir_handle);
return $FolderList; //ERROR: Only Shows 1 Folder
echo $FolderList; //WORKS: Show All The Folders Correctly
}
Thanks
Give this a shot:
function ListFolder($path)
{
$path = str_replace("//","/",$path);
//using the opendir function
$dir_handle = #opendir($path) or die("Unable to open $path");
//Leave only the lastest folder name
$dirname = end(explode("/", $path));
//display the target folder.
$FolderList = ('<option value="">'.$path.'</option>');
while (false !== ($file = readdir($dir_handle)))
{
if($file!="." && $file!="..")
{
if (is_dir($path."/".$file))
{
//Display a list of sub folders.
$FolderList .= ListFolder($path."/".$file);
}
}
}
//closing the directory
closedir($dir_handle);
return $FolderList;
}
echo ListFolder('/path/to/folder/');
I simply changed the $FolderList to be assigned to the return value of the ListFolder function.
Inside your while loop, you're calling ListFolder again. This is okay to do but you're not storing the result anywhere and just echoing the result every time ListFolder is called.
That correct format you're seeing on the page is not that 1 string being echoed at the end. its a single directory being echoed every time ListFolder is being called.
Below is the code that works.
function ListFolder($path)
{
$FolderList = "";
$path = str_replace("//","/",$path);
//using the opendir function
$dir_handle = #opendir($path) or die("Unable to open $path");
//Leave only the lastest folder name
$dirname = end(explode("/", $path));
//display the target folder.
$FolderList .= ('<option value="">'.$path.'</option>');
while (false !== ($file = readdir($dir_handle)))
{
if($file!="." && $file!="..")
{
if (is_dir($path."/".$file))
{
//Display a list of sub folders.
$FolderList .= ListFolder($path."/".$file);
}
}
}
//closing the directory
closedir($dir_handle);
return $FolderList;
}
Each function call has its own variable scope. You need to union the returned value from your recursive call with the one that you’ve gathered in the while loop:
while(false !== ($file = readdir($dir_handle))) {
if($file!="." && $file!="..") {
if(is_dir($path."/".$file)) {
$FolderList .= ListFolder($path."/".$file);
}
}
}
You forgot to catch the return value of the function calls
$FolderList .= ListFolder($path."/".$file);
You just add one folder to the string, than call the function, but do nothing with the return value. Then you return $FolderList, which only contains the one entry you add before the while-loop
When *echo*ing it, its just send directly to the browser independently on which level of recursion you are, so you think, that $FolderList is full, but in fact its just every sungle $FolderList from each recursion step.
Alternative Method
function ListFolder($path, &$FolderList = array()) {
$path = str_replace("//","/",$path);
//using the opendir function
$dir_handle = #opendir($path) or die("Unable to open $path");
//Leave only the lastest folder name
$dirname = end(explode("/", $path));
//display the target folder.
$FolderList[] = '<option value="">'.$path.'</option>';
while(false !== ($file = readdir($dir_handle))) {
if($file!="." && $file!="..") {
if(is_dir($path."/".$file)) {
//Display a list of sub folders.
ListFolder($path."/".$file, $FolderList);
}
}
}
//closing the directory
closedir($dir_handle);
return $FolderList;
}
$paths = ListFolder(getcwd());
echo "<select>".implode("", $paths)."</select>";