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でのファイル送受信が行えるまでを構築していきます。
- アジェンダ
開発環境
今回の開発環境は以下の通りです。
- 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ファサードから取得などのメソッドを叩いてみてください。