20200628のlaravelに関する記事は11件です。

【Laravel】idごとの情報を表示する

ユーザーのマイページのような、特定のidの情報を表示する方法のメモ。

Route

web.php
Route::group(['prefix'=>'~~~~~~','middleware'=>'auth'], function () {
    Route::get('index', '*******Controller@index')->name('~~~~~~.index');
    Route::get('create', '*******Controller@create')->name('~~~~~~.create');
    Route::post('store', '*******Controller@store')->name('~~~~~~.store');
    Route::get('show/{id}', '*******Controller@show')->name('~~~~~~.show');//この部分
});

Controller

****Controller.php
public function show($id)
    {
        $***** = モデル名::find($id);  //idを見つける

        //条件分岐の処理
        if($*****->gender === 0){
            $gender = '男性';
        }elseif ($*****->gender === 1) {
            $gender = '女性';
        }

        return view('*****.show',compact('*****','gender'));
    }

条件分岐する必要がある場合は、Controller内で処理させてその変数をcompactの引数に入れる。

View

show.blade.php
<div>
    {{$contact->name}}
    {{$gender}}  //Controllerでcompactの引数にセットしているので変数がそのまま使える。
</div>

表示できてたらおk。

おまけ

indexページからshowに飛ばす時のボタン。

index.blade.php
<button onclick="location.href='{{route('*****.show',['id' => $*****->id])}}'">詳細</button>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Laravel基礎】DBにデータを保存・保存内容を表示

LaravelでDBにデータを保存する方法と、保存した内容を表示する方法のメモ。

前提

resourceでControllerを作っています。

注意

コード部分の「****」「&&&&」みたいなのは代替文字です。

DBに保存

Controller,Route,Viewのそれぞれに書いていきます。

Route

web.php
Route::group(['prefix'=>'~~~~~~','middleware'=>'auth'], function () {
    Route::get('index', '*******Controller@index')->name('~~~~~~.index');
    Route::get('create', '*******Controller@create')->name('~~~~~~.create');
    Route::post('store', '*******Controller@store')->name('~~~~~~.store'); //この部分
    Route::get('show/{id}', '*******Controller@show')->name('~~~~~~.show');
});

postでviewで入力されたパラメータを受け取る。

View

create.blade.php
<form method="POST" action="{{route('~~~~~.store')}}">
    @csrf
    <input class="input-group" type="text" name="name" placeholder="Name">
    <input class="input-group" type="text" name="email" placeholder="Mail">
    男性:<input type="radio" name="gender" value="0">
    女性:<input type="radio" name="gender" value="1">
    <input class="input-group" type="text" name="title" placeholder="Title">
    <textarea class="input-group" name="contact" placeholder="Contact"></textarea>
    <input class="btn btn-primary" type="submit" value="Submit">
</form>

methodをpostに設定してパラメータをstoreに送信する。

Controller

~~~~~Controller.php
use App\Models\モデル名;

public function store(Request $request)
    {
        //Modelをインスタンス化
        $***** = new ContactForm;

        $*****->name = $request->input('name');
        $*****->email = $request->input('email');
        $*****->title = $request->input('title');
        $*****->gender = $request->input('gender');
        $*****->contact = $request->input('contact');

        $*****->save();  //保存

        return redirect('*****/index');  //indexページにリダイレクト
    }

Modelファイルを利用して送られてきたパラメータをDBに保存します。

保存できてるかどうか一度DBで確認してください。
できてたらおk。

Viewに表示

Controller,Viewのそれぞれに書いていきます。

Controller

*****Controller.php
use Illuminate\Support\Facades\DB;  //クエリビルダを利用

public function index()
    {
        // クエリビルダ
        $&&&&&& = DB::table('テーブル名')
        ->select('id','name','gender')  //表示したい情報のカラム名を記述
        ->get();  //取得
        return view('******.index',compact('&&&&&'));
    }

必要なデータだけ欲しい時はクエリビルダを使った方が処理速度が遅くならなくて済む。

View

index.blade.php
@foreach($****** as $×××××)
    {{$×××××->id}}
    {{$×××××->name}}
    @if($×××××->gender===0)
        男性
    @else
        女性
    @endif
@endforeach

データをforeachで回してあげる。
カラム名を指定して必要な情報を表示する。

Viewで表示できてるのが確認できたらおk。

まとめ

基本的にはController,View,Routeをいじればできます。

本当に基礎の基礎なので多分もっと良い書き方とか他にあるかと思いますが、基礎学習中の人間のメモなのでご容赦を。

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

Laravel7(Centos)

アップデート可能な全パッケージをアップデートする。

 yum -y update


2. Apacheのインストール
Apacheをインストールする

 yum -y install httpd
Apacheを起動する

 systemctl start httpd
 systemctl enable httpd
 systemctl status httpd
