从两台服务器移动和删除文件

时间:2014-02-12 09:12:14

标签: php file-io

在工作中,我们有一个网站,我们可以在其上发布可供下载的PDF文件(主要是用户通知等)。我们还管理我们的内部数据库以进行更新,并生成包含所有PDF文件的CD和USB棒,这些文件随产品一起发货。 因此,我构建了一个平台,生成这些PDF文件的所有工厂都可以上传它们。有时候,一个人会负责更新系统(同步两台服务器)。

我想在带有删除选项的文件旁边有一个链接。我已经使用简单的PHP脚本了。

<?php 
$deleter = new Deleter("./");
class Deleter {
    var $filename;
        var $ignorelist = array (
        '.',
        '..',
        'index.php',
        'del.php',
        'deletefile.php'
    );
    function Deleter($path="./") {
        $this->__construct($path);
    }
    function __construct($path="./") {

        $this->filename = basename(__FILE__);
        array_push($this->ignorelist, $this->filename);

        // insert page header
        $this->createHeader();

        // condition: create initial file list?
        if (isset($_GET['delete']) && !empty($_GET['delete'])) {

            // a path has been set, escape and use
            $path = basename($_GET['delete']);
            $path = urldecode($path);
            //$path = mysql_real_escape_string($path);

            // condition : Step 2: seek deletion confirmation?
            if (!isset($_GET['confirm']) || $_GET['confirm'] != 'aye') {
                $this->createConfirmationStep($path);

            // step 3: delete!  
            } else {
                $this->createShowDelete($path);
            }

        // step 1: no files selected, create file list  
        } else {
            echo '
                <p>These files are on the server:</p>
                <ul>
            ';
            $this->createFileList($path);
            echo '</ul>';
        }

        // insert page footer
        $this->createFooter();
    }


    /**
     * Step 1: Create a list of all files within a specific directory
     *
     * @param string $path The server path to look for files in 
     * @return array $fileList Array of all files, with file/directory details
     * @access public
     */
    function createFileList($path) {

        // condition : if the path isn't set, assume one
        if (!isset($path)) {
            $path = "./";
        }

        // temporary arrays to hold separate file and directory content
        $filelist = array();
        $directorylist = array();

        // get the ignore list, in local scope
        $ignorelist = $this->ignorelist;

        // Open directory and read contents
        if (is_dir($path)) {

            // loop through the contents (PHP4 compat)
            $dh  = opendir($path);
            while (false !== ($file = readdir($dh))) {

                // skip over any files in the ignore list
                if (!in_array($file, $ignorelist)) {

                    // condition : if it is a directory, add to dir list array
                    if (is_dir($path.$file)) {

                        $directorylist[] = array(
                            "path" => $path,
                            "file" => $file,
                            "filetype" => 'directory',
                            "date" => date("M d Y, H:i", filemtime($path.$file."")),
                            "filecount" => $this->countRelevantFiles($path.$file),
                            "filesize" => 0
                        );

                    // file, add to file array
                    } else {

                        $filelist[] = array(
                            "path" => $path,                            
                            "file" => $file,
                            "filetype" => $this->getFileType($path.$file) . " file",
                            "date" => date("M d Y, H:i", filemtime($path.$file."")),
                            "filecount" => 0,
                            "filesize" => $this->getFileSize(filesize($path.$file))
                        );
                    }
                }
            }
        }

        // merge file and directory lists
        $finalList = array_merge($directorylist, $filelist);

        // loop through each file
        foreach ($finalList as $key => $value) {

            // condition : add trailing slash for directories
            $trailingslash = ($value['filetype'] == 'directory' ) ? '/' : ''; 

            // condition : if it is a directory, display count of subfiles
            if ($value['filetype'] == 'directory') {
                $fileending = ($value['filecount'] == 1) ? 'item' : 'items';
                $filedetails = ' (contains '.$value['filecount'].' '.$fileending.')';

            // else, if it is a file, display file size
            } else {
                $filedetails = ' ('.$value['filesize'].')';
            }


            // create the html for each project
            echo '
                <li class="' . $value['filetype'].'" id="file_' . urlencode($value['file']) . '">
                        <strong>' . $value['file'] . '</strong> / 

                        ';



            echo '

                    <a href="./'.$this->filename.'?delete='.urlencode($value['file'].$trailingslash).'">
                        Delete
                    </a>
                </li>
            ';
        }
    }


    /**
     * count the number of files in a directory, not including the list of ignorable files
     * 
     * @param string $path The server path to look for files in 
     * @return int $count The number of relevant files
     * @access private
     */
    function countRelevantFiles($path, $count = 0) {

        // open the directory
        if (is_dir($path)) {

            // loop through all files, checking if we should count the current one
            $dh  = opendir($path);
            while (false !== ($file = readdir($dh))) {

                if (!in_array($file, $this->ignorelist)) {
                    $count++;
                    if(is_dir($path."/".$file)) {
                        $count = $this->countRelevantFiles($path."/".$file, $count);
                    } 
                }
            }
        }

        // return the result
        return $count;
    }



