RitoLabo

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

  • 公開:
  • カテゴリ: PHP Laravel
  • タグ: PHP,Laravel,Flysystem,FileStorage,5.6,SFTP

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

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

アジェンダ
  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ファサードから取得などのメソッドを叩いてみてください。