2009-05-29 2 views
16

Sto provando a scrivere uno script che caricherà l'intero contenuto di una directory memorizzata sul mio server su altri server via ftp.Carica l'intera directory tramite PHP FTP

Ho letto lo documentation on www.php.net, ma non riesco a trovare un modo per caricare più di un file alla volta.

C'è un modo per farlo, oppure c'è uno script che indicizzerà quella directory e creerà una serie di file da caricare?

Grazie in anticipo per il vostro aiuto!

risposta

0

Se si desidera caricare più file contemporaneamente, è necessario utilizzare thread o fork.

non sono sicuro di un'implentation Discussione in PHP, ma si dovrebbe dare uno sguardo al PHP SPL e/o PEAR

Edit: Grazie a Frank Farmer per farmi sapere che c'era un bivio() funzione in PHP nota come pcntl_fork()

Dovrai anche ottenere l'intera directory del contenuto in modo ricorsivo per poter caricare tutto il file per una determinata directory.

+1

PHP non esegue il thread, ma esegue fork (utilizzando pcntl_fork()), e ci sono alcuni wrapper simili a thread per le funzionalità di fork di PHP. –

+0

grazie, per il suggerimento, ho aggiunto il link al mio post. –

+0

Non consiglierei di usare le forche. È roba pelosa. È molto più semplice aprire più connessioni e usare un socket_select() per scrivere in modo asincrono. –

1

farlo in un ciclo, scorrendo tutti i file nella cartella

$servername = $GLOBALS["servername"]; 
    $ftpUser = $GLOBALS["ftpUser"]; 
    $ftpPass = $GLOBALS["ftpPass"]; 
$conn_id = ftp_connect($servername) or die("<p style=\"color:red\">Error connecting to $servername </p>"); 

if(ftp_login($conn_id, $ftpUser, $ftpPass)) 
{ 
    $dir_handle = @opendir($path) or die("Error opening $path"); 

     while ($file = readdir($dir_handle)) { 
      ftp_put($conn_id, PATH_TO_REMOTE_FILE, $file) 
     } 
} 
12

volta che avete una connessione aperta, caricando il contenuto di una directory in serie è semplice:

foreach (glob("/directory/to/upload/*.*") as $filename) 
    ftp_put($ftp_stream, basename($filename) , $filename, FTP_BINARY); 

Caricamento tutti i file in parallelo sarebbero più difficili.

+1

questo mi ha appena salvato un sacco di tempo. Snippet di codice eccellente! –

0

L'ho codificato, lo script carica l'intera cartella con le sue sottocartelle e file.

Spero che ti possa aiutare.

<?php 
ob_start(); 
set_time_limit(0); 
//r10.net fatal 

$anadizin="uploadedeceginizdizin"; //this is the folder that you want to upload with all subfolder and files of it. 

$ftpsunucu="domain.com"; //ftp domain name 
$ftpusername="ftpuser"; //ftp user name 
$ftppass="ftppass"; //ftp passowrd 
$ftpdizin="/public_html"; //ftp main folder 





$arkadaslarlabardaydik = ftp_connect($ftpsunucu); 
$ictikguldukeglendik = ftp_login($arkadaslarlabardaydik, $ftpusername, $ftppass); 

if((!$arkadaslarlabardaydik) || (!$ictikguldukeglendik)) 
{ 
    echo "cant connect!"; 
    die(); 
} 


function klasoruoku($dizinadi) 
{ 
    global $nerdeyiz,$fulldizin,$ftpdizin,$arkadaslarlabardaydik,$ftpdizin; 

    chdir($dizinadi."\\"); 
    $dizin = opendir("."); 

    while($bilgi=readdir($dizin)) 
    { 
    if ($bilgi!='.' and $bilgi!='..' and $bilgi!="Thumbs.db") 
    { 
     $tamyol="$dizinadi\\$bilgi"; 

     $lokalkla=str_replace("".$nerdeyiz."\\","",$dizinadi).""; 
     $lokaldosya="$lokalkla\\$bilgi"; 
     $ftpyeyolla=str_replace(array("\\\\","\\"),array("/","/"),"$ftpdizin\\".str_replace("".$fulldizin."","",$dizinadi)."\\$bilgi"); 

     if(!is_dir($bilgi)) 
     { 
      $yükleme = ftp_put($arkadaslarlabardaydik, $ftpyeyolla, $tamyol, FTP_BINARY); 

      if (!$yükleme) 
      { 
       echo "$lokaldosya <font color=red>uploaded</font>"; echo "<br>"; fls(); 
      } 
      else 
      { 
       echo "$lokaldosya <font color=green>not uploaded</font>"; echo "<br>"; fls(); 
      } 
     } 
     else 
     { 
      ftp_mkdir($arkadaslarlabardaydik, $ftpyeyolla); 
      klasoruoku("$dizinadi\\$bilgi"); 
      chdir($dizinadi."\\"); 
      fls(); 
     } 
    } 
    } 
    closedir ($dizin); 
} 

