1. Home
  2. PHP
  3. Laravel
  4. LaravelからSFTP転送でのファイル操作を行う(league/flysystem-sftp)

LaravelからSFTP転送でのファイル操作を行う(league/flysystem-sftp)

  • 公開日
  • カテゴリ:Laravel
  • タグ:PHP,Laravel,Flysystem,FileStorage,5.6,SFTP
LaravelからSFTP転送でのファイル操作を行う(league/flysystem-sftp)

Laravel ファイル操作

  1. local/public ディスク編
  2. Amazon S3 編
  3. SFTP 編

Laravel5.6.7(2018 年 2 月 28 日リリース)から、SFTP でのファイル操作がサポートされました。
[5.6] SFTP driver #23308

今回は Laravel を使い、SFTP でのファイル送受信が行えるまでを構築していきます。

Contents

  1. 開発環境
  2. SFTP とは
  3. SFTP ドライバのインストール
  4. 設定情報の追加
  5. サービスプロパイダの作成
    1. サービスプロパイダ生成
    2. SFTP サービスプロパイダ実装
  6. 動作確認
    1. コントローラ作成
    2. ルーティング

開発環境

今回の開発環境は以下の通りです。

  • Linux CentOS 7
  • Apache 2.4
  • PHP 7.2
  • Laravel 5.6

Laravel のバージョンは 5.6.7 以上です。

Laravel のルートディレクトリを「laravel/」とします。

SFTP とは

SFTP(SSH File Transfer Protocol)は、SSH 接続にて暗号化や認証を行い、安全かつ高速にファイル転送を実現する転送プロトコルです。クライアントソフトでは Windows の WinSCP などが有名です。

SFTP ドライバのインストール

SFTP ドライバを使う為には、league/flysystem-sftp パッケージを導入する必要があります。以下の composer コマンドを叩きインストールします。

# Laravel ルートディレクトリへ移動する
cd /path/to/laravel

# league/flysystem-sftp パッケージをインストール
composer require league/flysystem-sftp

# 実行結果
[demo@localhost laravel]# composer require league/flysystem-sftp
Using version ^1.0 for league/flysystem-sftp
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 2 installs, 0 updates, 0 removals
  - Installing phpseclib/phpseclib (2.0.10): Downloading (100%)
  - Installing league/flysystem-sftp (1.0.15): Downloading (100%)
phpseclib/phpseclib suggests installing ext-libsodium (SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.)
phpseclib/phpseclib suggests installing ext-mcrypt (Install the Mcrypt extension in order to speed up a few other cryptographic operations.)
phpseclib/phpseclib suggests installing ext-gmp (Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.)
Writing lock file
Generating optimized autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover
Discovered Package: fideloper/proxy
Discovered Package: laravel/tinker
Discovered Package: nunomaduro/collision
Package manifest generated successfully.

もしくは、composer.json に以下を追加して、composer update でも導入できます。

"require": {
    "php": ">=7.1.3",
    "fideloper/proxy": "~4.0",
    "laravel/framework": "5.6.*",
    "laravel/tinker": "~1.0",
    "league/flysystem-sftp": "^1.0" // ← ここを追加
},

設定情報の追加

インストールが完了したら、設定ファイルへ SFTP の設定を追加します。

laravel/config/filesystems.php
'sftp' => [
  'driver' => 'sftp',
  'host' => '192.168.99.99',
  'port' => 22,
  'username' => 'myname',
  'password' => 'mypass',
  'privateKey' => '/path/to/privatekey',
  'root' => '/tmp',
  'timeout' => 10,
],

各項目は以下の通りです。

  • driver
    • ドライバ種別
  • host
    • ホスト名
  • port
    • ポート番号
  • username
    • ユーザ名
  • password
    • パスワード
  • privateKey
    • 秘密鍵までのパス(使用しない場合は空白)
  • root
    • ログイン後の初期パス
  • timeout
    • 接続できない時間がどれくらい続いたら切断するか(秒)

サービスプロパイダの作成

次に、サービスプロパイダを作成します。

サービスプロパイダ生成

artisan コマンドでサービスプロパイダクラスを生成します。 Laravel ルートディレクトリへ移動し、以下のコマンドを叩きます。

# Laravel ルートディレクトリへ移動
cd /path/to/laravel

# サービスプロパイダファイルを生成する
php artisan make:provider SftpServiceProvider

# 実行結果
[demo@localhost laravel]# php artisan make:provider SftpServiceProvider
Provider created successfully.

laravel/app/Providers 配下に SftpServiceProvider.php が生成されます。

laravel
├─ app
│   ├─ Providers
│   │   ├─ SftpServiceProvider.php
laravel/app/Providers/SftpServiceProvider.php
<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

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

    /**
     * Register services.
     *
     * @return void
     */
    public function register()
    {
//
    }
}

SFTP サービスプロパイダ実装

それでは生成した SFTP サービスプロパイダクラスを実装していきます。以下のようになります。

laravel/app/Providers/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
{
    /**
     * 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'],
        ]));
      });
    }

    /**
     * Register services.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

Storage ファサードの extend() メソッドで、第一引数には登録する種別 sftp を渡しつつ、第二引数でクロージャを定義しています。

各設定変数を SftpAdapter インスタンス化の際に渡し、それらを Filesystem のインスタンスに渡します。

これで、Filesystem で SFTP が使えるようになりました。

動作確認

実装が完了したので、実際に動かして試してみます。

コントローラ作成

コントローラに Storage ファサードを使ってファイル操作を記述します。

laravel/app/Http/Controllers/SampleController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;

class SampleController extends Controller
{
public function index()
  {
    $contents = file_get_contents(storage_path('test.txt'));
    Storage::disk('sftp')->put('file.txt', $contents);
  }
}

アプリケーション側の Storage/app配下にある test.txt を読み込み、SFTP にて接続先の/tmp ディレクトリへ file.txt として保存します。

ちなみにコントローラには記述がありませんが、.env に初期ディレクトリを/tmp と記述したので、接続先の初期ディレクトリは/tmp となり、put() メソッドでファイル名だけを記述した場合の保存先パスは/tmp/file.txt となります。

ルーティング

最後にルーティングを記述します。

laravel/routes/web.php
Route::get('/sample/sftp', 'SampleController@index');

準備も終わったので、ブラウザから
http://YOURDOMAIN/sample/sftp
にアクセスして一連の処理を動かし、保存先であるサーバを確認してみます。

問題なくファイルが保存されました。これで SFTP でのファイル操作は完了です。

まとめ

接続までできてしまえば、あとは通常のファイル操作と変わらないので、Storage ファサードから取得などのメソッドを叩いてみてください。

Author

rito

  • Backend Engineer
  • Tokyo, Japan
  • PHP 5 技術者認定上級試験 認定者
  • 統計検定 3 級