httpが接続できるように80ポートを許可する。

 firewall-cmd --add-service=http --zone=public
 firewall-cmd --reload
 systemctl restart firewalld
ブラウザでhttp://localhostに接続し、Apacheの初期画面が表示されることを確認する。

2. PHPのインストール
PHP7のリポジトリを追加する。

 sudo wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
 sudo rpm -ivh epel-release-latest-7.noarch.rpm
 sudo yum install -y http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
 sudo yum-config-manager --enable remi-php73
PHPをインストールする。

 yum install -y php73 php73-php php73-php-mysql php73-php-php-mysqlnd php73-php-bcmath php73-php-ctype php73-php-json php73-php-mbstring php73-php-openssl php73-php-PDO php73-php-tokenizer php73-php-xml gcc
PHPのシンボリックリンクを設定する。

 ln -s /usr/bin/php73 /usr/bin/php
PHPがインストールされたことを確認する。

 php -v
3. MariaDBのインストール
MariaDBをインストールする。

 yum install -y mariadb mariadb-server
MariaDBを起動する。

 systemctl start mariadb
 systemctl enable mariadb
 systemctl status mariadb
MariaDBの初期設定スクリプトを実行し、rootユーザーのパスワードを設定する。

 mysql_secure_installation
MariaDBに接続する。

 mysql -u root -p
Laravelで使用するMariaDBのユーザーを作成する。

> create user 'ユーザー名'@'localhost' identified by 'パスワード';
> grant all on *.* to 'ユーザー名'@'localhost';
4. composerのインストール
composerをインストールする。

 yum install composer
composerがインストールされたことを確認する。

 composer -V
5. Laravelプロジェクトの作成
composerでLaravelのライブラリを読み込む。

 composer global require laravel/installer
Laravelのプロジェクトを作成する。

 cd /var/www/html
 composer create-project --prefer-dist laravel/laravel プロジェクト名 "バージョン"
作成したプロジェクトのアクセス権限を変更する。

 chmod -R 777 /var/www/html/プロジェクト名
LaravelでMariaDBが使用できるように.envを編集する。

 cd /var/www/html/プロジェクト名
 vi .env

(省略)
DB_CONNECTION=mysql
DATABASE_URL=mysql://MariaDBのユーザー名:MariaDBのパスワード@127.0.0.1/MariaDBのデータベース名
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=MariaDBのデータベース名
DB_USERNAME=MariaDBのユーザー名
DB_PASSWORD=MariaDBのパスワード
Laravelを日本語環境に変更する。

 cd /var/www/html/プロジェクト名
 vi config/app.php

(省略)
'timezone' => 'Asia/Tokyo',

(省略)
'locale' => 'ja',
Apacheを再起動する。

systemctl restart httpd
6. Laravelの動作確認
Laravelのビルドインサーバを立ち上げる。

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

Laravelでユーザー情報画面のアクセス制限を実装~Middlewareの活用~

はじめに

LaravelのMiddlewareを活用して、カート画面のような、ユーザー情報画面へのアクセス制限を実装していきます。

ユーザー情報画面のアクセス制限とは

ユーザー情報画面など、ログインユーザー自身だけが閲覧できるページです。
例えば、カート画面は、カート作成者とログインユーザーが一致した場合のみアクセス可能になります。

カートを作成したAさんのページは、Aさんのみが見れるようにする制御を実装していきます。
Aさんのページを、Aさん以外がアクセスした場合は、特定のページにリダイレクトさせます。

実行環境

Laravel 5.5

目次

-Middlewareとは
-実装コード&解説

Middlewareとは

ミドルウェアを把握する一番良い方法は、HTTPリクエストがアプリケーションに届くまでに通過する、数々の「レイヤー(層)」なのだと考えることです。それぞれのレイヤーは、リクエストを通過させるかどうかテストし、場合により完全に破棄することさえできます。

公式 ミドルウェアより

こちらも、参考になると思います。

Laravelのミドルウェアの実施順検証と小技

実装コード&解説

今回作成するミドルウェアは、LoginUserCheckとします。

1.middlewareを作成

ターミナル上で、下記コマンドを実行します。

$ php artisan make:middleware LoginUserCheck

app/Http/Middleware/LoginUserCheck.phpが作成されます。

2.LoginUserCheck.phpに処理を記述

LoginUserCheck.php
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Auth;

class LoginUserCheck
{
     /**
      * Handle an incoming request.
      *
      * @param  \Illuminate\Http\Request  $request
      * @param  \Closure  $next
      * @return mixed
      */
      public function handle($request, Closure $next) {

         //ログインユーザーIDを取得
         $loginId = Auth::id();
         //カート情報のユーザーIDを取得
         $requestId = $request->user_id;

         //ログイン者とカート情報作成者が一致しなければ別のページにリダイレクト
         if ($loginId != $requestId) {
            return redirect(route('home'));
         }

      //チェックに合格し次の処理に進むことができる
      return $next($request);
      }
}

