The first argument to copy() function cannot be a directory? - php

$base = dirname(__FILE__).'/themes/';
$target = dirname( STYLESHEETPATH ).'/';
$directory_folders = new DirectoryIterator($base);
foreach ($directory_folders as $folder)
{
if (!$folder->isDot()) {
echo '<p>source: '.$folder->getRealPath();
//returns: C:\xampplite\htdocs\test\wp-content\plugins\test\themes\testtheme-1
echo '<br>target: '.$target;
//returns: C:\xampplite\htdocs\test/wp-content/themes/
copy($folder->getRealPath(), $target);
//returns: Error. The first argument to copy() function cannot be a directory
}
}die;
UPDATE: On Pascal's suggested answer, here's my amended code. This works.
function recurse_copy(){
$src = dirname(__FILE__).'/themes/';
$dst = dirname( STYLESHEETPATH ).'/';
$dir = opendir($src);
#mkdir($dst);
while(false !== ( $file = readdir($dir)) )
{
if (( $file != '.' ) && ( $file != '..' ))
{
if ( is_dir($src . '/' . $file) ) {
recurse_copy_recurse($src . '/' . $file,$dst . '/' . $file);
}
else {
copy($src . '/' . $file,$dst . '/' . $file);
}
}
}
closedir($dir);
}
function recurse_copy_recurse($src,$dst){
$dir = opendir($src);
#mkdir($dst);
while(false !== ( $file = readdir($dir)) )
{
if (( $file != '.' ) && ( $file != '..' ))
{
if ( is_dir($src . '/' . $file) ) {
recurse_copy_recurse($src . '/' . $file,$dst . '/' . $file);
}
else {
copy($src . '/' . $file,$dst . '/' . $file);
}
}
}
closedir($dir);
}

No, the copy() function is not recursive : it cannot copy folders and their contents.
But if you take a look at the users's notes on that manual page, you'll find some propositions of recursive implementations.
For example, here's a recursive function proposed by gimmicklessgpt (quoting his post) :
<?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);
}
?>
Edit after the edit of the question :
You are calling your function passing it parameters :
recurse_copy($src . '/' . $file,$dst . '/' . $file);
But your function is defined as taking no parameter :
function recurse_copy(){
$src = dirname(__FILE__).'/themes/';
$dst = dirname( STYLESHEETPATH ).'/';
...
You should correct your function's definition, so it takes parameters -- and not initialize those $src and $dst inside the function, but on its first call.

Related

how to check in a loop for a folder or a file in php

For copying a folder and a file in php i use this loop:
if(is_dir($_POST['copyfile'])) {
$copyfolder = recurse_copy($src_folder,$dest_folder);
if( $copyfolder) {
echo 'succeed-folder';
exit;
}
else {
echo 'failed-folder';
exit;
}
}
else {
$copy = copy( $src_file_url, $dest_file );
if($copy) {
echo 'succeed-file';
exit;
}
else {
echo 'failed-file';
exit;
}
}
When copying a folder instead of a file, i check it with: if(is_dir($_POST['copyfile']))
In the case that it is really a folder, it copies the files in the folder correctly but gives me this echo: failed-folder
So there must be something wrong with the loop. What is wrong with the loop? I only want to distinguish if a folder or a file was copied with an echo
This is the function:
function recurse_copy($src_folder,$dest_folder ) {
$copydir = opendir($src_folder);
while(false !== ( $folder = readdir($copydir)) ) {
if (( $folder != '.' ) && ( $folder != '..' )) {
if ( is_dir($src_folder . '/' . $folder) ) {
recurse_copy($src_folder. '/' . $folder,$dest_folder . '/' . $folder);
}
else {
copy($src_folder. '/' . $folder , $dest_folder . '/' . $folder);
}
}
}
closedir($copydir);
}
You do not have a return statement at all. Therefore the function returns "void" which is evaluated to false. You need to return a bool value indicating if an error occurred.
This version does not stop the copy process, it just tracks if all operations were successful:
function recurse_copy($src_folder,$dest_folder ) {
$success = true;
$copydir = opendir($src_folder);
if(!$copydir)
return false;
while(false !== ( $folder = readdir($copydir)) ) {
if (( $folder != '.' ) && ( $folder != '..' )) {
if ( is_dir($src_folder . '/' . $folder) ) {
$success = recurse_copy($src_folder. '/' . $folder,$dest_folder . '/' . $folder) && $success;
}
else {
$success = copy($src_folder. '/' . $folder , $dest_folder . '/' . $folder) && $success;
}
}
}
closedir($copydir);
return $success;
}
An example of how you could alter the recurse_copy() function is to test each point which can be a problem - opendir(), mkdir() and copy() and they return false if any step fails. So this value is checked to stop the loop on failure and then returned at the end...
function recurse_copy($src,$dst) {
$dir = opendir($src);
// As long as opendir is OK, then mkdir, or set failure
$success = ($dir)?mkdir($dst):false;
while($success && (false !== ( $file = readdir($dir))) ) {
if (( $file != '.' ) && ( $file != '..' )) {
if ( is_dir($src . '/' . $file) ) {
$success = recurse_copy($src . '/' . $file,$dst . '/' . $file);
}
else {
$success = copy($src . '/' . $file,$dst . '/' . $file);
}
}
}
if ( $dir ) {
closedir($dir);
}
return $success;
}

recursively copy a specific file extension php

I am writing a function to recursively copy a specific file type from one folder to the other, but the function copies all the files in the folder.
function recurse_copy($src, $dst) {
$dir = opendir($src);
#mkdir($dst);
while (false !== ( $file = readdir($dir))) {
if (( $file != '.' ) && ( $file != '..' )) {
if (is_dir($src . '/' . $file)) {
if ($file->getExtension() == "pdf") {
recurse_copy($src . '/' . $file, $dst . '/' . $file);
}
} else {
copy($src . '/' . $file, $dst . '/' . $file);
}
}
} closedir($dir);
}
// if statements for
$itp = new RecursiveDirectoryIterator("foldername/", > FilesystemIterator::SKIP_DOTS);
$displayp = Array('pdf');
$i = 0;
foreach (new RecursiveIteratorIterator($itp) as $filepop) {
if (in_array(strtolower(array_pop(explode('.', $filepop))), $displayp))
if ($filepop->getExtension() == "pdf") {
echo >
recurse_copy("a", "b");
}
}
$itcopy = new RecursiveDirectoryIterator("foldername/", FilesystemIterator::SKIP_DOTS);
$displayp = Array ( 'pdf' );
foreach(new RecursiveIteratorIterator($itcopy) as $filecopy)
{
if (in_array(strtolower(array_pop(explode('.', $filecopy))), $displayp))
if ($filecopy->getExtension()=="pdf"){
copy($filecopy->getrealPath(),'pdf_folder/'.$filecopy->getFilename()) ;
}
}

Unlinking files and directories in PHP

The following code successfully removes sub directories and the files within them.
However it also removes all files in the directory above what is specified as $dir. This is not desired.
Can anybody see what is wrong with the code?
private function unlinkPubDirectory()
{
$dir = DIR_DOWNLOAD_PUB;
$h1 = opendir($dir);
while ($subdir = readdir($h1)) {
$h2 = opendir($dir . $subdir);
while ($file = readdir($h2)) {
#unlink($dir . $subdir . '/' . $file);
}
closedir($h2);
#rmdir($dir . $subdir);
}
closedir($h1);
}
As marked in the comments you should check for '..' as a possible file/directory and omit it. Additionally, check for errors without the '#'-sign.
private function unlinkPubDirectory()
{
$dir = DIR_DOWNLOAD_PUB;
$h1 = opendir($dir);
while ($subdir = readdir($h1)) {
if ($subdir == '..') continue; // don't do anything with '..'
$h2 = opendir($dir . $subdir);
while ($file = readdir($h2)) {
unlink($dir . $subdir . '/' . $file);
}
closedir($h2);
rmdir($dir . $subdir);
}
closedir($h1);
}
This will show you what is being deleted
while ($subdir = readdir($h1)) {
$h2 = opendir($dir . $subdir);
while ($file = readdir($h2)) {
echo "<p>will remove file " . ($dir . $subdir . '/' . $file);
}
closedir($h2);
echo "<p>will remove dir " . ($dir . $subdir);
}
HINT: check for . or .. folders and ignore them

How to copy the only particular extension file in php?

Hello I am using following code for copy the files from one directory to another directory its worked like a charms This is my code:
<?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);
} if(isset($_POST["source"]) && isset($_POST["destination"])){
$src = $_POST["source"];
$dst = $_POST["destination" ];
recurse_copy($src,$dst);
}
?>
now I want to copy only the image files from the source folder.How can i do that?
Getimagesize can help you. It return false on error. File not image is error.
<?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 {
/////
if(!getimagesize($src . '/' . $file,$dst . '/' . $file)) continue;
/////
copy($src . '/' . $file,$dst . '/' . $file);
}
}
}
closedir($dir);
} if(isset($_POST["source"]) && isset($_POST["destination"])){
$src = $_POST["source"];
$dst = $_POST["destination" ];
recurse_copy($src,$dst);
}
?>
OR
You just can check file extension:
$ext = end(explode('.',$file));
But it can lie.
I see 2 ways:
You make an array of the possible file extensions, and check end of
$file var for every file.
Or you use exif_imagetype() function along with the Imagetype
contants to determine the file type from the signature. Documentation
is here. However, there is a dependency for this, for details
see the first user contributed note.

