【问题标题】:Uploading files without causing server side errors during the process在此过程中上传文件而不会导致服务器端错误
【发布时间】:2012-06-06 07:00:23
【问题描述】:

我不断调整我的软件并将其上传到服务器。由于我的客户一直在使用我的在线软件,如果当客户单击链接(例如在 1 秒标记处)时部分上传了 PHP 文件(假设上传需要 3 秒),他们会收到错误,因为文件还在上传中……

Parse error: syntax error, unexpected $end in /inc/functions.php on line 475

由于我在澳大利亚,我们的互联网......嗯......“不是很快”是一个很好的表达方式。

上传文件时是否使用了任何技术,以免客户使用该软件时出错?

我唯一能做的就是上传文件到另一个目录,然后运行一个 PHP 脚本,以超快的速度复制文件......但是有更好的解决方案吗?

最终代码

感谢下面的 Greg,我能够找出最好的做事方式。以为我会分享我的最终代码。这有点粗糙,但可以解决问题......希望它可以帮助某人

<?php

// root path
define('ABSPATH', dirname(__FILE__) . '/');

// messages
$GLOBALS['copied'] = array();
$GLOBALS['failed'] = array();
$GLOBALS['folders'] = array();

// you have to submit the form (added security)
if (isset($_POST['copy'])) {

    $GLOBALS['devuploads_folder'] = '_devuploads';

    function find_files($dir) {
        if ($dh = opendir(ABSPATH . $dir)) {
            while (($file = readdir($dh)) !== false) {

                // ignore files
                if ($file === '.' || $file === '..')
                    continue;

                // delete temporary files (optional)
                if ($file == '.DS_Store') {
                    unlink(ABSPATH . $dir . $file);
                    continue;
                }

                // determine paths                  
                $live_path = str_replace($GLOBALS['devuploads_folder'] . '/', '', $dir . $file);                
                $dev_file = $dir . $file;                   
                $live_file = $live_path;
                $dev_file_path = ABSPATH . $dir . $file;                    
                $live_file_path = ABSPATH . $live_path;

                // it's a file
                if (is_file(ABSPATH . $dir . $file)) {  

                    // check if the file has been updated or it's a brand newy
                    $updated_file = $new_file = false;
                    if (file_exists($live_file_path)) {                                 
                        $dev_file_modified = filemtime($dev_file_path);     
                        $live_file_modified = filemtime($live_file_path);                                               
                        if ($dev_file_modified > $live_file_modified)
                            $updated_file = true;                       
                    } else {
                        $new_file = true;
                    }

                    // move the file
                    if ($updated_file || $new_file) {
                        if (copy($dev_file_path, $dev_file_path . '.bak')) {
                            if (rename($dev_file_path . '.bak', $live_file_path))
                                if ($new_file)
                                    $GLOBALS['copied'][] = '<strong>New File:</strong> ' . $dev_file . ' moved to ' . $live_file;   
                                else
                                    $GLOBALS['copied'][] = $dev_file . ' moved to ' . $live_file;   
                            else
                                $GLOBALS['failed'][] = '<strong>Rename failed:</strong> ' . $dev_file . ' to ' . $live_file;
                        } else {
                            $GLOBALS['failed'][] = '<strong>Copy failed:</strong> ' . $dev_file . ' to ' . $dev_file . '.bak';
                        }
                    }

                // it's a folder
                } else if (is_dir(ABSPATH . $dir . $file)) {

                    // create new folder if it doesn't exist
                    if (!is_dir($live_file_path)) {
                        $GLOBALS['folders'][] = '<strong>Created:</strong> ' . $live_file;  
                        mkdir($live_file_path, 0755);   
                    }

                    // keep digging
                    find_files($dir . $file . '/');

                }

            }
            closedir($dh);
        }
    }

    find_files($GLOBALS['devuploads_folder'] . '/');

}

?>
<!DOCTYPE HTML>
<html>
<head>
    <title>Copy Changes</title>
    <style type="text/css">
    h1 {
        font: normal 20px Arial, Helvetica, sans-serif;
        line-height: 24px;
        }
    p, li {
        font: normal 14px Arial, Helvetica, sans-serif;
        line-height: 20px;
        }
    </style>
</head> 
<body>

<?php   
if (!empty($GLOBALS['failed'])) {
    echo '<h1>Errors</h1>';
    echo '<ul>';
    foreach($GLOBALS['failed'] AS $message) {
        echo '<li>' . $message . '</li>';
    }
    echo '</ul>';
}

if (!empty($GLOBALS['folders'])) {
    echo '<h1>New Folders</h1>';
    echo '<ul>';
    foreach($GLOBALS['folders'] AS $message) {
        echo '<li>' . $message . '</li>';
    }
    echo '</ul>';
}

if (!empty($GLOBALS['copied'])) {
    echo '<h1>Copied</h1>';
    echo '<ul>';
    foreach($GLOBALS['copied'] AS $message) {
        echo '<li>' . $message . '</li>';
    }
    echo '</ul>';
}

if (empty($GLOBALS['failed']) && empty($GLOBALS['folders']) && empty($GLOBALS['copied']))
    echo '<p>No updates made.</p>';
?>

<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
<input type="hidden" name="copy" value="1" />
<p><input type="submit" value="Copy Files" /></p>
</form>

</body>
</html>

【问题讨论】:

  • 这个错误通常是由于未完成的功能造成的。检查您是否有一对不完整的{}
  • @silent 它具有未完成功能的原因是因为文件已部分上传,正如我在问题中指定的那样......代码没有任何问题。
  • 好的,我想念这个问题。我虽然,通过上传是用户上传文件。不是源代码。
  • 你至少应该添加一些 POST var,它需要一个很长的密码或其他东西......POST 本身就是不好的安全性

标签: php upload


【解决方案1】:

如果您的服务器是 Linux(或其他 Unix 变体),那么 mv 命令是 原子 并且可以进行这种即时更新。先将文件复制到一个临时名称(如file.php.new),然后登录服务器并

mv file.php.new file.php

(即使file.php 存在也有效,它将被新的替换)。

【讨论】:

  • 谢谢@Greg!因此,如果我要更新 100 个文件,那么在上传之前不重命名每个文件并为每个文件运行 mv 命令的最佳方法是什么?我将所有文件上传到文件夹并使用 PHP 移动它们的想法是最佳选择吗?
  • 您可以编写一个脚本来执行此操作。但是,请务必移动它们而不是复制它们,这是关键点。你可以使用rename() 来做到这一点。
  • 有趣的是你为什么说move而不是copy。这有什么原因吗?我问的原因是我使用的 FTP 软件可以设置为仅上传已更改的文件,而不是上传每次需要几分钟的每个文件。最好在服务器上留下一个副本,这样上传时间只有几秒钟。 复制文件是否会导致某处出现问题?
  • 是的,复制是问题的根源。复制文件时,将字节从源移动到目标需要时间。您在问题中描述的场景中观察到了这一点(复制是通过网络链接完成的,因此很容易注意到)。当您在本地复制文件时会发生同样的事情,尽管您的 CPU 和硬盘驱动器比您的网络快得多。当您复制时,客户端可能会获得部分文件。但是,移动/重命名文件会将完整源文件移动到目标文件之上,不会留下部分文件间隙。
  • ftp 程序应该能够处理这个问题,至少当我在 NetBeans 中使用 ftp 选项时总是会发生这种情况(除非我另有说明)。当然,如果多个文件已更改并且一些文件依赖于其他文件,这仍然可能导致问题......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-23
  • 2020-03-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多