PHPのお勉強!

PHP TOP

ftp_put

(PHP 4, PHP 5, PHP 7, PHP 8)

ftp_putFTP サーバーにファイルをアップロードする

説明

ftp_put(
    FTP\Connection $ftp,
    string $remote_filename,
    string $local_filename,
    int $mode = FTP_BINARY,
    int $offset = 0
): bool

ftp_put() ローカルファイルを FTP サーバーに保存します。

パラメータ

ftp

FTP\Connection クラスのインスタンス

remote_filename

リモートファイルのパス。

local_filename

ローカルファイルのパス。

mode

転送モード。FTP_ASCII または FTP_BINARY のどちらかを指定する必要があります。

offset

リモートファイル内での、アップロード開始位置。

戻り値

成功した場合に true を、失敗した場合に false を返します。

変更履歴

バージョン 説明
8.1.0 引数 ftp は、FTP\Connection のインスタンスを期待するようになりました。 これより前のバージョンでは、リソース を期待していました。
7.3.0 mode パラメータはオプションになりました。 これより前のバージョンでは、このパラメータは必須でした。

例1 ftp_put() の例

<?php
$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
"successfully uploaded $file\n";
} else {
echo
"There was a problem while uploading $file\n";
}

// 接続を閉じる
ftp_close($ftp);
?>

参考

  • ftp_pasv() - パッシブモードをオンまたはオフにする
  • ftp_fput() - オープン中のファイルを FTP サーバーにアップロードする
  • ftp_nb_fput() - オープン中のファイルを FTP サーバーに保存する(非ブロッキング)
  • ftp_nb_put() - FTP サーバーにファイルを保存する(非ブロッキング)

add a note

User Contributed Notes 33 notes

up
132
darian lassan at yahoo de
21 years ago
ftp_put() overwrites existing files.
Again: trivial but not mentioned here.
up
57
Anonymous
15 years ago
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:

<?php
ftp_pasv
($resource, true);
?>

Before executing any put commands. Took me so long to figure this out I actually cheered when I did :D
up
12
koen dot depoorter at gmail dot com
17 years ago
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();

koen
up
5
todd
17 years ago
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.

<?php
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.
up
7
oheil at ecc-gmbh dot de
22 years ago
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.

Example:
----------------------------------------------------------------
$conn_id = ftp_connect("server_adress");
...

$src_dir = "/from";
$dst_dir = "/to";

ftp_copy($src_dir, $dst_dir);
...
ftp_close($conn_id)

Function: ftp_copy()
----------------------------------------------------------------
function ftp_copy($src_dir, $dst_dir) {

global $conn_id;

$d = dir($src_dir);

while($file = $d->read()) {

if ($file != "." && $file != "..") {

if (is_dir($src_dir."/".$file)) {

if (!@ftp_chdir($conn_id, $dst_dir."/".$file)) {

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

$d->close();
}
up
1
jan at odvarko dot cz
3 years ago
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.

<?php

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

return
$success;
}

?>
up
8
lucas at rufy dot com
21 years ago
The following is a fully tested function (based on a previous note) that recursively puts files from a source directory to a destination directory. See http://rufy.com/tech/archives/000026.html for more information.

NOTE: use full path name for the destination directory and the destination directory must already exist

function ftp_putAll($conn_id, $src_dir, $dst_dir) {
$d = dir($src_dir);
while($file = $d->read()) { // do this for each file in the directory
if ($file != "." && $file != "..") { // to prevent an infinite loop
if (is_dir($src_dir."/".$file)) { // do the following if it is a directory
if (!@ftp_chdir($conn_id, $dst_dir."/".$file)) {
ftp_mkdir($conn_id, $dst_dir."/".$file); // create directories that do not yet exist
}
ftp_putAll($conn_id, $src_dir."/".$file, $dst_dir."/".$file); // recursive part
} else {
$upload = ftp_put($conn_id, $dst_dir."/".$file, $src_dir."/".$file, FTP_BINARY); // put the files
}
}
}
$d->close();
}
up
3
Saeven
21 years ago
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
up
2
herok at atwatcher dot com
20 years ago
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.
up
1
tom pittlik
19 years ago
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.
up
5
Aditya P Bhatt (adityabhai at gmail dot com)
16 years ago
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)

$conn_id = ftp_connect($ftp_server) or die("<span style='color:#FF0000'><h2>Couldn't connect to $ftp_server</h2></span>"); // set up basic connection

$login_result = ftp_login($conn_id, $ftp_user_name, $ftp_user_pass) or die("<span style='color:#FF0000'><h2>You do not have access to this ftp server!</h2></span>"); // login with username and password, or give invalid user message

if ((!$conn_id) || (!$login_result)) { // check connection
// wont ever hit this, b/c of the die call on ftp_login
echo "<span style='color:#FF0000'><h2>FTP connection has failed! <br />";
echo "Attempted to connect to $ftp_server for user $ftp_user_name</h2></span>";
exit;
} else {
//echo "Connected to $ftp_server, for user $ftp_user_name <br />";
}

$upload = ftp_put($conn_id, $destination_file.$name, $filename, FTP_BINARY); // upload the file
if (!$upload) { // check upload status
echo "<span style='color:#FF0000'><h2>FTP upload of $filename has failed!</h2></span> <br />";
} else {
echo "<span style='color:#339900'><h2>Uploading $name Completed Successfully!</h2></span><br /><br />";
}
ftp_close($conn_id); // close the FTP stream
?>
up
9
Kev
15 years ago
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

<?php
ftp_chdir
($conn, '/www/site/');
ftp_put($conn,'file.html', 'c:/wamp/www/site/file.html', FTP_BINARY );
?>
up
2
florian dot ember at gmail dot com
16 years ago
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).

<?php
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;
}
?>
up
2
Svinto
14 years ago
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.
up
1
Ari
17 years ago
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.
up
2
webmaster at sweetphp dot com
19 years ago
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:

function ftp_putAll($conn_id, $src_dir, $dst_dir) {
$d = dir($src_dir);
while($file = $d->read()) { // do this for each file in the directory
if ($file != "." && $file != "..") { // to prevent an infinite loop
if (is_dir($src_dir."/".$file)) { // do the following if it is a directory
if (!@ftp_nlist($conn_id, $dst_dir."/".$file)) {
ftp_mkdir($conn_id, $dst_dir."/".$file); // create directories that do not yet exist
}
ftp_putAll($conn_id, $src_dir."/".$file, $dst_dir."/".$file); // recursive part
} else {
$upload = ftp_put($conn_id, $dst_dir."/".$file, $src_dir."/".$file, FTP_BINARY); // put the files
}
}
}
$d->close();
}
up
1
ben at over dot bomb
19 years ago
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).
up