move all files and folders in a folder to another?

I want to move all files and folders inside a folder to another folder. I found a code to copy all files inside a folder to another folder.
move all files in a folder to another
// Get array of all source files
$files = scandir("source");
// Identify directories
$source = "source/";
$destination = "destination/";
// Cycle through all source files
foreach ($files as $file) {
if (in_array($file, array(".",".."))) continue;
// If we copied this successfully, mark it for deletion
if (copy($source.$file, $destination.$file)) {
$delete[] = $source.$file;
}
}
// Delete all successfully-copied files
foreach ($delete as $file) {
unlink($file);
}
How do I change this to move all folders and files inside this folder to another folder.
This is what i use
// Function to remove folders and files
function rrmdir($dir) {
if (is_dir($dir)) {
$files = scandir($dir);
foreach ($files as $file)
if ($file != "." && $file != "..") rrmdir("$dir/$file");
rmdir($dir);
}
else if (file_exists($dir)) unlink($dir);
}
// Function to Copy folders and files
function rcopy($src, $dst) {
if (file_exists ( $dst ))
rrmdir ( $dst );
if (is_dir ( $src )) {
mkdir ( $dst );
$files = scandir ( $src );
foreach ( $files as $file )
if ($file != "." && $file != "..")
rcopy ( "$src/$file", "$dst/$file" );
} else if (file_exists ( $src ))
copy ( $src, $dst );
}
Usage
rcopy($source , $destination );
Another example without deleting destination file or folder
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);
}
Please See: http://php.net/manual/en/function.copy.php for more juicy examples
Thanks
:)
Use rename instead of copy.
Unlike the C function with the same name, rename can move a file from one file system to another (since PHP 4.3.3 on Unix and since PHP 5.3.1 on Windows).
You need the custom function:
Move_Folder_To("./path/old_folder_name", "./path/new_folder_name");
function code:
function Move_Folder_To($source, $target){
if( !is_dir($target) ) mkdir(dirname($target),null,true);
rename( $source, $target);
}
Think this should do the trick:
http://php.net/manual/en/function.shell-exec.php
shell_exec("mv sourcedirectory path_to_destination");
Hope this help.
I think the answers are not complete for me, beacuse DIRECTORY_SEPARATOR are not defined on any answer (thans to Edgar Aivars for remember that!), but I want to write my solution for move (rename), copy and delete directory structures (based on this post info, the credits are for yours!).
defined('DS') ? NULL : define('DS',DIRECTORY_SEPARATOR);
function full_move($src, $dst){
full_copy($src, $dst);
full_remove($src);
}
function full_copy($src, $dst) {
if (is_dir($src)) {
#mkdir( $dst, 0777 ,TRUE);
$files = scandir($src);
foreach($files as $file){
if ($file != "." && $file != ".."){
full_copy("$src".DS."$file", "$dst".DS."$file");
}
}
} else if (file_exists($src)){
copy($src, $dst);
}
}
function full_remove($dir) {
if (is_dir($dir)) {
$files = scandir($dir);
foreach ($files as $file){
if ($file != "." && $file != ".."){
full_remove("$dir".DS."$file");
}
}
rmdir($dir);
}else if (file_exists($dir)){
unlink($dir);
}
}
I hope this hepls anyone! (lile me in the future :D )
EDIT: Spell corrections... :(
My attempt at a recursive move function, after days of research and going through other excellent examples out there.
It provides for an overwriteExisting flag for choice. Consequently, if the overwriteExisting flag is false, the file will not be moved and the folder containing the file would not be removed.
function moveRecursive($sourcePath, $targetPath, $overwriteExisting) {
clearstatcache(); // not sure if this helps, or is even required.
$dir = opendir($sourcePath);
while (($file = readdir($dir)) !== false) {
echo nl2br($file . "\n");
if ($file != "." && $file != "..") {
if (is_dir($sourcePath . "/" . $file) == true) {
if (is_dir($targetPath. "/" . $file) == false) {
// I believe rename would be faster than copying and unlinking.
rename($sourcePath . "/" . $file, $targetPath. "/" . $file);
} else {
moveRecursive($sourcePath . "/" . $file, $targetPath ."/" . $file, $overwriteExisting);
if ($files = glob($sourcePath . "/*")) {
// remove the empty directory.
if (#rmdir($sourcePath . "/" . $file) == false) {
echo nl2br("rmdir has not removed empty directory " . $sourcePath . "/" . $file . "\n");
}
} else {
// when overwriteExisting flag is false, there would be some files leftover.
echo nl2br("cannot remove. not empty, count = " . count(glob($sourcePath . "/*")) . " -> " . $sourcePath . "/" . $file . "\n");
}
}
} else {
if (file_exists($targetPath. "/" . $file)) {
if ($overwriteExisting == true) {
// overwrite the file.
rename($sourcePath . "/" . $file, $targetPath. "/" . $file);
}
} else {
// if the target file does not exist, simply move the file.
rename($sourcePath . "/" . $file, $targetPath. "/" . $file);
}
}
}
}
closedir($dir);
}
I have spent about 3 hours testing this in many different scenarios, and it works most of the time. Although, sometimes, it gives me an Access denied code(5) error on Windows, which I have been unable to figure out. This is why I have put the clearstatcache() function up at the top, after reading up on its documentation. I don't know whether this is its appropriate usage. I can definitely imagine that it would slow down the function.
I can also imagine that this method may be faster than the copy -> unlink cycle, because if a target sub-folder does not exist, the whole folder tree below would be just moved. However, I am not sure and don't have the experience to conduct exhaustive tests, yet.
$src = 'user_data/company_2/T1/';
$dst = 'user_data/company_2/T2/T1/';
rcopy($src, $dst); // Call function
// Function to Copy folders and files
function rcopy($src, $dst) {
if (file_exists ( $dst ))
rrmdir ( $dst );
if (is_dir ( $src )) {
mkdir ( $dst );
$files = scandir ( $src );
foreach ( $files as $file )
if ($file != "." && $file != "..")
rcopy ( "$src/$file", "$dst/$file" );
} else if (file_exists ( $src ))
copy ( $src, $dst );
rrmdir ( $src );
}
// Function to remove folders and files
function rrmdir($dir) {
if (is_dir($dir)) {
$files = scandir($dir);
foreach ($files as $file)
if ($file != "." && $file != "..") rrmdir("$dir/$file");
rmdir($dir);
}
else if (file_exists($dir)) unlink($dir);
}
I use it
// function used to copy full directory structure from source to target
function full_copy( $source, $target )
{
if ( is_dir( $source ) )
{
mkdir( $target, 0777 );
$d = dir( $source );
while ( FALSE !== ( $entry = $d->read() ) )
{
if ( $entry == '.' || $entry == '..' )
{
continue;
}
$Entry = $source . '/' . $entry;
if ( is_dir( $Entry ) )
{
full_copy( $Entry, $target . '/' . $entry );
continue;
}
copy( $Entry, $target . '/' . $entry );
}
$d->close();
} else {
copy( $source, $target );
}
}

Categories