4
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.

League\Flysystemを使用してFTP接続してみる

Last updated at Posted at 2017-11-30

(2018/12/21)env関数から直接値を取得するのは避けた方がいいのでconfig経由で取得するようにしましょう

Laravel(Lumen)でLeague\Flysystemを使ってFTP接続してみます。

準備

まず**composer**でインストール。

composer require league/flysystem

使う際は以下のようにFTP情報をAdapterに渡してFilesystemをインスタンス化してやればいいみたいです。

参考:FTP Adapter - Flysystem

use League\Flysystem\Filesystem;
use League\Flysystem\Adapter\Ftp as Adapter;

$filesystem = new Filesystem(new Adapter([
    'host' => 'ftp.example.com',
    'username' => 'username',
    'password' => 'password',

    /** optional config settings */
    'port' => 21,
    'root' => '/path/to/root',
    'passive' => true,
    'ssl' => true,
    'timeout' => 30,
]));

実際に実装した際のコード

「サーバーにあるファイルを取得しローカルにダウンロードする処理」の実装時のコードです。

本番とテストで使用するサーバーが異なるので直書きせず、**.env**に接続先の情報を記述

.env
FILE_SYSTEM_HOST=
FILE_SYSTEM_USERNAME=
FILE_SYSTEM_PASSWORD=
FILE_SYSTEM_PORT=
FILE_SYSTEM_ROOT=
FILE_SYSTEM_PASSIVE=
FILE_SYSTEM_SSL=
FILE_SYSTEM_TIMEOUT=

STORAGE_DIRECTORY=

以下バッチ処理のClassです。
実行させる処理は**execute()**を想定しています。

FileOperation.php
<?php

namespace App;

use Log;  // Log出さないなら不要
use League\Flysystem\Filesystem;
use League\Flysystem\Adapter\Local;
use League\Flysystem\Adapter\Ftp as Adapter;

class FileOperation
{
    /**
    * FTP接続情報
    * @see  __construct()
    */
    private $ftpConnection = [];

    /**
    * 保存先ディレクトリパス
    * @see  __construct()
    */
    private $storageDirectory;

    /**
    * ダウンロード対象ファイル名
    * @see  __construct()
    */
    private $downloadFiles = [];

    /**
    * 最大試行回数
    * @see  __construct()
    */
    private $maxTries;

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        // この辺りの処理は場合によって異なるかもしれません・・・
        $this->ftpConnection = [
            'host'     => env('FILE_SYSTEM_HOST'),
            'username' => env('FILE_SYSTEM_USERNAME'),
            'password' => env('FILE_SYSTEM_PASSWORD'),
            'port'     => env('FILE_SYSTEM_PORT'),
            'root'     => env('FILE_SYSTEM_ROOT'),
            'ssl'      => env('FILE_SYSTEM_SSL'),
            'timeout'  => env('FILE_SYSTEM_TIMEOUT'),
        ];

        $this->storageDirectory = env('STORAGE_DIRECTORY');

        // ダウンロードするファイル名をここに記述する
        $this->downloadFiles = [
            'AAA.txt',
            'BBB.txt',
            'CCC.txt',
        ];

        $this->maxTries = 3;
    }

    /**
     * ファイル操作処理を実行する
     * 
     * @return bool
     */
    public function execute()
    {
        if ($this->download($this->ftpConnection) === false) {
            return false;
        }

        return true;
    }

    /**
     * ファイルのダウンロードを行う
     *
     * @param array $ftpConnection FTP接続情報
     * @return bool
     */
    public function download(array $ftpConnection)
    {
        Log::info('App\FileOperation:download() start');

        // エラー時、設定したトライ回数分処理を行う
        for ($i = 1; $i <= $this->maxTries; $i++) {
            try {
                // 接続先
                $remoteFilesystem = new Filesystem(new Adapter($ftpConnection));
                // ローカル
                $localFilesystem = new Filesystem(new Local($this->storageDirectory));

                // 設定したファイル数分取得処理を行う
                foreach ($this->downloadFiles as $downloadFile) {

                    // ファイル内容の読み込み
                    $content = $remoteFilesystem->read($downloadFile);

                    // 前回ファイルをアーカイブ
                    if ($localFilesystem->has($downloadFile) === true) {
                        $localFilesystem->rename($downloadFile, 'archive/' . $downloadFile);
                    }

                    // ローカルファイルに書き込み(ファイルがない場合は新規で作られる)
                    $result = $localFilesystem->write($downloadFile, $content);

                    Log::info('App\FileOperation:download() ' . $downloadFile . ' download processed. Result : ' . ($result === true ? 'SUCCESS' : 'FAILURE'));
        
                }

                Log::info('App\FileOperation:download() end');
        
                return $result;

            } catch (\Exception $e) {

                Log::error("App\FileOperation:download() ExceptionError(Try count " . $i . "): \n" . $e);
                sleep(10);

            }
        }

        Log::error("App\FileOperation:download() Error (Max trial end.)");
        return false;
    }

}

一応さくらサーバーに接続してローカルにファイルをDLすることには成功しました。
(バッチ処理の作りとしてはどうなんでしょうかね・・・?いかんせん初めてなもので・・・)

参考

4
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
4
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?