3.ミドルウェアの登録

app/Http/Kernel.phpでミドルウエアの登録を行います。

app/Http/Kernel.php
<?php

namespacenamespace App\Http;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel
{

//~~中略~~

   protected $middlewareGroups = [
      'web' => [
         //~~中略~~
      ],

      'api' => [
         //~~中略~~
      ],

      //ここから追記箇所
      'loginUserCheck' => [        
          \App\Http\Middleware\LoginUserCheck::class,
      ],
      //ここまで
  ];

4.Routeで名前指定

route/web.php
Route::group(['middleware' => ['loginUserCheck']], function() {
  //ここに実行したい処理を記述
}

以上で、特定のページは、ログインユーザーと情報作成ユーザーが一致した場合のみ表示させることができるようになります。

おわりに

ご覧いただきありがとうございました。
修正箇所、ご指摘等ございましたらご意見いただけますと幸いです。

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

Laravel入門学習ノート part6 『マイグレーション』

今回の内容

マイグレーションの説明
laravelのマイグレーション方法

マイグレーションとは

そもそもMigrateという英単語には「移動する」という意味がある。
Migrationは「移動」「移行」という意味。

データベースを扱う本来の意味のマイグレーションは
『データを保持したままテーブル変更やDB移行を行う』
というような意味らしい。

laravel公式ドキュメントでは

Migrations are like version control for your database, allowing your team to easily modify and share the application's database schema.
↓ 翻訳したもの
移行はデータベースのバージョン管理のようなもので、チームがアプリケーションのデータベーススキーマを簡単に変更および共有できるようにします。

とある。

マイグレーションファイル作成

アプリケーションフォルダでmakeコマンド実行。
指定したファイル名でマイグレーションファイルが作成される。
今回は例として「create_fruits_table」でファイル作成。

php artisan make:migration create_fruits_table

実行すると/database/migrationsフォルダ内に日付付きでファイルが作成される。
(ファイル名の日付部分は人によって異なります)

この記事で使用しているlaravel 7では、ID列はid()で指定できる。
Laravel 6系以前はincrement()と指定するっぽい。

2020_06_27_XXXXXX_create_fruits_table.php
// 抜粋
class CreateFruitsTable extends Migration{
  public function up(){
    Schema::create('fruits', function (Blueprint $table) {
      $table->id();
      $table->timestamps();
    });
  }

  public function down(){
    Schema::dropIfExists('fruits');
  }
}

up()には「今回のマイグレーションでの更新内容」を書く。
down()にはup()を取り消す操作を書く。

up()に列名変更や列追加、削除なども記述できる。
個人で小規模にやる分にはテーブル作成のマイグレーションだけで事足りる気もする。

fruitsテーブルに名前を入れるname列と価格を入れるprice列を追加する。
up()関数にその内容を追加する。

database/migrations/xxxx_create_fruits_table.php
public function up(){
  Schema::create('fruits', function (Blueprint $table) {
    $table->id();
    $table->string('name', 20); // 追加
    $table->integer('price');   // 追加
    $table->timestamps();
  });
}

列を記述する時、型もいっしょに指定する。
また、外部キーやnullable、デフォルト値も設定できる。

詳しいことは公式ドキュメントから
https://laravel.com/docs/7.x/migrations#creating-columns

マイグレーション実行

マイグレーションファイルが完成したら下記コマンドでマイグレーションを実行する。
マイグレーションを実行するというのは、ファイルの記述内容を実際にDBに反映させること。

php artisan migrate

実行したらログが出る。
エラーが出てなければ成功。

Migration table created successfully.
...省略
Migrating: 2020_06_27_144910_create_fruits_table
Migrated:  2020_06_27_144910_create_fruits_table (0.05 seconds)

create_fruits_tableがマイグレーションされていることがわかる。

確認

fruitsテーブルが作成されている。

・failed_jobs
・migrations
・password_reset
・users
laravelが自動で作るセキュリティ関係のテーブルとマイグレーション管理のテーブル。

la_tab.png

fruitsテーブルはこんな感じ。
name列とprice列もちゃんと追加されている。
image.png

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

Laravel入門学習ノート part6 『マイグレーション・テーブル作成』

今回の内容

マイグレーションの説明
Laravelのマイグレーション方法

マイグレーションとは

そもそもMigrateという英単語には「移動する」という意味がある。
Migrationは「移動」「移行」という意味。

データベースを扱う本来の意味のマイグレーションは
『データを保持したままテーブル変更やDB移行を行う』
というような意味らしい。

Laravel公式ドキュメントでは

Migrations are like version control for your database, allowing your team to easily modify and share the application's database schema.
↓ 翻訳したもの
移行はデータベースのバージョン管理のようなもので、チームがアプリケーションのデータベーススキーマを簡単に変更および共有できるようにします。

とある。

マイグレーションファイル作成

アプリケーションフォルダでmakeコマンド実行。
指定したファイル名でマイグレーションファイルが作成される。
今回は例として「create_fruits_table」でファイル作成。

php artisan make:migration create_fruits_table

実行すると/database/migrationsフォルダ内に日付付きでファイルが作成される。
(ファイル名の日付部分は人によって異なります)

この記事で使用しているLaravel 7では、ID列はid()で指定できる。
Laravel 6系以前はincrement()と指定するっぽい。

2020_06_27_XXXXXX_create_fruits_table.php
// 抜粋
class CreateFruitsTable extends Migration{
  public function up(){
    Schema::create('fruits', function (Blueprint $table) {
      $table->id();
      $table->timestamps();
    });
  }

  public function down(){
    Schema::dropIfExists('fruits');
  }
}

up()には「今回のマイグレーションでの更新内容」を書く。
down()にはup()を取り消す操作を書く。

up()に列名変更や列追加、削除なども記述できる。
個人で小規模にやる分にはテーブル作成のマイグレーションだけで事足りる気もする。

fruitsテーブルに名前を入れるname列と価格を入れるprice列を追加する。
up()関数にその内容を追加する。

database/migrations/xxxx_create_fruits_table.php
public function up(){
  Schema::create('fruits', function (Blueprint $table) {
    $table->id();
    $table->string('name', 20); // 追加
    $table->integer('price');   // 追加
    $table->timestamps();
  });
}

列を記述する時、型もいっしょに指定する。
また、外部キーやnullable、デフォルト値も設定できる。

詳しいことは公式ドキュメントから
https://laravel.com/docs/7.x/migrations#creating-columns

マイグレーション実行

マイグレーションファイルが完成したら下記コマンドでマイグレーションを実行する。
マイグレーションを実行するというのは、ファイルの記述内容を実際にDBに反映させること。

php artisan migrate

実行したらログが出る。
エラーが出てなければ成功。

Migration table created successfully.
...省略
Migrating: 2020_06_27_144910_create_fruits_table
Migrated:  2020_06_27_144910_create_fruits_table (0.05 seconds)

create_fruits_tableがマイグレーションされていることがわかる。

確認

fruitsテーブルが作成されている。

・failed_jobs
・migrations
・password_reset
・users
Laravelが自動で作るセキュリティ関係のテーブルとマイグレーション管理のテーブル。

la_tab.png

fruitsテーブルはこんな感じ。
name列とprice列もちゃんと追加されている。
image.png

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

laravel-adminの設定をエクスポートしてseederに追加する方法

laravel-adminのMenu設定をエクスポートして、seederに追加することで初期Migration時にデータを戻す方法を考えました。

laravel-adminのメニューやロールの初期設定を開発画面で作っておいて別環境で再現するなど。

admin:export-seedではMenuやRoleの情報しかExportされない

php artisan admin:export-seed
Admin tables seed file was created: /database/seeds/AdminTablesSeeder.php
Use: php artisan db:seed --class=AdminTablesSeeder

上記のコマンドで設定が全部エクスポートされたよわーい!と思ってdb:seedしても、管理画面にログインできない。どうやらこのエクスポートされたSeederを見る限り、ユーザー情報が含まれていないように見える。

admin useraのseederは別で作らないといけないようだ。。。

こちらの記事を参考にlaravel-admin初期設定のSeederをコピーします。

https://qiita.com/ntm718/items/5ea29ee70b50320352c4

ファイル名をクラス名をAdminUsersSeederに変更して、// create a user.〜role部分だけ使って以下のように修正。

AdminUsersSeeder
<?php

use Illuminate\Database\Seeder;
use Encore\Admin\Auth\Database\Administrator;
use Encore\Admin\Auth\Database\Role;
use Encore\Admin\Auth\Database\Permission;

class AdminUsersSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        // create a user.
        Administrator::truncate();
        Administrator::create([
            'username' => 'admin',
            'password' => bcrypt('admin'),
            'name'     => 'Administrator',
        ]);

        // create a role.
        Role::truncate();
        Role::create([
            'name' => 'Administrator',
            'slug' => 'administrator',
        ]);

        // add role to user.
        Administrator::first()->roles()->save(Role::first());

        // 別のユーザー(例:staff)やロールを初期状態で追加しておく場合
        Administrator::create([
            'username' => 'staff',
            'password' => bcrypt('staff'),
            'name'     => 'staff',
        ]);

        // create a role.
        Role::create([
            'name' => 'staff',
            'slug' => 'staff',
        ]);

        // add role to user.
        Administrator::find(2)->roles()->save(Role::find(2));



    }
}

