如何在PHP中同步两个文件夹?

时间:2010-05-06 06:53:04

标签: php synchronization

我使用的是Windows,Mysql DB,PHP

我正在构建Joomla组件,其功能之一是同步文件夹 我想同步两个不同名称的文件夹..我该怎么做?它必须在同一台机器上,不涉及两个不同的服务器..

如何在PHP中同步两个文件夹?

已更新

在Alex回复的背景下

如果我在一个文件夹中编辑任何.jpg文件并使用相同的名称保存它,该文件是否已存在于其他文件夹中。我希望这个编辑后的图片转移到另一个文件夹。我也有Joomla的嵌套文件,可以进行比较

更新2

我有一个递归函数,它会输出文件夹的完整结构...如果你可以用它来连接你的解决方案......

<?
function getDirectory($path = '.', $ignore = '') {
    $dirTree = array ();
    $dirTreeTemp = array ();
    $ignore[] = '.';
    $ignore[] = '..';

    $dh = @opendir($path);

    while (false !== ($file = readdir($dh))) {

        if (!in_array($file, $ignore)) {
            if (!is_dir("$path/$file")) {
                $stat = stat("$path/$file");
                $statdir = stat("$path");
                $dirTree["$path"][] = $file. " === ". date('Y-m-d H:i:s', $stat['mtime']) . " Directory == ".$path."===". date('Y-m-d H:i:s', $statdir['mtime']) ;

            } else {

                $dirTreeTemp = getDirectory("$path/$file", $ignore);
                if (is_array($dirTreeTemp))$dirTree = array_merge($dirTree, $dirTreeTemp);
            }
        }
    }
    closedir($dh);

    return $dirTree;
}


$ignore = array('.htaccess', 'error_log', 'cgi-bin', 'php.ini', '.ftpquota');

$dirTree = getDirectory('.', $ignore);
?>
<pre>
    <?
    print_r($dirTree);
    ?>
</pre> 

4 个答案:

答案 0 :(得分:5)

我刚跑了这个,似乎有用了

function sync() {

    $files = array();
    $folders = func_get_args();

    if (empty($folders)) {
        return FALSE;
    }

    // Get all files
    foreach($folders as $key => $folder) {
        // Normalise folder strings to remove trailing slash
        $folders[$key] = rtrim($folder, DIRECTORY_SEPARATOR);   
        $files += glob($folder . DIRECTORY_SEPARATOR . '*');    
    }

    // Drop same files
    $uniqueFiles = array();
    foreach($files as $file) {
        $hash = md5_file($file);

        if ( ! in_array($hash, $uniqueFiles)) {
            $uniqueFiles[$file] = $hash; 
        }
    }


    // Copy all these unique files into every folder
    foreach($folders as $folder) {
        foreach($uniqueFiles as $file => $hash) {
                copy($file, $folder . DIRECTORY_SEPARATOR . basename($file));
        }
    }
    return TRUE;    
}

// usage

sync('sync', 'sync2');

您只需给它一个要同步的文件夹列表,它就会同步所有文件。它将尝试跳过出现相同的文件(即他们的哈希碰撞的文件)。

然而,这并未考虑最后修改日期或任何内容。你必须修改自己才能做到这一点。它应该非常简单,请查看filemtime()

另外,如果代码很糟糕,请抱歉。我曾经让它递归,但我失败了:(

对于单向副本,请尝试此

$source = '/path/to/source/';
$destination = 'path/to/destination/';

$sourceFiles = glob($source . '*');

foreach($sourceFiles as $file) {

    $baseFile = basename($file);

    if (file_exists($destination . $baseFile)) {

        $originalHash = md5_file($file);
        $destinationHash = md5_file($destination . $baseFile);
        if ($originalHash === $destinationHash) {
            continue;
        }

    }
    copy($file, $destination . $baseFile);
}

听起来您只想将所有文件从一个文件夹复制到另一个文件夹。第二个例子就是这样做的。

答案 1 :(得分:2)

我使用它,它似乎工作,如果不存在也会制作新的目录.....

//sync the 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); 
                @mkdir($dest); 
                chmod($dest,$options['filePermission']); 
            } 
        } else { 
            if ($source[strlen($source)-1]=='/') { 
                //Copy parent directory with new name and all its content 
                @mkdir($dest,$options['folderPermission']); 
                chmod($dest,$options['filePermission']); 
            } else { 
                //Copy parent directory with new name and all its content 
                @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; 
} 
//end of function

echo smartCopy('media', 'mobile/images');

答案 2 :(得分:1)

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(md5_file($src . '/' . $file) !== md5_file($dst . '/' . $file))
             {
                echo 'copying' . $src . '/' . $file; echo '<br/>';
                copy($src . '/' . $file, $dst . '/' . $file);
             }
         } 
      } 
  } 
 closedir($dir); 
}

答案 3 :(得分:0)

如果它在Linux / Posix系统上(取决于您拥有的访问权限),它可能会更简单/更快:

$chk=`rsync -qrRlpt --delete $src $dest`;

下进行。

相关问题