LoginSignup
11
12

More than 5 years have passed since last update.

LaravelのファイルストレージでConohaのオブジェクトストレージを使う

Last updated at Posted at 2017-09-22

Laravelのファイルストレージ、便利ですね。
s3、FTPなど様々なファイルシステムを同じインターフェースで扱うことができます。

元からローカル、Amazon S3rackspaceなどのドライバが使えるようになってますが、
S3は料金体系が難しい、rackspaceはよくわからない、ということで、
今回はConohaのオブジェクトストレージに接続してみました。

作業

ライブラリのインストール

前述のrackspaceが、conohaと同じopenstackという規格でできているので、
conohaでもこのライブラリを使います。
用意されているとはいえライブラリの追加インストールが必要みたいなのでcomposerでインストール。
参考:https://readouble.com/laravel/5.4/ja/filesystem.html#driver-prerequisites

composer require league/flysystem-rackspace

ServiceProviderの登録

そのまま使ってもうまく接続できませんので、認証部分だけオリジナルで作成します。
以下のServiceProviderを新規作成します。

app/Providers/ConohaServiceProvider.php
<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use League\Flysystem\Filesystem;
use League\Flysystem\Rackspace\RackspaceAdapter;
use OpenCloud\OpenStack;

class ConohaServiceProvider extends ServiceProvider
{
    /**
     * サービスの初期処理登録後に実行
     *
     * @return void
     */
    public function boot()
    {
        $filesystem = $this->app->make('filesystem');
        $filesystem->extend('conoha', function($app, $config) {
            $client = new OpenStack($config['auth_url'], [
                'username' => $config['username'],
                'password' => $config['password'],
                'tenantName' => $config['tenant_name'],
            ]);
            $client->authenticate();
            $service = $client->objectStoreService('Object Storage Service', $config['region']);
            $container = $service->getContainer($config['container']);

            return new Filesystem(new RackspaceAdapter($container));
        });
    }

    /**
     * コンテナで結合の登録
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

ServiceProviderを作成したら、config/app.phpに登録します。

config/app.php
   'providers' => [
        // ...

        \App\Providers\ConohaServiceProvider::class, // ←追加
    ],

configの登録

認証情報などをconfig/filesystem.php.envに追加します。

config/filesystem.php
   'disks' => [
        // ...

        'conoha' => [
            'driver'        => 'conoha',
            'auth_url'      => env('OS_AUTH_URL', ''),
            'username'      => env('OS_USERNAME', ''),
            'password'      => env('OS_PASSWORD', ''),
            'tenant_name'   => env('OS_TENANT_NAME', ''),
            'container'     => env('OS_CONTAINER', ''),
            'region'        => env('OS_REGION', ''),
        ],
    ],
.env
OS_AUTH_URL=
OS_USERNAME=
OS_PASSWORD=
OS_TENANT_NAME=
OS_CONTAINER=
OS_REGION=

各設定値の意味は以下のとおりです。
※ConohaのAPIに関しては公式ドキュメントが参考になります。
事前に、cyberduckなりでコンテナを作っておくと良いです。
https://www.conoha.jp/guide/objectstoragecyberduck.php

名前 説明
OS_AUTH_URL Conohaのコントロールパネル→API→エンドポイント→Identity ServiceのURL
OS_USERNAME APIユーザー名
OS_PASSWORD APIユーザーパスワード
OS_TENANT_NAME Conohaのコントロールパネル→API→テナント情報→テナント名
OS_CONTAINER 作成したコンテナ名
OS_REGION リージョン名(エンドポイントの「tyo1」.conoha.ioの部分。東京ならtyo1)

使う

ここまでやれば、他のドライバと同じように使えます。
Laravelのファイルストレージについては公式ドキュメントが参考になります。
https://readouble.com/laravel/5.4/ja/filesystem.html

たとえばPOSTされたファイルをアップロードするなら以下のようになります。

$path = $request->file('avatar')->store('avatars', 'conoha');

ServiceProvider解説

app/Providers/ConohaServiceProvider.php
        $filesystem = $this->app->make('filesystem');
        $filesystem->extend('conoha', function($app, $config) {

filesystemのドライバに新しくconohaを追加します。extendメソッドの第1引数がドライバ名です。
functionの引数$configには、config/filesystem.phpで定義したusernameなどが入ってます。

app/Providers/ConohaServiceProvider.php
            $client = new OpenStack($config['auth_url'], [
                'username' => $config['username'],
                'password' => $config['password'],
                'tenantName' => $config['tenant_name'],
            ]);

OpenCloud\OpenStackのインスタンスを生成します。

認証情報はconfigで設定した値を渡しているだけです。
※rackspaceのドライバではこの部分がrackspace専用の実装になっており、
そのまま使うとconohaの認証と合わずにエラーになってしまってました。

app/Providers/ConohaServiceProvider.php
            $client->authenticate();

認証を行います。
※ここで認証しないと、このあとのobjectStoreServiceのところで、カテゴリが見つからない的なエラーになります。

app/Providers/ConohaServiceProvider.php
            $service = $client->objectStoreService('Object Storage Service', $config['region']);
            $container = $service->getContainer($config['container']);

オブジェクトストレージにアクセスするサービスを取得し、設定ファイルで指定したコンテナの情報を取り出します。

app/Providers/ConohaServiceProvider.php
            return new Filesystem(new RackspaceAdapter($container));

最後に、RackspaceAdapter$containerを渡し、Filesystemを生成して返します。
認証部分以外に関しては、rackspaceがそのまま使えるみたいですね。

(追記)WebMode時のURLを取得したい場合

ConohaのオブジェクトストレージをWebModeに設定しており、そのURLを取得したい場合、
上記の方法だとurl()メソッドが「対応してない」とエラーになってしまうことがわかったので、
対応方法を追記します。

なお、WebModeの詳しい説明はこちらをご参照ください。
https://www.conoha.jp/guide/objectstoragesdk.php

configに設定追加

WebMode時のURLのベースパスを登録します。

.env
OS_WEB_URL=[WebMode時のURLベース]
app/filesystems.php
        'conoha' => [
            // ...
            'web_url'       => env('OS_WEB_URL', ''), // ←追加
            // ...
        ],

ConohaAdapterを新たに作成

rackspaceのアダプタを継承してConoha用のアダプタを登録します。
なお、作成する場所は以下じゃなくても大丈夫だと思います。

app/Services/Filesystem/ConohaAdapter.php
<?php

namespace App\Services\Filesystem;

use League\Flysystem\Rackspace\RackspaceAdapter;

class ConohaAdapter extends RackspaceAdapter
{
    /**
     * WEB公開用のURLを取得
     * @param $path
     * @return string
     */
    public function getUrl($path)
    {
        return config('filesystems.disks.conoha.web_url') . DIRECTORY_SEPARATOR . $path;
    }
}

ConohaServiceProviderでインスタンス化するアダプタをConohaAdapterに変更

app/Providers/ConohaServiceProvider.php
            return new Filesystem(new ConohaAdapter($container));

RackspaceAdapterを継承しているので他の機能はそのまま使えます。


これで、url($path)メソッドでWebMode時のURLが取得できます。

11
12
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
11
12