20200830のlaravelに関する記事は7件です。

Using another database for phpunit test on Laravel 6 with docker-compose.

Every engineer would hope to divide database when running test.
I'll show using another database for phpunit test on Laravel 6 with docker-compose in this article.

STEP

  1. Adding test database on docker-compose
  2. Adding setting for test database in config/database.php
  3. Adding environment at phpunit.xml
  4. Create .env.testing as new env file
  5. Running migration command for test database
  6. Running phpunit

CODES

docer-compose.yml
version: '3' 
services:    
  db:            
    build:   
      context: ./app/mysql
    environment: 
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: hoge
      MYSQL_USER: hoge
      MYSQL_PASSWORD: hoge
    container_name: mydb
    ports: 
      - "3306:3306"
    tty: true
    volumes:
      - ./app/mysql/db_data:/var/lib/mysql
  testdb:            
    build:   
      context: ./app/mysql
    environment: 
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: hoge
      MYSQL_USER: hoge
      MYSQL_PASSWORD: hoge
    container_name: testdb
    ports: 
      - "3307:3306"
    tty: true
    volumes: 
      - ./app/mysql/testdb_data:/var/lib/mysql
  web:
    ...
config/database.php
    ...

    'connections' => [

       ... 

       'mysql' => [
            ...
        ],  

        'mysql_testing' => [
            ...
            'host' => 'testdb',
            ...
        ],  


phpunit.xml
<?xml version="1.0" encoding="UTF-8"?>                                    
    ...
    <php>                                                                 
        <env name="APP_ENV" value="testing" force="true"/> 
        <env name="DB_CONNECTION" value="mysql_testing" force="true"/> 
        ... 
    </php>                                                                
</phpunit>    
.env.testing
APP_ENV=test
APP_KEY=[YOURKEY]
APP_DEBUG=true 
$ php artisan:migrate database=mysql_testing
$ ./vendor/bin/phpunit
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

LaravelユーザがRailsの勉強を始めようと思った話

スキルセット

  • HTML
  • CSS
  • JavaScript
  • PHP
  • Laravel

勉強中

  • AWS
  • Docker
  • CircleCI

理由

  • 開発が早そう
  • Railsでチーム開発がしたい
  • 身の回りにRailsユーザが多い
  • Rails + AWS + Docker + CicleCIでなにか作りたい

勉強法

オブジェクト指向の理解や、MVCは理解済みなので、とりあえずProgateやって経過を見ます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Laravel実践】リクエストパラメータ名をスネークケースに変換する方法

Version

  • Laravel 5.7
  • PHP 7.2.31

前提

LaravelでAPIを開発する際、キャメルケースとして書かれたリクエストパラメータ名をスネークケースに変換したい、という要望を想定します。たとえば、SPA開発においてReact.jsやVue.jsにより非同期通信でLaravelのAPIにリクエストを送信する際、フロント側としてはキャメルケースで統一したいがバックエンド側としてはスネークケースで統一したい、というケースです。

Laravel側で簡単に変換する方法をググったのですが、ベストプラクティス的な方法が出てこなかったのでここに共有します。

早速、変換してみよう。

結論だけ述べると、以下の方法で実現できます。

$request->all()でリクエストパラメータを受け取り、リクエストパラメータ名($key)に大文字が含まれる場合にスネークケースに変換・挿入、offsetUnset()で元のプロパティ名を消す、ということをやっています。

foreach ($request->all() as $key => $value) {
    if(preg_match('/[A-Z]/', $key)){
        $new_key = Str::snake($key);
        $request->merge([$new_key => $request->$key]);
        $request->offsetUnset($key);
    }
}

たとえば、TestControllerのindexで受け取ることを考えてみましょう。バリデーションを一旦無視すれば、以下のように書けるはずです。

TestController.php
class TestController
{
    public function index(Request $request)
    {
        // スネークケースに変換する処理
        foreach ($request->all() as $key => $value) {
            if(preg_match('/[A-Z]/', $key)){
                $new_key = Str::snake($key);
                $request->merge([$new_key => $request->$key]);
                $request->offsetUnset($key);
            }
        }
        // hogehoge処理
        ...
        return $request;
    }
}

応用: スネークケース変換用のクラスを作成

色々と応用する方法はあると思いますが、最終的に以下の方法で落ち着きました。

  • FormRequestクラスでバリデーション処理(※1)
  • Controllerクラスを継承する形でスネークケースに変換するクラスを作成(※2)
  • indexのController側でスネークケース変換用のメソッドを呼び出し(※3)
NormalizedController.php
// ※2
class NormalizedController extends Controller
{
    /**
     * Change request parameter from camel case to snake case
     *
     * @param object $request
     * @return object
     */
    protected function normarize_request(Object $request) : object
    {
        foreach ($request->all() as $key => $value) {
            if(preg_match('/[A-Z]/', $key)){
                $new_key = Str::snake($key);
                $request->merge([$new_key => $request->$key]);
                $request->offsetUnset($key);
            }
        }
        return $request;
    }
}
TestController.php
// FormRequestクラス(※1)
use App\Http\Requests\Test\GetRequest;

class TestController extends NormalizedController
{
    public function index(GetRequest $request)
    {
        // 呼び出し(※3)
        $this->normarize_request($request);

        // hogehoge処理
        ...
        return $request;
    }
}

参照

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

laravel 別のMYSQLに動的接続、切り替え

laravel で 別のデータベースに切り替えたい時がある。
例えば、古いDBから新しいDBにデータを以降する時など。

今回は、database twiski に切り替たい

database.php
//色々と略
'connections' => [

'mysql' => [
    'driver' => 'mysql',
    'url' => env('DATABASE_URL'),
    'host' => env('DB_HOST', '127.0.0.1'),
    'port' => env('DB_PORT', '3306'),
    'database' => env('DB_DATABASE', 'forge'),
],


'old' => [
    'driver' => 'mysql',
    'url' => env('DATABASE_URL'),
    'host' => env('DB_HOST', '127.0.0.1'),
    'port' => env('DB_PORT', '3306'),
    'database' => 'twiski',//接続したいDBに書き換える
],


これで twiski に切り替えられる

HogeContorller.php
$model = new User;

$res = $model
    ->orderBy('id', 'ASC')
    ->first();

$res = $model
    ->setConnection('old')//これが味噌
    ->orderBy('id', 'ASC')
    ->first();


DBファサードを使う

これで oldusers テーブルのデータ取得できる

HogeController.php
//use DB;

$profiles_tags = DB::connection('old')
    ->table('users')
    ->limit(5)
    ->get();


以上

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Sign In With Appleを実装

概要

  • Sign In With Appleをアプリに組み込む際に調べたことをまとめました。
  • 今回の内容はサーバーサイドのみの内容となります。

開発環境

  • 使用言語:PHP(v7.3.11)
  • フレームワーク:Laravel(v7.20.0)
  • DB:Sqlite

事前準備

  • Apple Developerに登録してSign In With Appleの設定をしておく 以下の値、ファイルを取得
  • アプリのバンドルID
  • KeyID
  • 秘密鍵の.p8ファイル(1度しかダウンロードできないので注意)
  • TeamID

認証の流れ

以下の手順で認証を行いました
* クライアント側でSign In With Appleの認証をする
* 認証結果のcode値をサーバに送る
* サーバ側でcodeの検証
* 検証結果がJWT形式で返ってくるのでJWTデコードする

codeの検証

検証はAppleが提供している検証APIに以下のパラメータをPOSTして行います。
API:POST https://appleid.apple.com/auth/token
パラメータ
* client_id:アプリのバンドルIDのこと
* client_secret
* code:クライアント側から取得する
* grant_type:検証なので'authorization_code'を設定
* redirect_uri:あらかじめDevelopperサイトで登録しておく

client_secretの作成

  • client_secretとは検証に必要なJWTでエンコードされた値
  • JWTとは3種類の文字列をドットで繋げた文字列
  • JWTの作成にはfirebaseが提供しているライブラリを使用(他にもありましたが今回は以下を使用しました)

client_secret作成に必要な値

今回は以下のように実装しました

$key = openssl_pkey_get_private('file://'.PRIVATE_KEY_PASS); // 秘密鍵ファイルのパス
$now = time();
$expire = time() + 86400 * 180; // 有効期限を半年に設定
$payload = array(
    'iss' => TEAM_ID,
    'iat' => $now,
    'exp' => $expire,
    'aud' => 'https://appleid.apple.com',
    'sub' =>  CLIENT_ID
);
return JWT::encode($payload, $key, 'ES256', KEY_ID); // ES256は署名アルゴリズム

検証結果からユーザーを一意に特定するIDを取得

  • ユーザーを特定する文字列はid_tokenの中に含まれているのですが、JWT形式のためそのまま取り出すことはできません。
  • id_tokenは「ヘッダー.ペイロード.署名」のように情報をドット区切りで持っています
  • ユーザーを特定するIDはペイロードの中に含まれる「sub」値がそれに該当します

以下のようにしてsub値を取得しました

$jwt_token = expload('.', 'id_token');
$payload = base64_decode($jwt_token[1]);
$decode_payload = json_decode($payload, true);
$sub = $decode_payload['sub'];

参考資料

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【GitHub Actions】LaravelのCI環境構築

実現したいこと

GitHub Actionsを用いて、LaravelのCI環境構築をします。

前提

開発環境でPHPUnitのvendor/bin/phpunitコマンドを実行したら問題なくテストが正常に動作するのが前提です。

ワークフローの作成

github/workflows/ci.yml
name: CI

on:
  push:
    branches: [master]
  pull_request:
    branches: [master]

jobs:
  php-nuit:
    runs-on: ubuntu-latest

    services:
      mysql:
        image: mysql:8.0.19
        ports:
          - 3306:3306
        options: --health-cmd "mysqladmin ping -h localhost" --health-interval 20s --health-timeout 10s --health-retries 10
        env:
          MYSQL_ROOT_PASSWORD: password
          MYSQL_DATABASE: testdatabase

    env:
      DB_CONNECTION: mysql
      DB_HOST: 127.0.0.1
      DB_PORT: 3306
      DB_DATABASE: testdatabase
      DB_USERNAME: root
      DB_PASSWORD: password

    steps:
      - uses: actions/checkout@v2
      - name: Copy .env
        run: cp .env.ci .env
        working-directory: ./server
      - name: composer install
        run: |
          composer install --no-scripts
        working-directory: ./server
      - name: Generate key
        run: php artisan key:generate
        working-directory: ./server
      - name: Directory Permissions
        run: chmod -R 777 storage bootstrap/cache
        working-directory: ./server
      - name: migrate
        run: php artisan migrate
        working-directory: ./server
      - name: php-unit test
        run: ./vendor/bin/phpunit
        working-directory: ./server

今回のテストでは、データベースも絡んでいるため、MySQLを使用しました。また、私のLaravelのディレクトリ構造は下記の添付画像のようになっていたため、コマンドによってはディレクトリを指定するworking-directory: ./serverを記述しています。

スクリーンショット 2020-08-30 6.29.39.png

■参考
https://github.com/yuuta1988/shussekikun/blob/master/.github/workflows/ci.yml

.env.ciの作成

ワークフローで.env.ciを元に.envファイルを複製するので、.env.ciを作成します。

server/.env.ci
APP_NAME=Laravel
APP_ENV=testing
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=testdatabase
DB_USERNAME=root
DB_PASSWORD=password

■参考
https://github.com/yuuta1988/shussekikun/blob/master/server/.env.ci

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CodeIgniter3 から Laravel へ。文化の異なるフレームワークへ飛び込む上で,ハードルになりそうなパッケージ管理システムの概要を解説

概要

今回は,より高度な(実用的な)仕様の例題を設定し,CodeIgniter と Laravel のコードを対比させていきたいと思います。

具体的には,CSS と JS を組み込んだページを作成したいと思いますが,具体的なコードの紹介は次回の記事にゆだね,今回は,もっと基本となる「パッケージ管理システム」について触れます。

あまり一気に難しくならないよう,極力配慮したいと思いますが,前回よりは,ハードルがぐーんと高くなり,おじさんの言語化能力で,どこまで的確に表現できるか,冷や汗をかきそうです(プレッシャーの重圧感)。

マサカリ歓迎案件です(いろいろ教えてください)。

Laravel で登場する,2つのパッケージ管理システム

どのタイミングで話すべきか迷ったのですが,いずれ書かねばならないことなので,今のタイミングにします。

「軽量であること」を強みとする CodeIgniter は,フレームワークと言うより,フォルダ構造を決めただけの,ファイルの集合体に近いですね(そんな言い方をしてしまうと,世の中のすべてのフレームワークが,「ファイルの集合体」と言えますが……)。

一方,Laravel も「ファイルの集合体」ではありますが,「パッケージ管理システム」が標準的な仕組みとして多用されることが大きな相違点です。

※パッケージ管理システムをまったく使わず,Laravel で開発するのも可能かと思いますが,ほとんどメリットはないと思います(しんどくなるだけ)

※「パッケージ管理システムが何であるか」は,優れた記事が多数あるため,本記事の記述スコープに含めません

しかも,驚くなかれ,Laravel には,二種類のパッケージ管理システムが採用されています:

  • Composer バックエンド側(PHP ファイル)のパッケージ管理を担う
  • Laravel Mix フロントエンド側(CSS / JS ファイル)のパッケージ管理を担う

どっちか一つを使うというものではなく,役割がそもそも異なっているのですね(バックエンド側か,フロントエンド側か)。

以下,もっと具体的に見ていきましょう。

プロジェクト新規作成

CodeIgniter は,公式サイトから zip としてダウンロードする方法。

あくまでも,開発者が,ブラウザで公式サイトへアクセスし,そこからファイル一式を取得するというスタンスですね。

image.png

一方,Laravel では,Composer というパッケージ管理システムを使って,コマンドラインからプロジェクトのファイル一式を生成します。

たとえば,example という名のプロジェクトを生成するには,以下のようなコマンドを実行します:

composer create-project --prefer-dist laravel/laravel example

CodeIgniter に慣れていると,つい,手作業でファイルを追加したり,移動したりする衝動に駆られてしまいますが,そこはグッと我慢することが,Laravel 文化の入り口です。

最後に,もう一度まとめます:

工程 CodeIgniter Laravel
テンプレート一式の取得 公式サイトから zip をダウンロード Composer コマンド経由で取得

PHP ファイルの追加

CodeIgniter で新しい PHP ファイル(例:コントローラ)を追加するときには,テキストファイルをコピペする感覚で,みんな大好き Ctrl + CCtrl + P のショートカットが大活躍でした。

一方,Laravel では,新しい PHP ファイル(例:コントローラ)を追加するときには,パッケージ管理システム Composer を使って,コマンドライン上で実行します。

たとえば,MyFirstController というコントローラを作る場合,以下のようなコマンドを実行します:

php artisan make:controller MyFirstController

Laravel でも,Ctrl + CCtrl + P で,新しい PHP ファイルを生成可能(例:既存のクラスからコピーして生成可能)ですが,コピー後のファイルの中身を,自分で書き換える手間が生じるので,あまりスマートな方法だとは言えません。

最後に,もう一度まとめます:

工程 CodeIgniter Laravel
PHP ファイルの追加 Ctrl + CCtrl + P で手動対応 Composer コマンド経由で作成

CSS / JS ファイルの追加

CSS / JS ファイルといった,フロントエンドのアセットを生成するケースを考えます。

「ファイルの集合体」のようにシンプルな CodeIgniter では,所定のフォルダへ,CSS や JS を保存するだけ(&その後,ビュー側の <head></head> 部で,読み込ませるだけ)。

Laravel でも,所定のフォルダへ,CSS / JS を保存するという,CodeIgniter 時代のスタイルは利用可能です。

一方,Laravel では,もう一つのパッケージ管理システム Laravel Mix を使うというオプションも,用意されています。

超ざっくり書くと,以下のような役割を果たしてくれます。

  • 依存関係のあるライブラリを一括取得(一番「親」のライブラリを指定すると,配下の関連ライブラリを,芋づる式に,拾ってきてくれます)
  • リリースしやすいよう,関連ファイルを,一つのファイルにまとめてパッキング

コマンドラインでは,npm run dev とすれば,開発環境でデバッグが容易な(人の目で見ても解釈しやすい)形式にパッキングしてくれます。

一方,npm run production とすれば,リリースに適した形式(空白や改行を除外し,コンピュータの解釈に適したもの。ファイルサイズとしても,すごく小さくなる)にパッキングしてくれます。

ひとつ強調しておくと,Laravel Mix は,その名に 'Laravel' を冠しながらも,Laravel 利用の有無とは関係なく使える,パッケージ管理システムだったりします。

つまり,CodeIgniter でも,Laravel Mix を活用することは可能です。

最後に,もう一度まとめます:

工程 CodeIgniter Laravel
CSS / JS ファイルの追加 所定フォルダに,手動で保存 Laravel Mix 利用

まとめ

かなり駆け足になりましたが,CodeIgniter では手作業メインで行っていたファイル管理を,Laravel では,コマンドライン経由で済ませるのだという理解を形成いただければ,本記事のリリース目的は達成されました。

事実,コマンドラインで,パッケージ管理システムを上手に活用し,エンジニアが本来注力すべき作業へ集中させてくれるようになっているのは,Laravel のコンセプトでもあるように感じます。

次回では,実際に,パッケージ管理システムを操作しながら,Laravel を用いたフロントエンドアセット(CSS / JS)の組み込みについて,CodeIgniter と比較させながら見ていきたいと思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む