けけずんセルフハッキング

エンジニアっぽい雰囲気を醸しだしているかのようなブログです!

LaravelでS3へファイルをアップロード・参照する

概要

LaravelでアップロードされたファイルをS3に保存・参照する。

ファイルアップロード時の処理は下図の通り、クライアントからLaravelを通ってS3に保存される。

f:id:kkznch:20190404093027p:plain
LaravelからS3へアップロード

ファイルを参照する際は下図の通り、Laravelが対象となるファイルのURLをS3から取得してページにリンクする。URLからS3上のファイルを参照するために、対象となるファイルはPublicに公開される必要がある。

f:id:kkznch:20190404092903p:plain
LaravelからS3のファイルを参照

環境

  • Laravel 5.5.36

Laravelが動作するEC2、ファイル保存・参照先となるS3バケットは作成済みとする。

手順

AWS側の操作

AWSコンソールへログインし、以下の操作を行う。

IAMユーザーの作成

サービス「IAM」からサイドバーの「ユーザー」をクリックし、続いて以下の操作を行う。

  1. 「ユーザーを追加」をクリックする
  2. 「ユーザー名」を入力する
  3. 「プログラムによるアクセス」にチェックを入れる
  4. 「次のステップ:アクセス権限」をクリックする
  5. 「ユーザーをグループに追加」を選択する
  6. 「次のステップ:確認」をクリックする
  7. 「ユーザーの作成」をクリックする

ここでユーザの作成が完了する。このとき、作成したユーザーのセキュリティ認証情報が記述されたファイル(CSV)がダウンロード出来るので、ダウンロードしておく。

IAMユーザのアクセス権限を設定

サービス「IAM」からサイドバーの「ユーザー」をクリックし、続いて以下の操作を行う。

  1. 作成したユーザーをクリックする
  2. 「アクセス権限」タブを選択し、「インラインポリシー」をクリックする
  3. 「ビジュアルエディタ」タブにある項目を以下のように入力する
    1. 「サービスの選択」:S3
    2. 「アクション」:
      • 「GetObject」にチェック
      • 「PutObject」にチェック
      • 「DeleteObject」にチェック
      • 「PutObjectAcl」にチェック
    3. 「リソース」:
  4. 「Review policy」をクリックする
  5. 「名前」を入力する
  6. 「Create a policy」をクリックする

ちなみにJSONは以下のようになる。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:DeleteObject",
                "s3:PutObjectAcl"
            ],
            "Resource": "arn:aws:s3:::mybucket/myprefix/*"
        }
    ]
}

Resource要素の末尾に*がないと指定したプレフィックス(今回はmyprefix)以下を操作する権限がないと言われるので注意!

Laravel側の操作

パッケージをインストール

Laravelプロジェクトフォルダ下で以下のコマンドを入力する。

$ composer require league/flysystem-aws-s3-v3

これによりLaravelのファイルシステムでファイルの保存・参照先をS3に向けるためのパッケージがインストールされる。

.envを編集

.envファイルに以下を追記する。

AWS_S3_KEY=[AWS S3接続用ユーザのAccess Key ID]
AWS_S3_SECRET=[AWS S3接続用ユーザのSecret Key]
AWS_S3_REGION=[AWS S3設置リージョン]
AWS_S3_BUCKET=[AWS S3のバケット名]

config/filesystems.phpを編集

config/filesystems.phpを以下のように編集する。

<?php
return [
    'default' => 'local',
    'cloud' => 's3',

    'disks' => [

        'local' => [
            'driver' => 'local',
            'root' => storage_path('app'),
        ],

        'public' => [
            'driver' => 'local',
            'root' => storage_path('app/public'),
            'url' => env('APP_URL').'/storage',
            'visibility' => 'public',
        ],

+        's3' => [
+            'driver' => 's3',
+            'key' => env('AWS_S3_KEY'),
+            'secret' => env('AWS_S3_SECRET'),
+            'region' => env('AWS_S3_REGION'),
+            'bucket' => env('AWS_S3_BUCKET'),
+        ],

    ],

];

Controllerの作成

以下のコマンドでControllerを作成する。

$ php artisan make:controller UploadContentController

app/Http/Controllers/UploadContentController.phpを以下のように編集する。

<?php

namespace App\Http\Controllers;

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

class UploadContentController extends Controller
{
    public function index()
    {
        return view('upload');
    }

