Php копирование файлов ftp
Примеры сохранения и чтения текстовых данных и массивов в файлы.
You do not have access to this ftp server!
" ); // login with username and password, or give invalid user messageif ((! $conn_id ) || (! $login_result )) < // check connection
// wont ever hit this, b/c of the die call on ftp_login
echo "FTP connection has failed!
" ;
echo "Attempted to connect to $ftp_server for user $ftp_user_name " ;
exit;
> else // echo "Connected to $ftp_server, for user $ftp_user_name
";
>
$upload = ftp_put ( $conn_id , $destination_file , $file , FTP_BINARY ); // upload the file
if (! $upload ) < // check upload status
echo "
FTP upload of $myFileName has failed!
" ;
> else echo "Uploading $myFileName Complete!
" ;
>
ftp_close ( $conn_id ); // close the FTP stream
>
?>
This took me a few hours to work out. It is based on the code below I've just added a string replace to convert pathname given by Windows to Unix pathname. Hope it saves somebody some time. Enjoy! (Also, delete file function is included:))
Here is an example for downloading a remote ftp structure to local server, useful for migrating sites from one server to another, especially when you are upgrading ensim ;)
I didn't quite like my FTP program since I had to make all the settings all over when i restarted the client, so I made this script for simple ftp uploading, its running as a CLI app.
//if STDIN isn't defined, define it
if (! defined ( "STDIN" ))
define ( "STDIN" , fopen ( "php://stdin" , "r" ));
echo "FTP file uploader\r\n\r\n" ;
//trim() all the fgets cause it seams to add a \n
$server = trim ( fgets ( STDIN ));
$username = trim ( fgets ( STDIN ));
$password = trim ( fgets ( STDIN ));
$connect = ftp_connect ( $server );
$login = ftp_login ( $connect , $username , $password );
if ((! $connect ) || (! $login ))
exit( "Login failed.\r\n" );
echo "PASV (Y/Any key = Off): " ;
if( trim ( fgets ( STDIN )) == "Y" )
//enable passive mode
ftp_pasv ( $connect , true );
echo "PASV: Off\r\n" ;
$showContent = ftp_nlist ( $connect , "" );
echo "Listing Contents:\r\n" ;
echo "File to upload: " ;
$file = trim ( fgets ( STDIN ));
//escape the uploading process by typing "exit;"
if ( $file == "exit;" )
//use "$file, $file" since the file shouldn't be renamed, also if its a binary file change the last argument to FTP_BINARY
$upload = ftp_put ( $connect , $file , $file , FTP_ASCII );
exit( "Upload failed.\r\n" );
echo "The file \"" . $file . "\" was successfully uploaded. :)\r\nSize of \"" . $file . "\": " . filesize ( $file ) / 1024 . "kb.\r\n" ;
echo "My work is done, bye.\r\n" ;
A function to get a remote file and return it's contents, instead of saving to a local file, was missing - here it is:
function ftp_fetch($ftp_stream, $remote_file) ob_end_flush();
ob_start();
$out = fopen('php://output', 'w');
if (!ftp_fget($ftp_stream, $out, $remote_file, FTP_ASCII)) die('Unable to get file: ' . $remote_file);
fclose($out);
$data = ob_get_clean();
return $data;
>
It works the same as ftp_get(), but instead returns the contents of the remote file - for example:
Note, I use it to fetch text-files from a server - if you need to fetch binary files, change FTP_ASCII to FTP_BINARY .. but most likely, getting files to memory is only useful for smaller files, e.g. plain text, xml, etc.
After looking everywhere for a "FULLY WORKING" ftp uploader script, I finally came up with this, by using a lot of various one’s I found on the web. If you find a better way of doing something, please let me know. Thanks, and Enjoy
if(isset( $_POST [ 'SubmitFile' ])) $myFile = $_FILES [ 'txt_file' ]; // This will make an array out of the file information that was stored.
$file = $myFile [ 'tmp_name' ]; //Converts the array into a new string containing the path name on the server where your file is.
$myFileName = basename ( $_POST [ 'txt_fileName' ]); //Retrieve filename out of file path
$destination_file = "/" . $myFileName ; //where you want to throw the file on the webserver (relative to your login dir)
// connection settings
$ftp_server = "127.0.0.1" ; //address of ftp server.
$ftp_user_name = "Your UserName" ; // Username
$ftp_user_pass = "Your Password" ; // Password
$conn_id = ftp_connect ( $ftp_server ); // set up basic connection
$login_result = ftp_login ( $conn_id , $ftp_user_name , $ftp_user_pass ) or die( "
FTP upload of $myFileName has failed!
" ;
> else echo "Uploading $myFileName Complete!
" ;
>
ftp_close ( $conn_id ); // close the FTP stream
>
?>
This took me a few hours to work out. It is based on the code below I've just added a string replace to convert pathname given by Windows to Unix pathname. Hope it saves somebody some time. Enjoy! (Also, delete file function is included:))
Here is an example for downloading a remote ftp structure to local server, useful for migrating sites from one server to another, especially when you are upgrading ensim ;)
ftp_put() загружает локальный файл на FTP-сервер.
Список изменений
Версия | Описание |
---|---|
8.1.0 | Параметр ftp теперь ожидает экземпляр FTP\Connection ; ранее ожидался ресурс (resource). |
7.3.0 | Теперь параметр mode опционален. Раньше он был обязательным. |
Комментарии 2
Удалить файлы из директории, кроме некоторых
Например, нужно удалить все файлы, кроме файла .htaccess:
Смотрите также
- ftp_pasv() - Включает или выключает пассивный режим
- ftp_fput() - Загружает предварительно открытый файл на FTP-сервер
- ftp_nb_fput() - Загружает предварительно открытый файл на FTP-сервер в асинхронном режиме
- ftp_nb_put() - Загружает файл на FTP-сервер в асинхронном режиме
Сохранение в файл
Функция file_put_contents() записывает содержимое переменной в файл, если файла не существует. то пытается его создать, если существует то полностью перезапишет его.
File_put_contents:
Fopen / fwrite:
Набор функций fopen, fwrite, fclose предназначены для более гибкой работы с файлами.
- fopen – открытие или создание файла.
- fwrite – запись данных.
- fclose – закрытие файла.
Возможные режимы fopen():
Mode | Описание |
---|---|
r | Открывает файл только для чтения, помещает указатель в начало файла. |
r+ | Открывает файл для чтения и записи, помещает указатель в начало файла. |
w | Открывает файл только для записи, помещает указатель в начало файла и обрезает файл до нулевой длины. Если файл не существует – пробует его создать. |
w+ | Открывает файл для чтения и записи, помещает указатель в начало файла и обрезает файл до нулевой длины. Если файл не существует – пытается его создать. |
a | Открывает файл только для записи, помещает указатель в конец файла. Если файл не существует – пытается его создать. |
a+ | Открывает файл для чтения и записи, помещает указатель в конец файла. Если файл не существует – пытается его создать. |
x | Создаёт и открывает только для записи; помещает указатель в начало файла. Если файл уже существует, вызов fopen() закончится неудачей, вернёт false и выдаст ошибку. Если файл не существует, попытается его создать. |
x+ | Создаёт и открывает для чтения и записи, в остальном имеет то же поведение, что и « x ». |
c | Открывает файл только для записи. Если файл не существует, то он создаётся. Если же файл существует, то он не обрезается (в отличие от « w »), и вызов к этой функции не вызывает ошибку (также как и в случае с « x »). Указатель на файл будет установлен на начало файла. |
c+ | Открывает файл для чтения и записи, в остальном имеет то же поведение, что и « c ». |
Доступно в место fwrite() используют fputs() , разницы ни какой т.к. эта функция является псевдонимом.
I didn't quite like my FTP program since I had to make all the settings all over when i restarted the client, so I made this script for simple ftp uploading, its running as a CLI app.
//if STDIN isn't defined, define it
if (! defined ( "STDIN" ))
define ( "STDIN" , fopen ( "php://stdin" , "r" ));
echo "FTP file uploader\r\n\r\n" ;
//trim() all the fgets cause it seams to add a \n
$server = trim ( fgets ( STDIN ));
$username = trim ( fgets ( STDIN ));
$password = trim ( fgets ( STDIN ));
$connect = ftp_connect ( $server );
$login = ftp_login ( $connect , $username , $password );
if ((! $connect ) || (! $login ))
exit( "Login failed.\r\n" );
echo "PASV (Y/Any key = Off): " ;
if( trim ( fgets ( STDIN )) == "Y" )
//enable passive mode
ftp_pasv ( $connect , true );
echo "PASV: Off\r\n" ;
$showContent = ftp_nlist ( $connect , "" );
echo "Listing Contents:\r\n" ;
echo "File to upload: " ;
$file = trim ( fgets ( STDIN ));
//escape the uploading process by typing "exit;"
if ( $file == "exit;" )
//use "$file, $file" since the file shouldn't be renamed, also if its a binary file change the last argument to FTP_BINARY
$upload = ftp_put ( $connect , $file , $file , FTP_ASCII );
exit( "Upload failed.\r\n" );
echo "The file \"" . $file . "\" was successfully uploaded. :)\r\nSize of \"" . $file . "\": " . filesize ( $file ) / 1024 . "kb.\r\n" ;
echo "My work is done, bye.\r\n" ;
A function to get a remote file and return it's contents, instead of saving to a local file, was missing - here it is:
function ftp_fetch($ftp_stream, $remote_file) ob_end_flush();
ob_start();
$out = fopen('php://output', 'w');
if (!ftp_fget($ftp_stream, $out, $remote_file, FTP_ASCII)) die('Unable to get file: ' . $remote_file);
fclose($out);
$data = ob_get_clean();
return $data;
>
It works the same as ftp_get(), but instead returns the contents of the remote file - for example:
Note, I use it to fetch text-files from a server - if you need to fetch binary files, change FTP_ASCII to FTP_BINARY .. but most likely, getting files to memory is only useful for smaller files, e.g. plain text, xml, etc.
After looking everywhere for a "FULLY WORKING" ftp uploader script, I finally came up with this, by using a lot of various one’s I found on the web. If you find a better way of doing something, please let me know. Thanks, and Enjoy
if(isset( $_POST [ 'SubmitFile' ])) $myFile = $_FILES [ 'txt_file' ]; // This will make an array out of the file information that was stored.
$file = $myFile [ 'tmp_name' ]; //Converts the array into a new string containing the path name on the server where your file is.
$myFileName = basename ( $_POST [ 'txt_fileName' ]); //Retrieve filename out of file path
$destination_file = "/" . $myFileName ; //where you want to throw the file on the webserver (relative to your login dir)
// connection settings
$ftp_server = "127.0.0.1" ; //address of ftp server.
$ftp_user_name = "Your UserName" ; // Username
$ftp_user_pass = "Your Password" ; // Password
$conn_id = ftp_connect ( $ftp_server ); // set up basic connection
$login_result = ftp_login ( $conn_id , $ftp_user_name , $ftp_user_pass ) or die( "
Удалить только содержимое директории
You do not have access to this ftp server!
" ); // login with username and password, or give invalid user messageif ((! $conn_id ) || (! $login_result )) < // check connection
// wont ever hit this, b/c of the die call on ftp_login
echo "FTP connection has failed!
" ;
echo "Attempted to connect to $ftp_server for user $ftp_user_name " ;
exit;
> else // echo "Connected to $ftp_server, for user $ftp_user_name
";
>
$upload = ftp_put ( $conn_id , $destination_file , $file , FTP_BINARY ); // upload the file
if (! $upload ) < // check upload status
echo "
Копирование директории с ее содержимым
Получить список файлов директории в виде массива
То же самое делает функция scandir() , разница в том что у нее в массиве будут « . », « .. » и есть возможность сортировки.
Результат:
Удалить директорию со всем содержимым
Удаление директории
Функция rmdir($dir) — удаляет заданную директорию только при условии, если она пуста.
Примеры
$file = 'somefile.txt' ;
$remote_file = 'readme.txt' ;
// установка соединения
$ftp = ftp_connect ( $ftp_server );
// проверка имени пользователя и пароля
$login_result = ftp_login ( $ftp , $ftp_user_name , $ftp_user_pass );
// загрузка файла
if ( ftp_put ( $ftp , $remote_file , $file , FTP_ASCII )) echo " $file успешно загружен на сервер\n" ;
> else echo "Не удалось загрузить $file на сервер\n" ;
>
// закрытие соединения
ftp_close ( $ftp );
?>
Возвращаемые значения
Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.
User Contributed Notes 33 notes
If when using ftp_put you get the one of the following errors:
Warning: ftp_put() [function.ftp-put]: Opening ASCII mode data connection
Warning: ftp_put() [function.ftp-put]: Opening BINARY mode data connection
and it creates the file in the correct location but is a 0kb file and all FTP commands thereafter fail. It is likely that the client is behind a firewall. To rectify this use:
ftp_pasv ( $resource , true );
?>
Before executing any put commands. Took me so long to figure this out I actually cheered when I did :D
if you examine the first user submitted function, ftp_putAll, it will work only if you extract this line and its matching bracket.
if (!@ftp_chdir($conn_id, $dst_dir."/".$file))
The function will have changed into that directory before having uploaded files to it. This alters your upload path and the system will try to upload into an essentially non-existent directory (duped at the end).
Hope this helps some of you.
Cheers.
Saeven
If you want to copy a whole directory tree (with subdiretories),
this function (ftp_copy) might be usefull. Tested with
php 4.2.2 and a Linux OS.
$src_dir = "/from";
$dst_dir = "/to";
ftp_copy($src_dir, $dst_dir);
.
ftp_close($conn_id)
if (!@ftp_chdir($conn_id, $dst_dir."/".$file))
ftp_copy($src_dir."/".$file, $dst_dir."/".$file);
>
else
$upload = ftp_put($conn_id, $dst_dir."/".$file, $src_dir."/".$file, FTP_BINARY);
>
>
>
If you are having timeouts uploading a file, even very small files, you might have a look at ftp_pasv()
And don't forget to do it after your ftp_login();
Here is the Code I am using for the same function with more flexibility in static code:
$name = "FILE NAME";
$filename = "FILE NAME WITH FULL PATH";
//-- Code to Transfer File on Server Dt: 06-03-2008 by Aditya Bhatt --//
//-- Connection Settings
$ftp_server = "IP ADDRESS"; // Address of FTP server.
$ftp_user_name = " SERVER USERNAME"; // Username
$ftp_user_pass = " SERVER PASSWORD"; // Password
$destination_file = " SERVER FILE PATH TO UPLOAD VIA FTP_PUT"; //where you want to throw the file on the webserver (relative to your login dir)
NOTE: use full path name for the destination directory and the destination directory must already exist
If you get this error when trying to send data to server :
Warning: ftp_put() [function.ftp-put]: Unable to build data connection: Connection timed out.
Got this cryptic error
Warning: ftp_put() [function.ftp-put]: 'STOR' not understood in
C:\wamp\www\kevtest\ftp_todays.php on line 48
Found the prob, you can't put a path to the destination file
(even though I can do that in the dos ftp client. )
e.g. - this doesn't work
ftp_put($conn, '/www/site/file.html','c:/wamp/www/site/file.html',FTP_BINARY);
you have to put
ftp_chdir ( $conn , '/www/site/' );
ftp_put ( $conn , 'file.html' , 'c:/wamp/www/site/file.html' , FTP_BINARY );
?>
I [had an error for which] ftp_pasv didnt solve the problem. Here's why:
FTP uses 2 connections on different ports, one for connection/handshake and another for data transfer.
The problem was that the ftp-server (that php was connecting to) also used different IP-addresses for the different connections (say what!?).
Normally the firewall (csf) detects ftp-connections and allows them through but because of the different IP-adresses this didn't work.
Solution:
1 angry mail to the ftp server owner.
Allowing the second IP in the firewall.
ftp_put() can display confusing warning messages as it returns one line of the remote server's response which may be multi lined.
If you're transferring large amounts of files note that some file systems only support up to 2000 files per directory. This had me stumped for a while.
Currently, there is no function that lets you specifiy the file's contents as a string. However, there is ftp_fput(), which operates on an open file. Using this function in conjunction with tmpfile() lets you emulate this kind of function. (You could also use php://memory, but this breaks BC).
function ftp_fputs ( $ftp_stream , $remote_file , $contents , $mode , $startpos = 0 )
$tmp = tmpfile ();
fwrite ( $tmp , $contents );
rewind ( $tmp );
$result = ftp_fput ( $ftp_stream , $remote_file , $tmp , $mode , $startpos );
fclose ( $tmp );
return $result ;
>
?>
Here is a fix for the function from lucas at rufy dot com below that will recursively put files from a source directory to a destination directory. As written below, it won't put a file in a directory that already exists, because the the destination is altered. So here is the corrected function that will allow it to work:
I'm copying fairly large backup files from server to server. ftp_put was running fine for awhile until it occasionally began reporting errors.
When I set TRUE as the value for the ftp_pasv () (after login), ftp_put started working again.
I spent some time debugging a silly problem:
In php >= 5, ftp_put() will apparently rewind to the start of the file regardless of the state you left it in before sending it to the $host.
I found this out because I wasn't closing the file handle before using ftp_put(). Since I had just written to the file, the file pointer must have been located at the *bottom*.
I was sending a 0-byte file on php 4.2.2., but worked fine on php 5.
So, just a heads up, don't forget to close those filehandles. Even though I was using the filename as the argument for ftp_put, it still needs to be closed.
I did not call rewind on the file handle, just fclose($file_h).
victor at nobel dot com dot br wrote that
the correct dirpath format excluded "/home/USER/" from the public path, but for my server, i had to use it in order to get my scripts to work.
it may be obvious to most but I'm positing that you cannot use the $_SERVER['DOCUMENT_ROOT'] path since FTP starts at your top-level and therefore bypasses (or just plain doesn't recognize) most of the virtual server pathing.
I had a little trouble getting the ftp_put to work, because of that particular server. All variables and data parsed from the previous web form had to be retreived using $_POST, $_GET or $_FILES.
If you don't know what you sent use phpinfo(); to display what the server thinks about your data.
so. when sending files using a form and PHP, make sure that all the data (text files etc. ) are retreived with $_POST, and files (smiley.jpg, compression.zip, etc. ) are retreived with $_FILES.
here's what your start of a results.php file might look like:
$myName = $_POST [ 'name' ]; //This will copy the text into a variable
$myFile = $_FILES [ 'file_name' ]; // This will make an array out of the file information that was stored.
?>
Now when it comes to transmitting that information.
//where you want to throw the file on the webserver (relative to your login dir)
$destination_file = $destination_path . "img.jpg" ;
//This will create a full path with the file on the end for you to use, I like splitting the variables like this in case I need to use on on their own or if I'm dynamically creating new folders.
$file = $myFile [ 'tmp_name' ];
//Converts the array into a new string containing the path name on the server where your file is.
$upload = ftp_put ( $conn_id , $destination_file , $file , FTP_BINARY ); // upload the file
if (! $upload ) < // check upload status
echo "FTP upload of $destination_file has failed!" ;
> else echo "Uploaded $file to $conn_id as $destination_file " ;
>
?>
hope this is usefull ^_^
This is an extremely trivial thing but one that had me stumped forever (well, until I decided to check the error logs and see the error). I had a large file (mysql backup of a huge forum) that was only partially being uploaded to a remote backup server. Couldn't figure out why, until I realized that the max execution time was being hit since it was taking longer than 30 seconds to upload this file.
set_time_limit ( 0 );
rest of the code here .
?>
That did the trick. It's one of those dumb, trivial things, and if you're having trouble like I, it may be something you overlooked.
In case you aren't aware. Some web hosting services do NOT allow outbound ftp unless you have a dedicated server account. A "shared" hosting account often doesn't have this capability.
So if you can't get your ftp, curl, or ssh remote file transfer functions to work, check with the host service and ask. You may have to upgrade your account.
If you are moving files from one folder to another inside the same server, the "local file" field has to be indicated in a relative path according to the location of the script running the ftp_put() function.
For example, your function is running on: /public_html/do_ftp.php and you want to move /public_html/products.php to /public_html/backup/products.php
The correct way to build the function would be:
ftp_put($ftp_id, '/public_html/backup/products.php', 'products.php', FTP_ASCII);
After having headaches for 2 days trying to make this function work using absolute paths in both fields, I finally found the right way to use it. I hope it helps someone. Excuse my english, it isn't my native language.
I've seen two notes about a "ftp_copy" function but i think there's a misinterpretation about what an "ftp_copy" function should do. For me , it should be something like an ftp_rename that would keep the orginal file and clone it somewhere else on the same ftp server, as for them they consider its purpose is to copy a local file to a distant ftp ..well .. as in FTP protocol there's no such thing as an FTP COPY command anyway, i think you're free to interpret it as you want.
So here's my solution using ftp_put and ftp_get ..
// bool ftp_copy ( resource $ftp_stream , string $initialpath, string $newpath, string $imagename )
function ftp_copy ( $conn_distant , $pathftp , $pathftpimg , $img ) <
// on recupere l'image puis on la repose dans le nouveau folder
if( ftp_get ( $conn_distant , TEMPFOLDER . $img , $pathftp . '/' . $img , FTP_BINARY )) <
if( ftp_put ( $conn_distant , $pathftpimg . '/' . $img , TEMPFOLDER . $img , FTP_BINARY )) <
unlink ( TEMPFOLDER . $img ) ;
> else <
return false ;
>
Yet another recursive ftp_put.
* The parameters are similar to that of ftp_put, so if you need to copy a directory, just use ftp_put_dir(. ) instead of ftp_put(. ).
* Another advantage is that the remote directory doesn't need to exist.
* Returns TRUE on success, FALSE on failure.
* Inspired by lucas at rufy dot com and webmaster at sweetphp dot com.
function ftp_put_dir ( $ftp , $remote_dirname , $local_dirname , $mode = FTP_BINARY ) $success = true ;
// If necessary, create the remote directory.
if (! ftp_nlist ( $ftp , $remote_dirname )) if ( ftp_mkdir ( $ftp , $remote_dirname ) === false ) $success = false ;
>
>
$dir = dir ( $local_dirname );
while ( $f = $dir -> read ()) if ( $f === '.' || $f === '..' ) continue;
>
$lf = $local_dirname . '/' . $f ;
$rf = $remote_dirname . '/' . $f ;
if ( is_dir ( $lf )) if (! ftp_put_dir ( $ftp , $rf , $lf , $mode )) $success = false ;
>
> else if (! ftp_put ( $ftp , $rf , $lf , $mode )) $success = false ;
>
>
>
$dir -> close ();
Набор PHP функций для работы с директориями, получение списка файлов в папке, копирование и удаление содержимого папок.
Другие публикации
Примеры как сделать select для выбора загруженных файлов. Из PHP-функций для работы с файловой системой – opendir().
Для поиска файлов на сервере хорошо подходит функция glob(), которая возвращает список файлов по заданной маске, например.
Такой вопрос возникает когда у сайта есть копия, например региональный сайт или сайт на другом языке, но при этом база.
Протокол FTP – предназначен для передачи файлов на удаленный хост. В PHP функции для работы с FTP как правило всегда доступны и не требуется установка дополнительного расширения.
Список параметров
Путь к файлу на FTP-сервере.
Путь к локальному файлу.
Задаёт режим передачи. Может принимать значения FTP_ASCII или FTP_BINARY .
Задаёт позицию в удалённом файле, в которую начнётся загрузка
Создать директорию
Читайте также: