PHPでPASV(passiveモード)なFTP
しようと思ったらあれもだめこれもだめと言われたので
cURL、君に決めた!
ftp関数が使えない
マニュアルのサンプルどおり書いて終了、と思ったら・・・
Fatal error: Call to undefined function ftp_connect()
マニュアル:
PHP で FTP 関数を使用するには、PHP をインストールする際に --enable-ftp オプションを追加する必要があります。
うへっ。
じゃぁftpラッパ使うわ → アウツ
マニュアル:
ただ単にFTPサーバ上のファイルを読み書きしたいだけなら、ファイルシステム関数でftp://ラッパを用いることを考えてください。
こちらのほうがシンプルで直感的なインターフェースを提供します。
シンプルで直感的、ナイス。
がしかし、こちらもうまくいかない。
Warning: fopen(): connect() failed: Connection timed out Warning: fopen(ftp://...@hoge.example.com/dir/file.jpg): failed to open stream: FTP server reports STOR
サーバーのほうに0byteのファイルだけはできるがその後しばらく固まって↑のエラーになる。
php.netだとNAT関連とか言っている人がいたけど原因不明。
http://jp.php.net/manual/ja/function.fopen.php#39448
fsock_open → めんどい ><
結局やめたけど↓がとても参考になった
http://engineer.ns-it.net/php_47.php
http://engineer.ns-it.net/php_49.php
cURL、君に決めた!
$remote_file = 'ftp://user:passwd@hoge.example.com/dir/file.jpg'; $local_file = 'file.jpg'; $fp = fopen($local_file); $ch = curl_init(); curl_setopt($ch, CURLOPT_FTP_USE_EPSV, false); curl_setopt($ch, CURLOPT_UPLOAD, true); curl_setopt($ch, CURLOPT_URL, $remote_file); curl_setopt($ch, CURLOPT_INFILE, $fp); curl_setopt($ch, CURLOPT_INFILESIZE, filesize($local_file)); curl_exec($ch); curl_close($ch);
↓のオプションがミソで、
curl_setopt($ch, CURLOPT_FTP_USE_EPSV, false);
TRUE を設定すると、FTP 転送の際にまずEPSVコマンドの利用を試みます。
失敗した場合はPASVを利用します。FALSE を設定すると、EPSV を無効にします。
これがデフォルトでtrueらしく、そのままだとactiveモードで接続しようとしているのか、かなり長い時間待たされる。