    public function store(Request $request)
    {
        $this->validate($request, ['myfile' => 'required|image']);

        $image = $request->file('myfile');

        /**
         * 自動生成されたファイル名が付与されてS3に保存される。
         * 第三引数に'public'を付与しないと外部からアクセスできないので注意。
         */
        $path = Storage::disk('s3')->putFile('myprefix', $image, 'public');

        /* 上記と同じ */
        // $path = $image->store('myprefix', 's3');

        /* 名前を付与してS3に保存する */
        // $filename = 'hoge.jpg';
        // $path = Storage::disk('s3')->putFileAs('myprefix', $image, $filename, 'public');

        /* ファイルパスから参照するURLを生成する */
        $url = Storage::disk('s3')->url($path);

        return redirect()->back()->with('s3url', $url);
    }
}

Viewの作成

resources/views/upload.blade.phpを作成し、以下のようにする。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Upload S3 Test</title>
</head>

<h1>S3アップロードテスト</h1>

{!! Form::open(['url' => '/upload', 'method' => 'post', 'class' => 'form', 'files' => true]) !!}

<div class="form-group">
{!! Form::label('myfile', 'Upload a file') !!}
{!! Form::file('myfile', null) !!}
</div>

<div class="form-group">
{!! Form::submit('Upload') !!}
</div>

{!! Form::close() !!}

@if (session('s3url'))
    <h1>いまアップロードしたファイル</h1>
    <img src="{{ session('s3url') }}">
@endif
</html>

考察

LaravelからS3に対してファイルのアップロード及びファイルの参照を行うことができた。Controller内でファイルアップロード時のS3のプレフィックスを指定している箇所があるが、毎回同じプレフィックスを指定するの面倒くさいな。何かいい方法ないかな。

参考

PhpStorm+phpcsでシンタックスチェック

概要

PhpStormのデフォの機能だけでシンタックスチェック出来るかと思って色々探してみたが、見つからず。 諦めてphpcsをインストールしてそれを使ってシンタックスチェックをするようにしてみる。

手順

参考にした記事とまんま同じこと書いてるだけ。

Terminalでやること

composerをインストールする

phpcsをインストールするためにcomposerコマンドを使用するので、brewコマンドでcomposerをインストールする。

$ brew install homebrew/php/composer

phpcsをインストールする

composerコマンドでphpcsをインストールする。 システム全体で使用できるようにglobalにインストールする。

$ composer global require "squizlabs/php_codesniffer=*"

試しに実行してみる。

$ phpcs -i
The installed coding standards are PEAR, Zend, PSR2, MySource, Squiz and PSR1

出来てるっぽいのでオッケー。 この後でPhpStormの設定をする際にphpcsのパスを入力する必要があるので、以下のコマンドでパスを確認しておく。

$ where phpcs
/Users/[ユーザ名]/.composer/vendor/bin/phpcs

PhpStormでやること

Languages & Flameworksの設定

"PhpStorm"->"Preferences"を開く。 サイドバーの"Languages & Frameworks"->"PHP"->"Code Sniffer"を選択する。 "Configuration"の右側にある"..."(何だこれ)をクリックする。 "PHP Code Sniffer (phpcs) path"欄の右側にある入力欄に先ほどのphpcsのパスを入力する。 "Validate"をクリックしてパスを検証、特に問題がなければ"OK"をクリックする。

PHP Code Sniffer validationの設定

"PhpStorm"->"Preferences"を開く。

サイドバーの"Editor"->"Inspections"を選択する。 "PHP"->"PHP Code Sniffer validation"の右側にあるチェックボックスにチェックを入れ、"Options"->"Coding standard"の右側にあるリロードマークをクリックし、選択欄から"PSR2"(ここに関してはお好みで)を選択する。

以上の設定でシンタックスチェックが行われるが、デフォだとどの箇所が規約に沿っていないのかが分かりづらいので、規約に沿っていない箇所の色を変えて分かりやすくする。 サイドバーの"Editor"->"Inspections"を選択する。 "PHP"->"PHP Code Sniffer validation"を選択した状態で、"Options"->"Show warnings as"の右側にある選択欄から"Edit Serverities"を選択する。 "+"ボタンをクリックしてお好みで色を設定し、"OK"をクリックする。

最後に"Preferences"ウィンドウ右下にある"OK"をクリック、これで準備OK。

試しに使ってみる

PSR2に準拠してない行の上にカーソルを合わせると怒られている内容を確認することが出来る。

参考

Laradock+PhpStormでXdebug

概要

Laradock+PhpStormな環境でXdebugを使う設定をするよ。

環境

手順

Laradockの設定、PhpStormの設定と順を追って設定していく。

Laradock

.envの設定

laradock/.envの項目を以下のように設定する。 もしかするとデフォで設定されてるかもだが、確認すべし。

WORKSPACE_INSTALL_XDEBUG=true
PHP_FOM_INSTALL_XDEBUG=true

php-fpmの、workspaceの設定

laradock/php-fpm/xdebug.inilaradock/workspace/xdebug.iniを以下のように設定する。

