LaravelでSFTPの設定を導入して、本番環境やDEV環境でSFTP通信するまでの手順について

#はじめに
CSVファイルをSFTPサーバへ連携する案件があったのでその時の導入手順メモになります。
作業の流れを整理する目的で記事を書いています。
処理環境ではPHPのLaravelフレームワークが入っている環境が用意されていたので、SFTP用の処理や設定を追加する流れになります。

なお、導入に際してはこちらの[記事](https://qiita.com/kiyoami/items/39c77696e16c07a57cad)や[サイト](https://www.ritolab.com/entry/87)を参考にしてます。

#環境について
+ Laravel:5.8
+ PHP:7.2

#導入手順

## 1.SFTPモジュールのインストール
Laravelのhomeディレクトリに移動して、`composer require`を実行してSFTPモジュールをインストールします。

```sh
composer require league/flysystem-sftp
```
以下のようにインストール結果が「successfully」と出てれば大丈夫です。

```shell

Using version ^1.0 for league/flysystem-sftp
./composer.json has been updated
（省略）
Package manifest generated successfully.
```
また、`composer.jsonのrequire`にも、sftpのバージョンが追記されます。

```json
{
   "require": {
       "league/flysystem-sftp": "^1.0"
   }
}
```
他にも`vendor/league/flysystem-sftp`ディレクトリが実行環境に作成されます。この辺りを確認できれば良いと思います。


## 2.sftpモジュールの用意
[参考サイト](https://qiita.com/kiyoami/items/39c77696e16c07a57cad)と同じ流れですが、
接続情報を環境ごとに分けたかったので、`.env`から参照するようにしています。

### 2.1 ServiceProviderへの登録
`make:provider`コマンドで、sftp用のServiceProviderクラスを作成します。

```sh
# サービスプロパイダファイルを生成用のコマンド
php artisan make:provider SftpServiceProvider
```

```php
<?php

namespace App\Providers;

use Storage;
use League\Flysystem\Filesystem;
use Illuminate\Support\ServiceProvider;
use League\Flysystem\Sftp\SftpAdapter;

class SftpServiceProvider extends ServiceProvider
{
    /**
     * Register services.
     *
     * @return void
     */
    public function register()
    {
        //
    }

    /**
     * Bootstrap services.
     *
     * @return void
     */
    public function boot()
    {
      Storage::extend('sftp', function ($app, $config) {
        return new Filesystem(new SftpAdapter([
          'host'        => $config['host'],
          'port'        => $config['port'],
          'username'    => $config['username'],
          'password'    => $config['password'],
          'privateKey'  => $config['privateKey'],
          'root'        => $config['root'],
          'timeout'     => $config['timeout'],
        ]));
      });
    }
    
}

```

### 2.2 FileSystemへの追記
`config/filesystem.php`へ、sftp用のディスク設定を追記します。
この際、本番やDEV環境のアクセス設定を`.env`から参照するようにしています。

未定義の項目があった場合は、`env関数`の第2引数の値が使用されます。
（設定値は、nullでエラーが起きなければ良い程度で設定しています）

```php
<?php

return [

   'disks' => [

        /*他のディスク設定も入っていると思いますが、省略します*/

        'sftp' => [
            'driver' => 'sftp',
            'host' => env('SFTP_HOST','192.168.10.10'),
            'port' => env('SFTP_PORT',22),
            'username' => env('SFTP_USER','myName'),
            'password' => env('SFTP_PW','myPass'),
            'privateKey' => env('SFTP_PRIVATE_KEY', '/home/myUser/.ssh/sftp_key.rsa'),
            'root' => env('SFTP_ROOT_DIR','/tmp'),
            'timeout' => 10,
          ],
    ],
];

```

`.env`には以下のように設定情報を用意しておきます。

```
SFTP_HOST=[接続先HOSTのドメインまたは、IPアドレス]
SFTP_PORT=[接続先HOSTのアクセス用のポート]
SFTP_USER=[ユーザーアカウント]
SFTP_PW=[ユーザーパスワード]
SFTP_PRIVATE_KEY=[アクセス用キーのパス]
SFTP_ROOT_DIR=[接続先のルートディレクトリ]
```

## 3.SFTP通信
### 3.1 SFTP通信の実装
細かい処理は割愛しますが、設定情報の読み込みとSFTPによるファイルアップロードについて記載します。

```php
//SFTPの設定をloggerに出力
logger()->info(get_class() . ' SFTP HOST is[ ' . Config::get('filesystems.disks.sftp.host') . ' ]' );
        
//SFTPアップロード用のstorage設定
$storageDir = storage_path() . DIRECTORY_SEPARATOR . 'app' . DIRECTORY_SEPARATOR . 'upload' . DIRECTORY_SEPARATOR ;

//sample.csvを、new_sample.csvとしてアップロード
$contents = file_get_contents($storageDir.'sample.csv');
Storage::disk('sftp')->put('new_sample.csv', $contents);     
```

### 3.2 各環境（本番/dev）へのデプロイ
自前で設定した「2.1 ServiceProvider」,「2.2 FileSystem」や「3.1で自作した処理」は、git管理されてると思いますが、`vendor`以下は各環境でデプロイしました。
私の場合は、`git pull`して`composer.json`を配置した後で、`composer install`を実行しました。

```sh
composer install
```

#おわりに
長文となりましたが、LaravelでのSFTPの導入や設定についてと、各環境でのデプロイについて記載しました。
個人の作業内容の振り返りとしてまとめた内容について、最後までお読みいただきありがとうございました。

#参考サイト
+ [ssh(sftp)サーバーをLaravelのストレージとして利用する-Qiita](https://qiita.com/kiyoami/items/39c77696e16c07a57cad)
+ [LaravelからSFTP転送でのファイル操作を行う-RitoLab(外部サイト)](https://www.ritolab.com/entry/87)