AdminUsersSeeder, AdminTablesSeederをDatabaseSeederに追加。

    public function run()
    {
        $this->call(AdminUsersSeeder::class);
        $this->call(AdminTablesSeeder::class);
    }

これで、admin/adminでログインできる初期ユーザーと、GUIで設定したmenu,role,permisson情報がシーダーにエクスポートされました。

php artisan migrate:fresh
php artisan db:seed

上記のコマンドを実行して、ユーザーとメニューが戻ることを確認。

以後、メニューや権限を編集した場合は、再度

php artisan admin:export-seed

で、設定がSeederにエクスポートされます。
ユーザーを追加した場合は?手動でファイルに追記してください・・・

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

[Laravel][PHPUnit]APIテストコードの忘備録

LaravelのPHPUnitでAPIのコントローラに対するテストコードを書いた忘備録。
例はコメントのCRUD操作。

/tests/Feature/ApiCommentControllerTest.php
<?php

namespace Tests\Feature;

use Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;
use App\Classes\User\Session;

class ApiCommentControllerTest extends TestCase
{
    protected $user_session_id;

    function setUp(): void
    {
        parent::setUp();

        // アプリ側で$_SERVER変数や$_REQUEST変数を利用している場合は明示する必要がある
        $_SERVER['REQUEST_URI'] = 'XXXX';
        $_REQUEST['s'] = (new Session)->create(1);
        $this->user_session_id = $_REQUEST['s'];
    }