xdebug.remote_host=docker.for.mac.localhost
xdebug.remote_connect_back=0
xdebug.remote_port=9001
xdebug.idekey=PHPSTORM

xdebug.remote_autostart=1
xdebug.remote_enable=1
xdebug.cli_color=1
xdebug.profiler_enable=0
xdebug.profiler_output_dir="~/xdebug/phpstorm/tmp/profiling"

xdebug.remote_handler=dbgp
xdebug.remote_mode=req

xdebug.var_display_max_children=-1
xdebug.var_display_max_data=-1
xdebug.var_display_max_depth=-1

xdebug.remote_portが9000だとphp-fpmと衝突するため、9001にしている。 あと他のサイトだとxdebug.remote_connect_backが1でも動作するっぽいけど、自分の環境だと動かなかったので0にしている。

スケジューラのコメントアウト

Laradockはデフォでスケジューラが組み込まれており、定期的にphp artisanなコマンドがcronで呼ばれるという罠が仕掛けられている(ちゃんとした使いみちは知らん)。 こいつはデバッガに引っかかってしまうため、呼び出されないように設定する。

laradock/workspace/crontab/laradockを以下のようにコメントアウトする。

# * * * * * laradock php /var/www/artisan schedule:run >> /dev/null 2>&1

これ確か前の勉強会の時にサボさんが言ってた奴だよな...。

dockerイメージの再構築

以下のコマンドを入力してdockerイメージを再作成する。

$ docker-compose build workspace php-fpm

PhpStorm

Languages & Flameworksの設定

"PhpStorm"->"Preferences"を開く。 サイドバーの"Languages & Frameworks"->"PHP"->"Servers"を選択する。 "Languages & Frameworks"の"+"をクリックする。

各項目の設定を以下のように行う。

  • "Name": laradock(なんでもよい)
  • "Host": localhost
  • "Port": 80
  • "Debugger": Xdebug
  • "User path mapping": チェックを入れる
  • パスマッピング(ローカルPCとdockerでリンクされるプロジェクトのパス)
    • "File/Directory": ローカルPC上のlaravelプロジェクトのパス
    • "Absolute path on the server": docker上のlaravelプロジェクトのパス

Debugの設定

"PhpStorm"->"Preferences"を開く。 サイドバーの"Languages & Frameworks"->"PHP"->"Debug"を選択する。 "Xdebug"項目中の項目を以下のように設定する。

  • "Debug port": 9001

PHP Remote Debugの設定

"Run"->"Edit Configurations..."を開く。 サイドバーの"Defaults"->"PHP Remote Debug"を選択する。

各項目の設定を以下のように行う。

  • "Filter debug connection by IDE key": チェックを入れる
  • "Server": laradock("Language & Framework"で付けた名前)
  • "IDE key(session id)": PHPSTORM

以上で設定終わり。

実行してみる

PhpStormで任意のコードにブレークポイントを仕掛ける。 ブラウザからそのコントローラに対応するページにアクセスすると、PhpStormのデバッガが反応してくれる。

参考

macにDockerをインストール

概要

mac上でdockerを動かしたい。 brewコマンドでdockerをインストールするとdocker単体しかインストールされないため、brew caskコマンドでdockerをインストールする。

環境

手順

Docker.appのインストール

以下のコマンドでDocker.appをインストールする。

$ brew cask install docker

この時点ではdockerコマンドを叩いても使用できない。

$ docker --version
zsh: command not found: docker

Docker.appを起動

Docker.appを起動する。 色々設定した後にdockerコマンドが使用できるようになる。

$ docker --version
Docker version 17.09.1-ce, build 19e2cf6

感想

dockerよくわからんまま使ってるので少し勉強しないといけんなー。

「モブプログラミングでワイワイする会 その2.5」に参加して

[TDDYY会] モブプログラミングでワイワイする会 その2.5

2017/12/26(Tue)

YWT

Y

  • モブプログラミング
    • ある問題に対して皆で協力して挑む
    • PCと画面は一つずつで、ドライバー(PC操作する人)が一人、それ以外はナビゲータ
  • テスト駆動開発
    • 何をどうテストするか定義し、テストに沿って実装する
  • FizzBuzz問題
    • 3の倍数のときに"Fizz"を出力
    • 5の倍数のときに"Buzz"を出力
    • 15の倍数のときに"FizzBuzz"を出力
  • 動作をToDoリストとして列挙する
    • ToDoリストの更新はどのタイミングでもよい
  • タイムライン
    • 時間軸(横軸)に沿って何をやったか洗い出す
    • その時間毎の自分のモチベーションの上下を縦軸に線を描く

