2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

PHPとCurlを使ってSFTPでファイルアップロードと削除をする

Posted at

何がしたかったか

ユーザーからmultipart/form-dataでPOSTされてきたファイルをSFTPでストレージサーバに送る
ファイルのバリデーションは実装してるけど今回はSFTPする部分について。

実現方法

  • 使っているフレームワークに頼る
  • ssh2のライブラリを使う
  • curlを使う
  • systemやexecでコマンドを叩く

フレームワークを利用しているならフレームワークのライブラリを使うのが多分1番簡単です。
composerなどが使える環境ならさくっとライブラリを入れてしまうのも手だと思います。
systemやexecでコマンドを叩くのはエラーハンドリングも面倒だし、コマンドを直接発行するという怖さがあるのでオススメしません。
今回は僕が実装した環境がこれらの手段が使えなかったため、curlで実装してみたという話です。

実装

記事用なのでコメント多め。

アップロード

<?php
$curl = curl_init();
//プロトコルをSFTPに設定
curl_setopt($curl, CURLOPT_PROTOCOLS, CURLPROTO_SFTP);

// 認証方法の設定
curl_setopt($curl, CURLOPT_SSH_AUTH_TYPES, CURLSSH_AUTH_PUBLICKEY);        

// ポートを指定する
curl_setopt($curl, CURLOPT_PORT, **);

// 実行ユーザーの公開鍵と秘密鍵のパスを指定する
curl_setopt($curl, CURLOPT_SSH_PUBLIC_KEYFILE, 'pub_key_path');
curl_setopt($curl, CURLOPT_SSH_PRIVATE_KEYFILE, 'pri_key_path');

// アップロードを指定
curl_setopt($curl, CURLOPT_UPLOAD, 1);

// URL設定
// パスワードを指定する場合は user:pass@~の形式にする
$url = "sftp://user@server/~/UploadPath";
curl_setopt($curl, CURLOPT_URL, $url);

// 送信するファイルをオープンして設定する
$fp = fopen($file, 'rb');
curl_setopt($curl, CURLOPT_INFILE, $fp);
curl_setopt($curl, CURLOPT_INFILESIZE, filesize($file));

//実行
$res = curl_exec($curl);

//エラーハンドリング
if(curl_errno($curl) !== 0) {
    fclose($fp);
    curl_close($curl);
    //例外を投げるなりよしなにする
    echo 'failed.';
    exit;
}
//終わったら後処理
fclose($fp);
curl_close($curl);
echo 'success';
exit;

ファイルの削除

<?php
$curl = curl_init();
// アップロードと同じ設定
curl_setopt($curl, CURLOPT_PROTOCOLS, CURLPROTO_SFTP);
curl_setopt($curl, CURLOPT_SSH_AUTH_TYPES, CURLSSH_AUTH_PUBLICKEY);        
curl_setopt($curl, CURLOPT_PORT, **);
curl_setopt($curl, CURLOPT_SSH_PUBLIC_KEYFILE, 'pub_key_path');
curl_setopt($curl, CURLOPT_SSH_PRIVATE_KEYFILE, 'pri_key_path');

// URL設定 削除のときは対象のファイルパスは不要
$url = "sftp://user@server";
curl_setopt($curl, CURLOPT_URL, $url);

// 削除コマンドを発行するように設定する
curl_setopt($curl, CURLOPT_QUOTE, array('rm deleteFilePath'));

//実行
$res = curl_exec($curl);

//エラーハンドリング
if(curl_errno($curl) !== 0) {
    curl_close($curl);
    //例外を投げるなりよしなにする
    echo 'failed.';
    exit;
}
//終わったら後処理
curl_close($curl);
echo 'success';
exit;

詰まった個所

curl_setopt($curl, CURLOPT_SSH_AUTH_TYPES, CURLSSH_AUTH_PUBLICKEY);     

これがPHP5.2環境だとWarningを吐いて設定されなかった。
公式ドキュメントを見たがPHPのバージョン依存はなく、使っているcurlのバージョンにも問題なかったので結局理由が解らなかった。
今時PHP5.2なんて環境を使うのが悪い。

所感

やっぱフレームワーク無いとこういうのを自前で実装しないといけなくなって面倒なので、フレームワーク使いましょう。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?