    public function testCreateComment()
    {
        $response = $this->post(
            '/api/comment/create',
            [
                'post_id' => 1,
                'user_id' => 1,
                'comment' => 'auto test',
                's' => $this->user_session_id
            ]
        );

        $response->dump();
        $response->assertStatus(200);
    }

    public function testListComment()
    {
        $response = $this->post(
            '/api/comment/list',
            [
                's' => $this->user_session_id
            ]
        );

        $response->dump();
        $response->assertStatus(200);
    }

    public function testUpdateComment()
    {
        $response = $this->post(
            '/api/comment/update',
            [
                'id' => 1
                'post_id' => 1,
                'user_id' => 1,
                'comment' => 'auto test update',
                's' => $this->user_session_id,
            ]
        );

        $response->dump();
        $response->assertStatus(200);
    }

    public function testDeleteComment()
    {
        $response = $this->post(
            '/api/comment/delete',
            [
                'id' => 1
                's' => $this->user_session_id,
            ]
        );

        $response->dump();
        $response->assertStatus(200);
    }
}

実行

$ php artisan route:cache
$ ./vendor/bin/phpunit 
#もしくは $ composer exec phpunit
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravelアプリ同士をWeb APIで連携させる

オンプレで動く Laravel と、クラウドで動く Laravel を、Web API でシステム間連携させた話。
image.png

やりたいこと

社内オンプレの給与明細APサーバにアクセスすると、クラウドの勤怠打刻APサーバのデータも取得し、給与明細と合わせて勤怠実績明細も表示させる。
image.png

Web API の設計

設計時に決めておくべき項目。

  • HTTPメソッド
    GET

  • エンドポイント
    /api/v1/kintai/{yyyyMM}/{勤怠個人番号}

  • 機能概要
    従業員の勤怠実績データを返す

  • リクエスト

    • yyyyMM ・・・ 年月("last" と指定された場合は最終年月とする)
    • 勤怠個人番号 ・・・ 従業員の勤怠個人番号(Active Directory に照会すること)
  • レスポンス

    • ステータスコード
      • 200 ・・・ 成功
      • 404 ・・・ リクエストされた勤怠実績が存在しなかった
    • 応答形式 ・・・ JSON

REST APIはステートレスなので、認証にCookieやセッションは使えない。APIではトークン認証BASIC認証が一般的だが、今回は社内システムということもあり、簡素化のため認証は省略する。

【参考】人事労務パッケージが提供するAPI

Laravelでの実装方法

勤怠打刻APサーバ

APIが呼ばれる側のサーバ。
api.phpにエンドポイントを定義する。web.phpとは違い、api.phpにはCSRF保護が無い。

routes\api.php
Route::get('v1/kintai/{yyyymm}/{id}', 'Api\KintaiController@index');

呼ばれるコントローラを作成する。

app\Http\Controllers\Api\KintaiController.php
<?php
namespace App\Http\Controllers\Api;
use Illuminate\Http\Request;
use App\Models\Result;
use Carbon\Carbon;
use App\Http\Controllers\Controller;

