2012-06-01 5 views
6

Apporto continuamente modifiche al mio software e lo carico sul server. Poiché i miei clienti utilizzano sempre il mio software online per tutto il tempo, se un file PHP viene parzialmente caricato (diciamo che occorrono 3 secondi per caricarlo) quando un cliente fa clic su un link (ad esempio al segno 1 secondo) riceve un errore perché il file è ancora caricando ...Caricamento dei file senza causare errori sul lato server durante il processo

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

Come io sono in Australia, il nostro internet ... beh ... "non è molto veloce" è un bel modo di metterlo.

Esistono tecniche utilizzate per caricare i file in modo che non causino errori ai clienti che utilizzano il software?

L'unica cosa che posso fare è caricare file per dire un'altra directory, quindi eseguire uno script PHP che copia i file in modo super veloce ... Ma ci sono soluzioni migliori?

codice finale

Grazie a Greg di seguito sono stato in grado di capire il modo migliore di fare le cose. Ho pensato di condividere il mio codice finale. E 'un po' ruvido, ma fa il trucco ... Speriamo che aiuta qualcuno

<?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> 
+0

questo errore è in genere causato dalla funzione non completata. Controlla se hai una coppia incompleta di '{' e '}' – ariefbayu

+1

@silent la ragione per cui ha una funzione incompleta è perché il file è parzialmente caricato come specificato nella mia domanda ... Non c'è niente di sbagliato nel codice. –

+0

ok, non ho capito la domanda. Io però, caricando è l'utente che carica i file. Codice sorgente non – ariefbayu

risposta

6

Se il server è Linux (o altra variante di Unix), quindi il comando mv è atomica e può fare questo tipo di aggiornamento istantaneo . In primo luogo copiare il file a un nome temporaneo (come file.php.new), e quindi accedere al server e

mv file.php.new file.php 

(questo funziona anche se file.php esiste, esso sarà sostituito da quello nuovo).

+0

Grazie a @Greg! Quindi, se dovessi aggiornare dire 100 file, quale sarebbe il modo migliore senza rinominare ogni file prima di caricare ed eseguire il comando 'mv' per ogni file? La mia idea di caricare tutti i file in una cartella e utilizzare PHP per spostarli è l'opzione migliore? –

+0

Puoi scrivere uno script per farlo. Tuttavia, assicurati di * spostarli * invece di * copiarli *, questo è il punto chiave. Puoi usare ['rename()'] (http://php.net/rename) per farlo. –

+0

Interessante il motivo per cui hai detto di _move_ invece di _copy_. C'è una ragione per questo? Il motivo per cui chiedo è il software FTP che utilizzo che posso impostare per caricare solo i file che sono cambiati invece di caricare ogni file che richiede alcuni minuti ogni volta. Sarebbe fantastico lasciare un duplicato sul server in modo che il tempo di caricamento sia di pochi secondi. _copying_ i file causano problemi da qualche parte? –