2009-05-29 23 views
16

Ich versuche ein Skript zu schreiben, das den gesamten Inhalt eines auf meinem Server gespeicherten Verzeichnisses per FTP auf andere Server hochlädt.Gesamtes Verzeichnis über PHP hochladen FTP

Ich habe durch die documentation on www.php.net gelesen, aber kann nicht scheinen, eine Möglichkeit zu finden, mehr als eine Datei auf einmal zu laden.

Gibt es eine Möglichkeit, dies zu tun, oder gibt es ein Skript, das dieses Verzeichnis indiziert und ein Array von Dateien zum Hochladen erstellt?

Vielen Dank im Voraus für Ihre Hilfe!

Antwort

0

Wenn mehrere Dateien gleichzeitig hochgeladen werden sollen, müssen Sie thread oder fork verwenden.

Ich bin ein Thema implentation in PHP nicht sicher, aber Sie sollten einen Blick auf den PHP SPL und/oder PEAR

bearbeiten nehmen: Dank Frank Farmer mich wissen zu lassen, dass es eine Gabel() Funktion in PHP bekannt als pcntl_fork()

Sie müssen auch das gesamte Inhaltsverzeichnis rekursiv abrufen, um die gesamte Datei für ein bestimmtes Verzeichnis hochladen zu können.

+1

PHP nicht thread, aber es gibt fork (mit pcntl_fork()), und es gibt einige Thread-ähnliche Wrapper für PHP Fork-Funktionalität. –

+0

danke, für den Tipp habe ich den Link zu meinem Beitrag hinzugefügt. –

+0

Ich würde nicht empfehlen, Gabeln zu verwenden. Das ist haarige Sachen. Es ist viel einfacher, einfach mehrere Verbindungen zu öffnen und socket_select() zu verwenden, um dann asynchron zu schreiben. –

1

Tun Sie es in einer Schleife, die alle Dateien im Ordner Iterieren durch

$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

Sobald Sie eine Verbindung geöffnet haben, ist der Inhalt eines Verzeichnisses seriell Hochladen einfach:

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

Hochladen Alle Dateien parallel wären schwieriger.

+1

das hat mir gerade viel Zeit gespart. Exzellentes Code-Snippet! –

0

Ich habe es codiert, das Skript lädt den gesamten Ordner mit seinen Unterordnern und Dateien hoch.

Ich hoffe, es wird Ihnen helfen.

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

Also nahm ich @ iYETER-Code und wickelte es als ein Klassenobjekt.

Sie können von diesen Linien diesen Code nennen:

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

Es kriecht rekursiv lokales Verzeichnis und legt es auf Remote-Verzeichnis relativ. Wenn es irgendwelche Fehler trifft, erstellt es eine Array-Hierarchie von jeder Datei und ihrem Ausnahmecode (ich erfasse nur 2 bisher, wenn es ein anderer Fehler ist, wirft es die Standardroute für jetzt) ​​

Die Klasse, in die es verpackt ist:

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