我正在尝试编写一个脚本,将通过ftp将存储在我的服务器上的目录的全部内容上传到其他服务器。通过PHP FTP上传整个目录
我一直在阅读documentation on www.php.net,但似乎无法找到一次上传多个文件的方法。
有没有办法做到这一点,或者有一个脚本,将索引该目录并创建一个文件上传数组?
在此先感谢您的帮助!
我正在尝试编写一个脚本,将通过ftp将存储在我的服务器上的目录的全部内容上传到其他服务器。通过PHP FTP上传整个目录
我一直在阅读documentation on www.php.net,但似乎无法找到一次上传多个文件的方法。
有没有办法做到这一点,或者有一个脚本,将索引该目录并创建一个文件上传数组?
在此先感谢您的帮助!
如果您想要一次上传多个文件,您需要使用线程或分支。
我不知道在PHP中的线程implentation的,但你应该看看的PHP SPL和/或PEAR
编辑:感谢Frank农民,让我知道,有一个叉()函数在PHP中被称为pcntl_fork()
您还必须递归获取整个内容目录才能上传给定目录的所有文件。
做一个循环,通过所有文件的文件夹
$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)
}
}
在迭代一旦你有一个连接打开,上传目录的内容顺序很简单:
foreach (glob("/directory/to/upload/*.*") as $filename)
ftp_put($ftp_stream, basename($filename) , $filename, FTP_BINARY);
上传所有文件并行将会更加困难。
我编码它,脚本上传整个文件夹与它的子文件夹和文件。
我希望它能帮助你。
<?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);
?>
所以,我拿了@ iYETER的代码,并把它作为一个类对象包装起来。
您可以通过这些线路把这个代码:
$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();
它递归抓取本地目录,并把它放在相对偏远目录。如果它遇到任何错误,它会创建每个文件及其异常代码的阵列层次结构(如果它是另一个错误,它现在会抛出默认路由),并创建一个数组层次结构。
<?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;
}
}
PHP没有线程,但它叉(使用pcntl_fork()),并且有一些类似线程的包装器用于PHP的fork功能。 – 2009-05-29 18:27:39
谢谢你的提示,我添加了链接到我的文章。 – 2009-05-29 18:37:50