/*
  給与明細サーバから呼ばれるクラス
*/
class KintaiController extends Controller
{
    public function index(Request $request, $yyyymm, $syaincd)
    {
        if ($yyyymm == 'last') {  // last指定時は最終年月を仮定
            $yyyymm = Carbon::yesterday()->format('Ym');
        }
        $baseDate = Carbon::create(substr($yyyymm, 0, 4), substr($yyyymm, 4, 2), 1);  // 基準日の設定

        // 勤怠実績データベースの読み込み
        $query = Result::where('syaincd', $syaincd)
            ->whereBetween('kintaijissekiymd', array($baseDate->copy()->startOfMonth()->format('Ymd'), $baseDate->copy()->endOfMonth()->format('Ymd')))
            ->orderBy('kintaijissekiymd');

        // レコード件数が0より大きければデータを返し、そうでなければエラーレスポンスとする
        if ($query->count() > 0) {
            return response()->json([
                'code'     => 200,
                'contents' => $query->get()
              ], 200);
        } else {
            return response()->json([
                'code'     => 404,
                'message'  => 'Not Found'
              ], 404);
        }
    }
}

Eloquentモデルでは、文字列にキャストされるときJSONに変換されるため、Eloquentオブジェクトをそのまま返すことができる。

コマンドからAPIをテストする

curlコマンドで得られるJSONデータをjqコマンドで整形して確認。

