2009-05-29 10 views
16

Próbuję napisać skrypt, który prześle całą zawartość katalogu przechowywanego na moim serwerze na inne serwery za pośrednictwem ftp.Załaduj cały katalog przez PHP FTP

Czytałem przez documentation on www.php.net, ale nie mogę znaleźć sposobu, aby przesłać więcej niż jeden plik na raz.

Czy istnieje sposób, aby to zrobić, czy istnieje skrypt, który zaindeksuje ten katalog i utworzy tablicę plików do przesłania?

Z góry dziękuję za pomoc!

Odpowiedz

0

Jeśli chcesz jednocześnie przesłać wiele plików, musisz użyć wątku lub widelca.

nie jestem pewien o implentation wątek w PHP, ale trzeba spojrzeć na PHP SPL i/lub PEAR

Edit: Dzięki Frank Farmer aby dać mi znać, że nie było widelec() Funkcja w PHP znana jako pcntl_fork()

Będziesz także musiał pobierać rekursywnie cały katalog zawartości, aby móc załadować cały plik dla danego katalogu.

+1

PHP nie wątkuje, ale robi widelec (używając pcntl_fork()), a istnieją pewne podobne do owijki dla funkcjonalności widelca PHP. –

+0

dziękuję, za wskazówkę, dodałem link do mojego wpisu. –

+0

Nie polecam używania wideł. To owłosione rzeczy. O wiele łatwiej jest po prostu otworzyć wiele połączeń i użyć socket_select(), aby następnie pisać asynchronicznie. –

1

zrobić w pętli iteracja wszystkich plików w folderze

$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

Gdy masz połączenie otwarte, przesłać zawartość katalogu seryjnie jest prosta:

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

Przekazywanie wszystkie pliki równolegle byłyby trudniejsze.

+1

to tylko zaoszczędziło mi dużo czasu. Doskonały fragment kodu! –

0

Zakodowałem, skrypt przesyła cały folder z jego podfolderami i plikami.

Mam nadzieję, że ci to pomoże.

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

Więc wziąłem kod @ iYETER i opakowałem go jako obiekt klasy.

Można nazwać ten kod przez te linie:

$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(); 

To rekurencyjnie przeszukuje lokalny dir i umieszcza go na zdalnym reż krewnego. Jeśli natrafi na jakiekolwiek błędy, tworzy hierarchię tablicową każdego pliku i kodu wyjątku (do tej pory przechwytuję tylko 2, jeśli jest to kolejny błąd, teraz jest to domyślna trasa)

Klasa, w którą jest zawijana:

<?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; 
} 
}