    /**
     * list all sub-files of a directory
     * 
     * @param string $path The server path to look for files in 
     * @return void
     * @access private
     */
    function listFilesToDelete($path) {

        // open the directory
        if (is_dir($path)) {

            // loop through all files, checking if we should count the current one
            $dh  = opendir($path);
            while (false !== ($file = readdir($dh))) {

                if (!in_array($file, $this->ignorelist)) {

                    echo '<li>'.$path.'/'.$file.'</li>'; 

                    if(is_dir($path."/".$file)) {
                        $this->listFilesToDelete($path."/".$file);
                    } 
                }
            }
        }
    }



    /**
     * Delete files
     * 
     * @param string $path The server path to delete
     * @return void 
     * @access private
     */
    function delete($path) {
        // Simple delete for a file
        if (is_file($path)) {

            echo '<li>deleting file: ' . $path . '</li>';

if (copy($path, "../trash/".$path)) {
  unlink($path);
}
        } 

        }




    /**
     * Create a nice readable filesize from the number of bytes in a file
     *
     * @param int $size the size in bytes
     * @param string $retstring 
     *
     * @return string the size in nice words
     */
    function getFileSize($size, $retstring = null)
    {
        $sizes = array('B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
        if ($retstring === null) { $retstring = '%01.2f %s'; }
        $lastsizestring = end($sizes);
        foreach ($sizes as $sizestring) {
                if ($size < 1024) { break; }
                if ($sizestring != $lastsizestring) { $size /= 1024; }
        }
        if ($sizestring == $sizes[0]) { $retstring = '%01d %s'; } // Bytes aren't normally fractional
        return sprintf($retstring, $size, $sizestring);
    }


    /**
     * Function to find a file type for a given filename
     * 
     * @param string $file filename/path
     * @return string $extension file type
     */
    function getFileType($file="") {

        // get file name 
        $filearray = explode("/", $file);
        $filename = array_pop($filearray);

        // condition : if no file extension, return
        if(strpos($filename, ".") === false) return false;

        // get file extension
        $filenamearray = explode(".", $filename);
        $extension = $filenamearray[(count($filenamearray) - 1)];
        return $extension;

    }



/* Page Building Methods */


    /**
     * Create page header
     */
    function createHeader(){
        echo '

        ';      
    }


    /**
     * Create page footer
     */
    function createFooter(){
        echo '

        ';
    }



    /**
     * Create confirmation step
     */
    function createConfirmationStep($path){
        echo '
            <p><a href="'.$this->filename.'">� back to file list</a></p>
            <p>Please confirm that you want to delete the following files:</p>
            <p class="confirm"><a href="'.$this->filename.'?delete='.$path.'&confirm=aye">Delete</a></p>
            <ol>
                <li>'.$path.'</li>
        ';

        $this->listFilesToDelete($path);

        echo '
            </ol>
            <p class="confirm"><a href="'.$this->filename.'?delete='.$path.'&confirm=aye">Delete</a></p>
        ';
    }



    /**
     * Show the files you're deleting
     */
    function createShowDelete($path){
        echo '
            <p><a href="'.$this->filename.'">� back to file list</a></p>
            <p>The following items have been removed:</p>
            <ol>
        ';

        $this->delete($path);

        echo '
            </ol>
            <p><strong>Deletion complete.</strong></p>
            <p><a href="'.$this->filename.'">� back to file list</a></p>
        ';
    }

}

?>

现在我想要做的是删除一台服务器上的文件,例如server1.com/files/并将同一文件从server2.com/files/移至server2.com/trash /

我可以完全访问这两台服务器。有没有办法做到这一点?

2 个答案:

答案 0 :(得分:0)

既然你没有告诉我们你运行什么操作系统的PHP脚本,我假设你有一个linux。 因为您需要从一台服务器执行此操作,所以您需要为另一台服务器提供passwordless ssh access。那么你需要创建一个利用mvrsync来执行所需文件操作的bash脚本。然后你可以使用php的exec()函数执行并从网页上将文件名参数发送到shell脚本。

答案 1 :(得分:0)

我认为最好使用--delete选项在ssh上配置rsync。像这样的东西

/usr/bin/rsync -avz --delete /path/files -e "ssh" userforsync@$SECONDARYSERVER:/path/files

其中$ SECONDARYSERVER是dns名称或ip。要使其工作,您应该接受辅助服务器上的公钥验证,并将公钥添加到授权密钥