シェルからコマンドを実行
curl -s https://example.com/api/v1/kintai/202006/12765 | jq
出力結果
{
  "code": 200,
  "contents": [
    {
      "syaincd": 12765,
      "syainmei": "山田 太郎",
      "kanrisyouninkengencode": "一般社員",
      "kintaijissekiymd": "20200625",
      "syugyozikantaikaishihhmi": "0850",
      "syugyozikantaisyuryohhmi": "1730",
      "meisyo": "出勤",
      "barcodesyukkinhhmi": "0842",
      "barcodetaikinhhmi": "1738",
      :

給与明細APサーバ

APIを呼ぶ側のサーバ。
昨今のWebアプリでは、APIで取得したデータはVueやReactで表示することが多いが、ここではLaravelで受けてビュー(Blade)に渡す。

app\Http\Controllers\KintaiController.php(一部)
$context = stream_context_create(array(
  'http' => array('ignore_errors' => true)
));
$kintaicd = $request->session()->get('user')->kintaicd;
// APIを呼び出す
$json = file_get_contents("https://example.com/api/v1/kintai/$yyyymm/$kintaicd", false, $context);
$ary = json_decode($json);  // JSONを配列に

// 正常なら "contents" をViewに渡す
if ($ary->code == 200) {
    $reports = $ary->contents;
} else {
    $reports = null;
}

return view('kintai', compact('reports'))
   ->with('spec_type', 'kintai')
   ->with('ym', substr($yyyymm, 0, 4) . '年' . ltrim(substr($yyyymm, 4, 2), '0') . '月')
   ->with('prev_month', $dt->copy()->subMonth(1)->format('Ym'))
   ->with('next_month', $dt->copy()->addMonth(1)->format('Ym'));

ビュー(Blade)で $reports を展開する。

resources\views\kintai.blade.php
<div class="table-responsive">
    <table class="table text-nowrap table-bordered table-striped table-hover table-condensed">
      <thead>
      <tr>
        <td rowspan="2">日付</td>
        <td rowspan="2">勤怠種別</td>
        <td colspan="2">打刻</td>
         省略
      </tr>
      <tr>
        <td>出勤</td>
        <td>退勤</td>
        <td>就業開始</td>
         省略
      </tr>
      </thead>
      <tbody>
      @foreach ($reports as $report)
      <tr>
          <td>{{ $report->kintaijissekiymd }}</td>
          <td>{{ $report->syukkinhhmi }}</td>
          <td>{{ $report->taikinhhmi }}</td>
           省略
      </tr>
      @endforeach
      </tbody>
    </table>
</div>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravelアプリ同士をWeb APIで連携させるには

オンプレで動く Laravel と、クラウドで動く Laravel を、Web API でシステム間連携させてみた話。
image.png

やりたいこと

社内オンプレの給与明細APサーバにアクセスすると、クラウドの勤怠打刻APサーバのデータも取得し、給与明細と合わせて勤怠実績明細も表示できるようにする。
シーケンス図で書くと次のようになる。
image.png
勤怠実績明細の表示例。
image.png

Web API の設計

設計時に決めておくべき項目。

  • HTTPメソッド
    GET

  • エンドポイント
    /api/v1/kintai/{yyyyMM}/{勤怠個人番号}

  • 機能概要
    従業員の勤怠実績データを返す

  • リクエスト

    • yyyyMM ・・・ 年月("last" と指定された場合は最終年月とする)
    • 勤怠個人番号 ・・・ 従業員の勤怠個人番号(Active Directory に照会すること)
  • レスポンス

    • ステータスコード
      • 200 ・・・ 成功
      • 404 ・・・ リクエストされた勤怠実績が存在しなかった
    • 応答形式 ・・・ JSON

REST APIはステートレスなので、認証にCookieやセッションは使えない。APIではトークン認証BASIC認証が一般的だが、今回は社内限定利用ということもあり、簡素化のため認証は省略する。

(参考) クラウド人事労務パッケージのAPI

Laravelでの実装方法

勤怠打刻APサーバ

APIが呼ばれる側のサーバ。
api.phpにエンドポイントを定義する。web.phpとは違いapi.phpにはCSRF保護が無い。

routes\api.php
Route::get('v1/kintai/{yyyymm}/{id}', 'Api\KintaiController@index');

呼ばれるコントローラを作成する。

app\Http\Controllers\Api\KintaiController.php
<?php
namespace App\Http\Controllers\Api;
use Illuminate\Http\Request;
use App\Models\Result;
use Carbon\Carbon;
use App\Http\Controllers\Controller;

/*
  給与明細サーバから呼ばれるクラス
*/
class KintaiController extends Controller
{
    public function index(Request $request, $yyyymm, $syaincd)
    {
        if ($yyyymm == 'last') {  // last指定時は最終年月を仮定
            $yyyymm = Carbon::yesterday()->format('Ym');
        }
        $baseDate = Carbon::create(substr($yyyymm, 0, 4), substr($yyyymm, 4, 2), 1);  // 基準日の設定

        // 勤怠実績データベースの読み込み
        $query = Result::where('syaincd', $syaincd)
            ->whereBetween('kintaijissekiymd', array($baseDate->copy()->startOfMonth()->format('Ymd'), $baseDate->copy()->endOfMonth()->format('Ymd')))
            ->orderBy('kintaijissekiymd');

        // レコード件数が0より大きければデータを返し、そうでなければエラーレスポンスとする
        if ($query->count() > 0) {
            return response()->json([
                'code'     => 200,
                'contents' => $query->get()
              ], 200);
        } else {
            return response()->json([
                'code'     => 404,
                'message'  => 'Not Found'
              ], 404);
        }
    }
}

Eloquentモデルでは、文字列にキャストされるときJSONに変換されるため、Eloquentオブジェクトをそのまま返しても良い。

コマンドからAPIをテストする

curlコマンドで得られるJSONデータをjqコマンドで整形して確認。

シェルからコマンドを実行
curl -s https://example.com/api/v1/kintai/202006/12765 | jq
出力結果
{
  "code": 200,
  "contents": [
    {
      "syaincd": 12765,
      "syainmei": "山田 太郎",
      "kanrisyouninkengencode": "一般社員",
      "kintaijissekiymd": "20200625",
      "syugyozikantaikaishihhmi": "0850",
      "syugyozikantaisyuryohhmi": "1730",
      "meisyo": "出勤",
      "barcodesyukkinhhmi": "0842",
      "barcodetaikinhhmi": "1738",
      :

給与明細APサーバ

APIを呼ぶ側のサーバ。
昨今のWebアプリでは、APIで取得したデータはフロントエンドの Vue や React で表示することが多いが、ここではLaravelで受けてビュー(Blade)に渡す。

app\Http\Controllers\KintaiController.php(一部抜粋)
$context = stream_context_create(array(
  'http' => array('ignore_errors' => true)
));
$kintaicd = $request->session()->get('user')->kintaicd;
// APIを呼び出す
$json = file_get_contents("https://example.com/api/v1/kintai/$yyyymm/$kintaicd", false, $context);
$ary = json_decode($json);  // JSONを配列に

// 正常なら "contents" をViewに渡す
if ($ary->code == 200) {
    $reports = $ary->contents;
} else {
    $reports = null;
}

return view('kintai', compact('reports'))
   ->with('spec_type', 'kintai')
   ->with('ym', substr($yyyymm, 0, 4) . '年' . ltrim(substr($yyyymm, 4, 2), '0') . '月')
   ->with('prev_month', $dt->copy()->subMonth(1)->format('Ym'))
   ->with('next_month', $dt->copy()->addMonth(1)->format('Ym'));

ビュー(Blade)で $reports を展開する。

resources\views\kintai.blade.php
<div class="table-responsive">
    <table class="table text-nowrap table-bordered table-striped table-hover table-condensed">
      <thead>
      <tr>
        <td rowspan="2">日付</td>
        <td rowspan="2">勤怠種別</td>
        <td colspan="2">打刻</td>
         省略
      </tr>
      <tr>
        <td>出勤</td>
        <td>退勤</td>
        <td>就業開始</td>
         省略
      </tr>
      </thead>
      <tbody>
      @foreach ($reports as $report)
      <tr>
          <td>{{ $report->kintaijissekiymd }}</td>
          <td>{{ $report->syukkinhhmi }}</td>
          <td>{{ $report->taikinhhmi }}</td>
           省略
      </tr>
      @endforeach
      </tbody>
    </table>
</div>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel MySQL DBのカラムタイプを途中で変更する

目的

  • Laravelにて新規作成後のDBのカラムタイプの変更方法をまとめる

実施環境

  • ハードウェア環境
項目 情報
OS macOS Catalina(10.15.5)
ハードウェア MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports)
プロセッサ 2 GHz クアッドコアIntel Core i5
メモリ 32 GB 3733 MHz LPDDR4
グラフィックス Intel Iris Plus Graphics 1536 MB
  • ソフトウェア環境
項目 情報 備考
PHP バージョン 7.4.3 Homwbrewを用いて導入
Laravel バージョン 7.0.8 commposerを用いてこちらの方法で導入→Mac Laravelの環境構築を行う
MySQLバージョン 8.0.19 for osx10.13 on x86_64 Homwbrewを用いてこちらの方法で導入→Mac HomebrewでMySQLをインストールする

前提情報

  • MySQLを使用しているが確認箇所以外はそのほかのRDSでも作業内容は変わらない。
  • カラム名を変更するとLaravelアプリで自分で実装したデータ取得処理を変更しないといけない場合があるので注視する。
  • すでに存在するカラムのタイプ(データ型や有効文字数など)を変更する際の方法を記載する。
  • 現在のカラムタイプが下記に記載されているものではないと変更することはできない。
    • bigInteger
    • binary
    • boolean
    • date
    • dateTime
    • dateTimeTz
    • decimal
    • integer
    • json
    • longText
    • mediumText
    • smallInteger
    • string
    • text
    • time
    • unsignedBigInteger
    • unsignedInteger
    • unsignedSmallInteger
    • uuid
  • 公式ドキュメントに記載されている内容を元に自分なりにまとめてみる。

概要

  1. ライブラリのインストール
  2. マイグレーションファイルの作成と記載
  3. マイグレート
  4. 確認

詳細

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

    1. アプリ名ディレクトリで下記コマンドを実行してライブラリをインストールする。

      $ composer require doctrine/dbal
      
  2. マイグレーションファイルの作成と記載

    1. アプリ名ディレクトリで下記コマンドを実行してマイグレーションファイルを作成する。(下記のファイル名出なくても良い。自分がわかりやすいと思うものにする必要がある。)

      $ php artisan make:migration change_カラムタイプ変更するカラム名_既存カラムタイプ_to_変更後のカラムタイプ_on_所属テーブル名_table --table=所属テーブル名
      
    2. アプリ名ディレクトリで下記コマンドを実行してマイグレーションファイルを開く。

      $ vi database/migrations/YYYY_MM_DD_XXXXXX_change_カラムタイプ変更するカラム名_既存カラムタイプ_to_変更後のカラムタイプ_on_所属テーブル名_table
      
    3. マイグレーションファイルを下記の様に修正する。(public function up()にはマイグレーションにより実行したい処理(今回だとカラムタイプの変更)処理を記載する。public function down()にはロールバックで実行したい(カラムタイプを元に直す)処理)

      database/migrations/YYYY_MM_DD_XXXXXX_change_変更する前のカラム名_to_変更した後のカラム名_on_所属テーブル名_table.php
      <?php
      
      use Illuminate\Database\Migrations\Migration;
      use Illuminate\Database\Schema\Blueprint;
      use Illuminate\Support\Facades\Schema;
      
      class Rename対象カラム名変更前カラムタイプTo変更後カラムタイプOnテーブル名Table extends Migration
      {
          /**
           * Run the migrations.
           *
           * @return void
           */
          public function up()
          {
              Schema::table('テーブル名', function (Blueprint $table) {
                  //下記を追記する
                  $table->変更したいデータ型('カラム名')->change();
              });
          }
      
          /**
           * Reverse the migrations.
           *
           * @return void
           */
          public function down()
          {
              Schema::table('テーブル名', function (Blueprint $table) {
                  //下記を追記する
                  $table->今までのデータ型('カラム名')->change();
              });
          }
      }
      
  3. マイグレート

    1. アプリ名ディレクトリで下記コマンドを実行してマイグレートを実行する。

      $ php artisan migrate
      
  4. 確認

    1. 下記コマンドを実行してMySQLにターミナルからログインする。(MySQLのパスワードを忘れてしまった方はこちら→Mac ローカル環境の MySQL 8.0 のrootパスワードを忘れた時のリセット方法)

      $ mysql -u root -p
      
    2. 下記を実行してカラムタイプが変更されたことを確認する。

      mysql> show columns from DB.テーブル名;
      

メモ

  • stringからintだとできなかったけどstringからintegerの指定だといけるかも知れん。試してみて

参考文献

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