W

  • モブプログラミング楽しい
    • 考える時間はなるべくなくして、手を動かしながら考える
    • みんなでワイワイできる
    • 話し合いながら進めることで、お互いの知識をシェア出来て非常に良い
  • テスト駆動開発
    • 先にテストを書くことで何を実装するのかが明確になる
    • テスト書くの面倒と思っていたが、モブプログラミングと組み合わせると楽しい
    • 単体テストの方法は分かったが、結合テストの方法がちょっとよくわからん

T

  • テストの方法について勉強する
  • テストをするためのモジュールについて調べておく
  • 次回のtddyy会も開催する

参考

Atomエディタで特定の行を自動インデントするキーバインド

概要

Atomエディタでコーディングをする際、特定の行をよしなにインデントするようにctrl-iキーバインドを割り当てる。

環境

手順

Atom」->「Preferences」->「Keybindings」を開く。

Keybindingsのページ上部にあるリンク「your keymap file」をクリックしてキーマップ用のファイル(~/.atom/keymap.cson)を開く。

開いたファイルに以下のコードを追記する。

'atom-text-editor':
    'ctrl-i': 'editor:auto-indent'

考察

コーディング中にctrl-iで中々よい感じにインデントされるようになった。 tabキーを押すのって結構面倒なので、これで楽になれそう。

Laravel開発環境の簡単構築

概要

前回の記事(PHP7.1+Laravel5.x+Nginx+php-fpmな仮想環境構築)の改良版。

ホストOSとゲストOSで共有フォルダを設けて、ホストOS側でファイルを編集できる開発環境を作る。 共有フォルダを用いることで、ホストOS側でIDEを使ったファイル編集が可能になり、ゲストOSはDBのmigrate以外は基本的に触らずにLaravelプロジェクトページを開くことが出来る。

リポジトリは以下の通り。

github.com

環境

ホストOS

ゲストOS

構築手順

ホストOS(mac)での準備

composerをインストールする

laravelコマンドをインストールするのに使用する。

$ brew install homebrew/php/composer

laravelインストーラをダウンロードする

Laravelプロジェクトを作製するためのlaravelインストーラをダウンロードする。

$ composer global require "laravel/installer"

laravelコマンドを実行するためのパスを通す。

$ echo "path=(${HOME}/.composer/vendor/bin ${path})" >>${HOME}/.zshrc

.zshrcを再読込みする。

$ source ~/.zshrc

ここまででLaravelプロジェクト作製用コマンドの準備が完了した。

ゲストOS(仮想マシン)の用意

リポジトリをcloneする

リポジトリを公開してるので、まずはそこからcloneする。

$ git clone https://github.com/kkznch/laravelvm.git

仮想マシンを起動する

cloneしたリポジトリ内でvagrantコマンドを使って仮想マシンを起動する。 --provisionオプションはVagrantfile内で指定したプロビジョニング用のコマンドを実行する。 今回は中でansibleコマンドを実行している。

$ cd laravelvm
$ vagrant up --provision

SSH接続のための設定をする

起動した仮想マシンSSH情報を設定ファイルに追記する。

$ vagrant ssh-config >> ~/.ssh/config

この時点ではIPアドレスとポート番号がデフォルトのままなので、書き換える。

$ emacs ~/.ssh/config
Host laravelvm
  HostName 192.168.16.132 # 変更部分
  User vagrant
  Port 22 # 変更部分
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile /Users/kkz/.vagrant.d/insecure_private_key
  IdentitiesOnly yes
  LogLevel FATAL

ここまでで仮想マシンSSH接続ができるはず。

Laravelプロジェクトを作成する

仮想マシンリポジトリ内にあるsharedフォルダを共有フォルダとして仮想マシン内部の/var/wwwにマウントする。

また、仮想マシン/var/www/laravel/publicをドキュメントルートとしているため、sharedフォルダ内にlaravelという名前でLaravelプロジェクトを作成すればよい。

$ pwd
/path/to/laravelvm
$ ls
Vagrantfile playbook shared
$ cd shared

以下のコマンドでLaravelプロジェクトが作製される。

$ laravel new laravel

接続確認

ブラウザで以下のURLにアクセする。

http://192.168.16.132:9000

LaravelのTopページが表示されればOK。

Laravelプロジェクト編集

ホストOS(mac)にインストールされているIDEでLaravelプロジェクトを開き、コードを編集していく。 このとき、IDEにPhpStormを使っていれば楽になれる(デバッグ的な意味で)。 ファイル編集後はブラウザから上記URLにアクセスするだけでページが更新されているのが分かる。これが非常に楽ちん。

考察

仮想マシンは起動しておくだけでいいし、編集もローカルのIDEを使用して出来るのでかなり良い。 ただ、データベースの更新などを行う際は仮想マシン内で操作を行う必要がある。

参考