ここでは、詳細は不明ですが、FTP 接続時にエラーが発生することがありましたので、備忘録がわりに掲載しています。
スポンサーリンク
常に FTP 接続エラーとなるわけではない
常に FTP 接続時にエラーとなるわけではないのですが、以下のエラーが発生することがありました。
エラー内容
Warning: ftp_get(): php_connect_nonb() failed: Operation now in progress (150)
エラー発生時の環境
OS | Solaris10 |
---|---|
PHP | 5.3.6 |
FTPモード | パッシブ |
Solaris10 においては errno = 150 ( EINPROGRESS ) です。完了までに長時間を要する操作 ( connect など ) を、非ブロックオブジェクト上で試みた場合に発生するエラーとのことです。
暫定対処
原因は不明です。わかっていません。ただ、PHP のソースコードを確認したところ本警告が発生するのはパッシブモードの場合のみであることがわかりました。FTP 接続をアクティブモードに変更すると問題なく FTP によるファイル転送が行われることが確認できました。
今回はパッシブ・アクティブのどちらのモードでも問題ない環境でしたので、この暫定的な対応でとりあえず回避することにしました。
FTP 接続モードの設定 ( パッシブ or アクティブ )
接続モードの設定を行うサンプルスクリプトになります。詳細はコメントを参照ください。
class Ftp { /* * FTP 接続情報 */ protected $_config; /* * FTP コネクションリソース */ protected $_conn = null; /* * コンストラクタ * @param array $config * * FTP 接続情報 * array() { * ["hostname"] => "127.0.0.1" * ["port"] => "21" * ["timeout"] => "90" * ["user"] => "user" * ["passwd"] => "passwd" * } */ public function __construct($config) { $this->_config = $config; } /* * FTP サーバーに接続し、ログインする * * @return bool true:成功 false:失敗 */ public function open($pasv = true) { // FTP サーバに接続 $this->_conn = ftp_connect($this->_config['hostname'], $this->_config['port'], $this->_config['timeout']); if($this->_conn === false) { return false; } // FTP サーバにログイン if (!@ftp_login($this->_conn, $this->_config['user'], $this->_config['passwd'])) { return false; } // パッシブモードのオン・オフを切り替える ftp_pasv($this->_conn, $pasv); return true; } /* * FTPサーバーから切断する */ public function close() { if(empty($this->_conn)) { return; } @ftp_close($this->_conn); } }
開発アルアル
- 暫定対処は本対処
- 動いてればみんなそのうち忘れる
- 忘れた頃に障害発生
- 言い訳必死に考える