PHP:ssh2_disconnect()でSegmentation Fault

こんにちは、さるまりんです。

PHPプログラムでSFTPを使ってファイルを取得するプログラムを書いていて起こったことで勉強になったのでメモしておきます。

以下、SFTPでディレクトリ配下のファイルをダウンロードするプログラムです。

$remote_dir = "/download/";
$local_dir = "/tmp/"

$conn = ssh2_connect($host, $port);
ssh2_auth_password($conn, $id, $pw);

$sftp = ssh2_sftp($conn);
$sftp_fd = intval($sftp);

$rmt_dir = "ssh2.sftp://$sftp_fd/$remote_dir";
$handle = opendir($rmt_dir);


// ディレクトリ内のファイルを全てダウンロード
while (($entry = readdir($handle)) != false) {
    // 現在 + 親のディレクトリをスキップ
    if ($entry == '.' || $entry == '..') continue;

    $remote = $remote_dir . $entry;
    $local = $local_dir . $entry;

    // ダウンロード
    $remote_path = "ssh2.sftp://$sftp_fd/$remote";
    $contents = file_get_contents($remote_path);
    file_put_contents($local, $contents);
}

// ハンドルを閉じる
closedir($handle);
$handle = null;
unset($handle);

// 接続を閉じる
ssh2_disconnect($conn);
$conn = null;
unset($conn);

リモートの”/download/“にあるファイルローカルの”/tmp/“にをダウンロードしてきます。

期待通りにちゃんと目的のファイルをダウンロードすることができました。

が、実行最後に

Segmentation fault

と出ています。

なにかおかしい。。。

色々探っていくとちょっとだけ足りない部分がありました。

ssh接続$connを閉じる前に$sftpを閉じないと、これが発生するそうです。

なので、

// SFTPを閉じる
ssh2_disconnect($sftp);
$sftp = null;
unset($sftp);

↑これが要ります。

最後の部分はこうなります。

// ハンドルを閉じる
closedir($handle);
$handle = null;
unset($handle);

// SFTPを閉じる
ssh2_disconnect($sftp);
$sftp = null;
unset($sftp);

// 接続を閉じる
ssh2_disconnect($conn);
$conn = null;
unset($conn);

ディレクトリハンドルを閉じて、SFTPを閉じて、ssh接続を閉じる。

順序通り忘れずに。

ちゃんと動作しているのだけど、Segmentation Faultなんて気持ち悪いですよね。

エラーが出るのはなにか理由がある。

わかってスッキリです。

読んでくださってありがとうございます。

それではまた!