function fls() 
{ 
    ob_end_flush(); 
    ob_flush(); 
    flush(); 
    ob_start(); 
} 

$nerdeyiz=getcwd(); 
$fulldizin=$nerdeyiz."\\$anadizin"; 
klasoruoku($fulldizin); 
ftp_close($arkadaslarlabardaydik); 

?> 
5

Quindi, ho preso il codice di @ iYETER e lo ha avvolto come oggetto di classe.

È possibile chiamare questo codice da queste linee:

$ftp = new FtpNew("hostname"); 

$ftpSession = $ftp->login("username", "password"); 

if (!$ftpSession) die("Failed to connect."); 

$errorList = $ftp->send_recursive_directory("/local/dir/", "/remote/dir/"); 
print_r($errorList); 

$ftp->disconnect(); 

Si esegue la scansione in modo ricorsivo dir locali, e lo inserisce dir relativo telecomando. Se si verificano errori, crea una gerarchia di array di ogni file e il loro codice di eccezione (ne acquisisco solo 2 fino a quel momento, se si tratta di un altro errore, per ora lo getta per impostazione predefinita)

La classe è racchiusa in:

<?php 
//Thanks for iYETER on http://stackoverflow.com/questions/927341/upload-entire-directory-via-php-ftp 

class FtpNew { 
private $connectionID; 
private $ftpSession = false; 
private $blackList = array('.', '..', 'Thumbs.db'); 
public function __construct($ftpHost = "") { 
    if ($ftpHost != "") $this->connectionID = ftp_connect($ftpHost); 
} 

public function __destruct() { 
    $this->disconnect(); 
} 

public function connect($ftpHost) {  
    $this->disconnect(); 
    $this->connectionID = ftp_connect($ftpHost); 
    return $this->connectionID; 
} 

public function login($ftpUser, $ftpPass) { 
    if (!$this->connectionID) throw new Exception("Connection not established.", -1); 
    $this->ftpSession = ftp_login($this->connectionID, $ftpUser, $ftpPass); 
    return $this->ftpSession; 
} 

public function disconnect() { 
    if (isset($this->connectionID)) { 
     ftp_close($this->connectionID); 
     unset($this->connectionID); 
    } 
} 

public function send_recursive_directory($localPath, $remotePath) { 
    return $this->recurse_directory($localPath, $localPath, $remotePath); 
} 

private function recurse_directory($rootPath, $localPath, $remotePath) { 
    $errorList = array(); 
    if (!is_dir($localPath)) throw new Exception("Invalid directory: $localPath"); 
    chdir($localPath); 
    $directory = opendir("."); 
    while ($file = readdir($directory)) { 
     if (in_array($file, $this->blackList)) continue; 
     if (is_dir($file)) { 
      $errorList["$remotePath/$file"] = $this->make_directory("$remotePath/$file"); 
      $errorList[] = $this->recurse_directory($rootPath, "$localPath/$file", "$remotePath/$file"); 
      chdir($localPath); 
     } else { 
      $errorList["$remotePath/$file"] = $this->put_file("$localPath/$file", "$remotePath/$file"); 
     } 
    } 
    return $errorList; 
} 

public function make_directory($remotePath) { 
    $error = ""; 
    try { 
     ftp_mkdir($this->connectionID, $remotePath); 
    } catch (Exception $e) { 
     if ($e->getCode() == 2) $error = $e->getMessage(); 
    } 
    return $error; 
} 

public function put_file($localPath, $remotePath) { 
    $error = ""; 
    try { 
     ftp_put($this->connectionID, $remotePath, $localPath, FTP_BINARY); 
    } catch (Exception $e) { 
     if ($e->getCode() == 2) $error = $e->getMessage(); 
    } 
    return $error; 
} 
}