ここでは、詳細は不明ですが、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);
}
}
開発アルアル
- 暫定対処は本対処
- 動いてればみんなそのうち忘れる
- 忘れた頃に障害発生
- 言い訳必死に考える