20201130のlaravelに関する記事は9件です。

まだJSで消耗してるの?LaravelのLivewireでSPA開発

タイトルで釣りました(1年ぶり2度目の犯行

煽ってごめんなさい
JavaScript大好きだよ(ホントダヨ)

はじめに

この記事は 弁護士ドットコム Advent Calendar 2020 の記念すべき1日目の記事です?

Livewireとは

こんなことを思った事はないだろうか、、
なぜ簡単なWebアプリケーションを作りたいだけなのにVueやReactを別で用意してJSを書かないといけないのか...
ワイはPHPerなんや...JSなんて書きたくないんや....

そんな贅沢な悩みを持つPHPerを解決に導くツールこそ Livewire なのだ!!

それっぽい説明

LivewireとはBlade(Laravelの標準Viewテンプレート)を用いて、JavaScriptを記述せずにSPAを実現できるライブラリのことです。
これまでの様にフロントエンドにVueやReactなどフレームワークを選定する必要がなくなり、
バックエンドはもちろんフロントエンドもLaravelだけで開発が可能になりました。

LivewireはLaravelの標準ライブラリではありません。
Laravelで認証機能を担う Jetstream を使用する際に、
View部分をLivewireかInertiaを選択する必要があるのでその際にLivewireを選択する。
または直接インストールして使用する方法があります。

自分で書いといてアレだけどピンとこないと思う

とはいえ実装方法

上記のどこにでも落ちてそうな説明ではいまいちイメージ出来ないと思うので、
公式のデモコードで実装方法を確認してみます。

デモコードの内容は 要素に名前を入力して一致した名前をリアルタイムで下に表示するというよくあるやつ

1l6nc-5wawf.gif

Userのテストデータが用意されている前提で進めます!

コンポーネント(ロジック部分)

従来の Controller の様に使用します。
Laravel知ってる人なら分かると思うけど、この辺は記述に変わったところはなく、
プロパティの $search の値を検索条件として、Usersテーブルの name に一致するデータをViewに返しているだけです。

App\Http\Livewire\SearchUsers.php
<?php

namespace App\Http\Livewire;

use Livewire\Component;
use App\Models\User;

class SearchUsers extends Component
{
    public $search = '';

    public function render()
    {
        return view('livewire.search-users', [
            'users' => User::where('name', $this->search)->get(),
        ]);
    }
}

コンポーネント(View部分)

View部分は 要素に wire:model="search" という記述以外変わったところはなさそう
ロジック部分から受け取った値 users から name のみを表示している。

resources/views/livewire/search-users.blade.php
<div>
    <input wire:model="search" type="text" placeholder="Search users..."/>

    <ul>
        @foreach($users as $user)
            <li>{{ $user->name }}</li>
        @endforeach
    </ul>
</div>

コンポーネントを呼び出す

最初から用意されている welcome.blade.php にて先ほど作成したコンポーネントを呼び出してみます! @livewire('search-users')の部分が該当部分です。

welcome.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Livewire</title>
    @livewireStyles
</head>
<body>
    @livewire('search-users')
    @livewireScripts
</body>
</html>

なんとこれだけで終わりです!
Laravel知ってる人なら簡単ですよね?

Livewireを使えばこんな事も簡単

welcome.blade.phpでコンポーネントを呼び出す前提でデモを実装しています。

1. ファイルアップロード

リアルタイムでファイルアップロード機能を実装したいなぁ
だけdなんだかんだでJSでAjax書いたりと色々大変だしなぁ...

Livewire なら WithFileUploads をuseしてstore()で保存するだけ!

chthl-cy304.gif

ロジック部分

UploadPhoto.php
<?php

namespace App\Http\Livewire;

use Livewire\Component;
use Livewire\WithFileUploads;

class UploadPhoto extends Component
{
    use WithFileUploads;

    public $photo;

    public function save()
    {
        $this->photo->store('photos');
    }
}

View部分

upload-photo.blade.php
<div>
    <input type="file" wire:model="photo">
    <button>Save Photo</button>
</div>

2. もっと読み込む

もっと読み込むってボタンを押したら非同期で一覧データを読み込むの作りたいなぁ
でもJS書くのめんどくさいなぁ...

Livewire なら wire:click でイベントを受け取って取得処理するだけで簡単

1wldn-0gui9.gif

ロジック部分

UploadPhoto.php
<?php

namespace App\Http\Livewire;

use Livewire\Component;
use App\Models\User;

class LoadMore extends Component
{
    public $amount = 5;

    public function load()
    {
        $this->amount += 5;
    }

    public function render()
    {
        return view('livewire.load-more', [
            'users' => User::take($this->amount)->get()
        ]);
    }
}

View部分

upload-photo.blade.php
<div>
    <table>
        <tr>
            <th>名前</th>
            <th>Email</th>
        </tr>
        @foreach ($users as $user)
            <tr>
                <td>{{ $user->name }}</td>
                <td>{{ $user->email }}</td>
            </tr>
        @endforeach
    </table>
    <button wire:click="load">もっと読み込む</button>
</div>

最初のデモと処理的な物はほとんど一緒なので詳細は省く

メリデメ

Livewireを使うメリット

  • 普段からLarvel使ってる人なら低い学習コストで実装できる
  • 簡単なwebアプリケーションの実装ならJSよりこっちの方が楽(な気がする)
  • JSのこと気にしないで書けるのは割とストレスフリー
  • マスコットが可愛い

Livewireを使うデメリット

  • Laravel知らない人には学習コストが高い
  • Laravel依存ライブラリなので改修する時のコストが高そう
  • JSのフレームワークの様に知識的な汎用性に欠ける
  • 記事が少ないので詰まる ≒ 死

所感

多分複雑なことをやろうとすると結局は内部で使用している Alpine.js を使うことになると思うの...
PHPerの理想郷はまだ先なのかもしれない...。

最後に

弁護士ドットコムでは Livewire を使う予定は皆無だけど
一緒に働く仲間を募集しています?‍?

弁護士ドットコム株式会社 エンジニア採用情報


12/02 はReactといえばの「プログラミングをするパンダ」さんの担当日です
弁護士ドットコムライブラリーのフロントエンドのアーキテクチャ(Next.js + TypeScript)

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

【SQL】SQL大量発行 パフォーマンス向上

実現したいこと

今回は、SQLで1日毎30日間のデータを取得した時に、大量のクエリが発行された(30個程)ため、パフォーマンスが下がってしまった。可能な限りクエリの発行数を少なくしていきたいと思います。

なぜ大量にクエリ発行されるとパフォーマンスがよくないのか

SQLが大量に発行されるということは、例えば、レジでガムを10個買うときに、1個ずつレジで会計するくらい効率が悪いです。

現状

下記に示したコードより、for文で30回回しているため、パフォーマンスはかなり悪いです。一回毎にSQLが発行される仕組みになっています。計測したところ0.744秒でした。

 $time_start = microtime(true);
        for ($i = 0; $i < 30; $i++) {
            $daily = date('Y/m/d', strtotime("-{$i} day"));
         $projectPerDayCount = Project::whereDate('created_at', '=', $daily)->count();
        }
 dd(microtime(true) - $time_start);

そこで、パフォーマンス向上のため2つの方法を試してみました。

パート1 クエリービルダーで実行

クエリービルダーを用いて一括で取得する方法。
whereYear、whereMonthなど便利なメソッドを用いて、更にはcreated_atでは時間指定しなければいけないため、
Carbon::createFromFormaでformatをY-m-d H:i:s->Y-m-dに変換し、mapメソッドでその日のデータをカウントするなどの方法を使い実現しました。結果は、0.193秒の速さで、クエリー数は元の30->1回になりました。

  $time_start = microtime(true);
        $year = date('Y');
        $month = date('m');
        $projectPerDayCount = Project::whereYear('created_at', $year)
        ->whereMonth('created_at', $month)
        ->orderBy('created_at')
        ->get()
        ->groupBy(function ($row) {
            return Carbon::createFromFormat('Y-m-d H:i:s', $row->created_at)->format('Y-m-d');
        })
        ->map(function ($day) {
            return $day->count();
        });
    dd(microtime(true) - $time_start);


パート2 直接SQLを書いて実行


直接SQLを書くことで、クエリーは1回に発行で、処理の速さはなんと0.036秒になりました。20倍近く処理が早くなりました。
     $sql = "SELECT DATE_FORMAT(created_at, '%Y/%m/%d') as date, count(*) as count ";
      $sql .= " FROM projects";
      $sql .= " WHERE YEAR(created_at) = ? AND MONTH(created_at) = ?";
      $sql .= " group by DATE_FORMAT(created_at, '%Y/%m/%d')";
      $result = DB::select($sql, [$year,$month]);
      $projectCountPerDay = [];
      foreach($result as $row) {
        $projectCountPerDay[$row->date] = $row->count;
      }
       return $projectCountPerDay;

まとめ

今回のように、ループでSQLを書いてしまうとパフォーマンスが落ちてしまいます。
「N+1問題」と検索をかけるとSQLの大量クエリ発行について詳しく調べることができます。
今回の検証では直接SQLを書くことで、20倍近く処理が速くなることがわかりました。

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

【環境構築メモ】docker × Laravel 開発環境構築(Laradock使用)

はじめに

Laravelでの開発環境を構築する際の手順をまとめました。
今回は、laradockを使ってみたかったので、laradockを使用して環境構築します。

※ laradockとは? http://laradock.io/

  1. Laravel(PHP)のプロジェクトをDocker上で動作させるためのワンダフルな環境
  2. Dockerを用いてlaravelの環境を作るために必要なものがほぼ全てパッケージ化されている
  3. PHP, nginx, MySQLやミドルウェア等、Laravelの実行に必要な環境が整っている。

前提環境

  • Windows 10 Professional
  • PHP7.3
  • Dockerインストール済み
  • gitインストール済み

ゴール

  • Laradockを使用して、Laravelの開発環境を構築する。
  • 開発環境としては、以下のような構成にします。
    • Laravel(Webアプリケーションフレームワーク)
    • mysql(DB)
    • nginx(Webサーバ)

手順

1. プロジェクトディレクトリを作成

  • 任意の場所にプロジェクトディレクトリを作成します。どこでもOK。
    $ mkdir todo-list

2. プロジェクトディレクトリに移動し、laradockをプロジェクトディレクトリ直下にclone

  • Githubからlaradockをcloneしてきます。cloneが終わると、プロジェクトディレクトリ直下に「laradock」というディレクトリが作成されます。
    $ git clone https://github.com/laradock/laradock.git

  • clone直後のプロジェクトディレクトリ階層: laradockディレクトリ下に色々入ってます

3. laradockディレクトリに移動し、「.env」ファイルを作成、編集

  • laradockディレクトリ直下の「env-example」ファイルをリネームして作成する
    • .envファイル = 環境設定ファイル
    • 設定ファイルのサンプルをベースに置き換える為、設定ファイルをコピーしておく。
      $ cd laradock/ $ cp env-example .env

3-1. envファイルの設定

  • .envファイル内の値を編集していきます。

【設定詳細】

I. envファイル内の「APP_CODE_PATH_HOST」の値を変更

  5 ### Paths #################################################
  6
  7 # Point to the path of your applications code on your host
  8 APP_CODE_PATH_HOST=../todo-app
  9

↑上記記述で、「todo-list/todo-app/」下の階層がアプリケーションのコードを格納するディレクトリとみなされるようになる。

  • 2020年11月時点では.envファイルに書いてあるPHPのバージョンは「7.3」でした。

    • PHP_VERSION=7.3
  • mysqlは「その時点の最新版」

    • MYSQL_VERSION=latest

4. docker-composeでコンテナを立ち上げる:nginx と mysqlを立ち上げ

  • laradockディレクトリに移動し、コマンドを実行。コンテナを起動します。
    $ docker-compose up -d nginx mysql
    ※初回起動は時間がかなり!!かかります。気長に待ちましょう。10分以上は間違いなくかかる!

  • docker-compose up でエラーが出たら、下記参考URLの内容を参照ください。
    https://qiita.com/blueray777/items/44e25dc04ed1ab5c4cc8

    ・Laradockのdocker-compose upで出会ったエラー達

  • コンテナの確認

$ docker-compose ps -a
           Name                          Command               State                                                                      Ports
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
laradock_docker-in-docker_1   dockerd-entrypoint.sh            Up      2375/tcp, 2376/tcp
laradock_mysql_1              docker-entrypoint.sh mysqld      Up      0.0.0.0:3306->3306/tcp, 33060/tcp
laradock_nginx_1              /docker-entrypoint.sh /bin ...   Up      0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp, 0.0.0.0:81->81/tcp
laradock_php-fpm_1            docker-php-entrypoint php-fpm    Up      9000/tcp
laradock_workspace_1          /sbin/my_init                    Up      0.0.0.0:2222->22/tcp, 0.0.0.0:3000->3000/tcp, 0.0.0.0:3001->3001/tcp, 0.0.0.0:4200->4200/tcp, 0.0.0.0:8001->8000/tcp, 0.0.0.0:8080->8080/tcp

5. Laravelプロジェクトの作成

  • コンテナ起動後は、コンテナ内に入ってLaravelプロジェクトを生成します。
    laradockはworkspaceという全ての操作が可能なコンテナが用意されるので、ここから操作していきます。

  • コンテナ内に入る(laradockユーザー/rootユーザー)
    $ winpty docker-compose exec --user=laradock workspace bash
    $ winpty docker-compose exec --user=root workspace bash

    - Laradockに入れた時の表示
    laradock@fb36cc3540cd:/var/www$

  • Laravelプロジェクトのダウンロード
    • コンテナに入ったら/var/www配下にいますので、composerを使用してプロジェクトを生成します。
      laradock@fb36cc3540cd:/var/www$ composer create-project laravel/laravel todo-app ※ダウンロードに時間かかる

6. プロジェクトの生成確認

  • http://localhost/ にブランチからアクセス確認

    • Laravelのデフォルト画面が出ることを確認
  • 404 Not Foundが表示された場合

    • 3-1. envファイルの設定 で、.envファイルの「APP_CODE_PATH_HOST」のみ変更しましたが、「APP_CODE_PATH_CONTAINER」のパスも変更する必要がありました。(共有ディレクトリのマウント設定)
  5 ### Paths #################################################
  6
  7 # Point to the path of your applications code on your host
  8 APP_CODE_PATH_HOST=../todo-app
  9
 10 # Point to where the `APP_CODE_PATH_HOST` should be in the container
 11 APP_CODE_PATH_CONTAINER=/var/www/todo-app
  • nginxのroot変更
    • nginxの設定を変更します。ドキュメントルートを変更(13行目:root 以下のパスを変更)
$ vi nginx/sites/default.conf

  1 server {
  2
  3     listen 80 default_server;
  4     listen [::]:80 default_server ipv6only=on;
  5
  6     # For https
  7     # listen 443 ssl default_server;
  8     # listen [::]:443 ssl default_server ipv6only=on;
  9     # ssl_certificate /etc/nginx/ssl/default.crt;
 10     # ssl_certificate_key /etc/nginx/ssl/default.key;
 11
 12     server_name localhost;
 13     root /var/www/todo-app/public;
 14     index index.php index.html index.htm;
  • envファイル変更後は、コンテナを再起動してください。
    $ docker-compose stop $ docker-compose up -d nginx mysql

まとめ

  • ここまでで、laradock環境で構築したLaravelの初期画面表示ができるようになりました。 プロジェクトディレクトリの階層はこんな感じです。
  todo-list/
      | todo-app/
      └ laradock/

todo-appディレクトリ配下には、Laravelの各種ソースが格納されています。
dockerの知識や、Nginx等のインフラ知識がなくても、ここまではすんなりとこれるのではないかと思います。次の記事では、今回構築したLaravel開発環境をベースに、簡単なWebアプリケーションを構築して実行してみたいと思います。

次回!

  • DB設定
  • テーブルを作成、データ投入→ DBのデータを画面(ビュー)で一覧表示させてみる。

参考にしたサイト

Laravelで簡単なページを作成するまで https://qiita.com/tasogarei/items/1e0a3577a9fae7e519ba

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

LaravelとPHPWordを使って、年賀状の宛名面を出力してみた。

PHP(Laravel)を使って、Wordファイルを出力する記事です。

わざわざLaravelとphpwordを使ってはがき宛名面の作成は実用性低いですが、
この手順は報告書の自動作成などに応用できます。

ちなみに、年賀状の宛名面がテーマなのはただの思いつきで決めました。

動作環境
・Windows10
・XAMPP
・Word 2016

開発環境
・Laravel 6

1.Laravelインストール

Composerを利用してLaravelのインストールを行います。
プロジェクトのフォルダに移動して、下記コマンドを実行します。


$ composer create-project "laravel/laravel=6.0.*" project

Composerを利用して、phpwordをインストールします。

$ composer require phpoffice/phpword

2.マイグレーションファイルを作成します。

$ php artisan make:migration create_addresses_table --create=addresses
"2020_11_09_134553_create_addresses_table.php"
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateAddressesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('addresses', function (Blueprint $table) {
            $table->increments('id');
            $table->timestamps();
            $table->string('zipcode', 7);
            $table->string('name', 50);
            $table->string('prefecture', 30);
            $table->string('city', 30);
            $table->string('town', 100);
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('addresses');
    }
}

3.モデルを作成します。

$ php artisan make:model Address

4.コントローラーを作成します。

$ php artisan make:controller TestController

5.シーダーを作成します。

$ php artisan make:seeder AddressTableSeeder
”AddressTableSeeder.php”
<?php

use Illuminate\Database\Seeder;

class AddressTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        DB::table('addresses')->insert([
            [
                'zipcode' => '1430002',     //郵便番号
                'prefecture' => '東京都',   //都道府県
                'city' => '大田区',         //市区町村
                'town' => '城南島六ー二ー一 カーム城南島 一〇〇六号室',      //町域
                'name' => '高野彦好',       //名前
            ],
            [
                'zipcode' => '1730003',     //郵便番号
                'prefecture' => '東京都',   //都道府県
                'city' => '板橋区',         //市区町村
                'town' => '加賀二ー二ー九',      //町域
                'name' => '米田政広',       //名前
            ],
            [
                'zipcode' => '1940204',     //郵便番号
                'prefecture' => '東京都',   //都道府県
                'city' => '町田市',         //市区町村
                'town' => '小山田桜台一ー一三ー八 アスコットヴィラ小山田桜台 二一二',    //町域
                'name' => '溝口為一郎',     //名前
            ],
            [
                'zipcode' => '1300025',     //郵便番号
                'prefecture' => '東京都',   //都道府県
                'city' => '墨田区',         //市区町村
                'town' => '千歳二ー七ー七五',       //町域
                'name' => '小倉真紀子',     //名前
            ],
            [
                'zipcode' => '2060041',     //郵便番号
                'prefecture' => '東京都',   //都道府県
                'city' => '多摩市',         //市区町村
                'town' => '愛宕五ー二ー九',      //町域
                'name' => '吉井孝市',       //名前
            ]
        ]);
    }
}

6.マイグレーションとシードを同時に実行します。

$ php artisan migrate:fresh --seed

7.Viewのレイアウトファイルを作る

”base.blade.php”
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  <title>アプリケーション名</title>
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
</head>

<body>
  <nav class="navbar navbar-expand-lg navbar-light bg-light">
    <a class="navbar-brand" href="#">テスト</a>
  </nav>

@yield('content')

    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>

</html>

8.ルーティングの設定をする

web.php
Route::group(['prefix' => 'test'], function() {
    Route::get('index','TestController@index');
    Route::post('word_inport','TestController@word_inport');
    Route::get('word_inport','TestController@word_inport');
});

9.コントローラーの設定をする。

今回は、phpwordのテンプレートプロセッサを利用してdocxファイル出力をする。

"TestController.php"
<?php

namespace App\Http\Controllers;

use App\Address;

use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\IOFactory;
use PhpOffice\PhpWord\TemplateProcessor;

use Illuminate\Http\Request;

class TestController extends Controller
{
    //
    public function index(){
        $addresses = Address::all();

        return view('index',['addresses' => $addresses]);
    }

    public function word_inport(Request $request){
        $addresses = Address::find($request->id);

        $templateprocessor = new TemplateProcessor('./template/template.docx');
        $templateprocessor->setValue('zipcode',$addresses->zipcode);
        $templateprocessor->setValue('prefecture',$addresses->prefecture);
        $templateprocessor->setValue('city',$addresses->city);
        $templateprocessor->setValue('town',$addresses->town);
        $templateprocessor->setValue('name',$addresses->name);

        $templateprocessor->saveAs($addresses->name.'様宛名.docx');
        return response()->download($addresses->name.'様宛名.docx')->deleteFileAfterSend(true);
    }
}

10.一覧画面を作る

"index.blade.php"
@extends('base')
@section('title', 'テスト')

@section('content')
<div class="container">
    <div class="table_position">
        <table class="table table-bordered">
            <thead>
                <tr>
                    <th>ID</th>
                    <th>郵便番号</th>
                    <th>都道府県</th>
                    <th>市区町村</th>
                    <th>町域</th>
                    <th>名前</th>
                    <th></th>
                </tr>
            </thead>
            <tbody class="table">
            @foreach($addresses as $address)
                <tr>
                    <td>{{ $address->id }}</td>
                    <input type="hidden" value="{{ $address->id }}" name="id">
                    <td>{{ $address->zipcode }}</td>
                    <input type="hidden" value="{{ $address->zipcode }}" name="zipcode">
                    <td>{{ $address->prefecture }}</td>
                    <input type="hidden" value="{{ $address->prefecture }}" name="prefecture">
                    <td>{{ $address->city }}</td>
                    <input type="hidden" value="{{ $address->city }}" name="city">
                    <td>{{ $address->town }}</td>
                    <input type="hidden" value="{{ $address->town }}" name="town">
                    <td>{{ $address->name }}</td>
                    <input type="hidden" value="{{ $address->name }}" name="name">
                    <th><a href="{{ action('TestController@word_inport', ['id' => $address->id]) }}" class="btn btn-primary">Word出力</a></th>
                </tr>
            @endforeach
            </tbody>
        </table>
    </div>
</div>
@endsection

11.テンプレートファイルを置く

Wordで、宛名面のテンプレートファイルを使って図のように編集する。
注意:宛名印刷テンプレートが利用できるのは、Windows版のWordのみです。
Mac版の場合は、ご自身でテンプレートファイルを探してください。

スクリーンショット 2020-11-29 201401.PNG

編集したものは、project\public\templateに置く
(ここでは、ファイル名はtemplate.docxになっている。)

動作確認をしてみる。

http://localhost:8000/test/indexを開き、Word出力のボタンを押す。

スクリーンショット 2020-11-29 204843.PNG

ダウンロードされたWordファイルを開く。

スクリーンショット 2020-11-29 204949.PNG

以上で、Laravelとphpwordを用いてのテンプレート出力が完了です。

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

Laravel 6.xでredisをセッションサーバーとして使えるようにする

Laravel 6.x でセッションサーバーとしてredisを使おうとして、インストールや設定に少し手間取ったので、備忘録としての記録です。

環境

ubuntu 18.04
Laravel 6.20.x

前提条件

php-fpm, redisはインストール済み

インストール

まずは、peclをインストールしましょう。php-pearに含まれます。
そして、peclからphpredisのインストールです。

predisでも動作しますが、今回は公式で推奨されるphpredisをインストールしたいと思います。

6.x 日本語ドキュメント

LaravelでRedis使用するには、PECLを使用してPhpRedis PHP拡張をインストールすることを推奨します。インストール方法は複雑ですが、Redisをヘビーユースするアプリケーションではより良いパフォーマンスが得られます

## peclのインストール
sudo apt install php-pear

## phpredisのインストール
sudo pecl install redis

php.iniの修正

extensionの追加。
追加後、php-fpmは再起動してください。

/etc/php/7.x/fpm/php.ini
extension=redis

Laravelの設定

各設定の変更

.env
SESSION_DRIVER=redis #fileから変更
config/database.php
# redisのクライアントがphpredisになっているか確認
'redis' => [
    'client' => env('REDIS_CLIENT', 'phpredis'),

確認

webページを開いてみると、redisがセッションサーバーとして機能してるのが分かると思います。

$ redis-cli
> keys *
1) "sample_database_cache:AIn7Io8yHuhTolvAJhk5ITLdMsqXL1FqsuOTSDBl"
> get ample_database_cache:AIn7Io8yHuhTolvAJhk5ITLdMsqXL1FqsuOTSDBl
"s:198:\"a:3:{s:6:\"_token\";s:40:\"FBn1BGQlMBUXXMQBI2SDDBuvKIr31YTAyOo4X20L\";s:6:\"_flash\";a:2:{s:3:\"old\";a:0:{}s:3:\"new\";a:0:{}}s:9:\"_previous\";a:1:{s:3:\"url\";s:40:\"https://sample.com/xxx\";}}\";"
> 
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel 6.x 非同期通信(Ajax) 【JavaScript】 【jQuery】 【axios】 【Vue.js】 各記述方法 ~jQuery × FetchAPI編~

制作環境

Windows 10
Laravel : 6.18.35
Laravel/ui : 1.0
Laravel-mix : 5.0.1
Bootstrap : 4.0.0
axios : 0.19
Vue : 2.5.17
XAMPP
PHP : 7.4.3
Visual Studio Code

はじめに

この記事はプログラミングをはじめたばかりの素人が、できたことをメモするのに利用しています。
内容には誤りがあるかもしれません。

前回のつづきになります。

関連記事

Laravel 6.x 非同期通信(Ajax) 【JavaScript】 【jQuery】 【axios】 【Vue.js】 各記述方法 ~事前準備編~
Laravel 6.x 非同期通信(Ajax) 【JavaScript】 【jQuery】 【axios】 【Vue.js】 各記述方法 ~JavaScript編~
Laravel 6.x 非同期通信(Ajax) 【JavaScript】 【jQuery】 【axios】 【Vue.js】 各記述方法 ~jQuery編~
Laravel 6.x 非同期通信(Ajax) 【JavaScript】 【jQuery】 【axios】 【Vue.js】 各記述方法 ~JavaScript × axios編~
Laravel 6.x 非同期通信(Ajax) 【JavaScript】 【jQuery】 【axios】 【Vue.js】 各記述方法 ~jQuery × axios編~
Laravel 6.x 非同期通信(Ajax) 【JavaScript】 【jQuery】 【axios】 【Vue.js】 各記述方法 ~Vue.js × axios編~
Laravel 6.x 非同期通信(Ajax) 【JavaScript】 【jQuery】 【axios】 【Vue.js】 各記述方法 ~JavaScript × FetchAPI編~

今回作成するもの

FetchAPIを利用し非同期通信を行い、自動で仕入れ先が入力される機能を実装します。

以下作成条件

  • 基本的な記述にはjQueryを使用し通信にはFetchAPIを使用します。
  • 数字が4桁入力されたら自動で仕入れ先を検索し、反映します。
  • 検索するのにクリック操作を必要としません。inputに入力されたら検索します。
  • スクリプトの読み込みにはLaravel-mixを使用します。
  • 前回作成したtest.jsを編集して使用するで、必要ならtest6.js等コピーを作成してバックアップしてください。

スクリプトの作成

resources>js内のtest.jsを開き、以下のように記述します。
※前回作成した内容は全て削除してください。

test.js
// ここから先はjQuery編と変わらないため、詳細は割愛します
$(function() {
    $('#code').on('input', function() {
        let traderCode = $('#code').val();

        if (traderCode.length < 4) {
            return;
        }

        let url = 'form_search?trader_code=' + traderCode;
// ここまでjQuery編と変わらない

        // ここから先はJavaScript × FetchAPI編と変わらないため、詳細は割愛します
        fetch(url).then(response => response.json())
            .then(data => {
        // ここまでJavaScript × FetchAPI編と変わらない
                // 受け取ったデータ(検索結果)を仕入れ先のvalueに反映します 
                $('#supplier').val(data[0].trader_name);
            })
    })
})

コンパイル

ターミナルを起動し、以下を実行してください。
※node.jsが必要です。インストールされていない方は、インストールを行ってください。

node.js
https://nodejs.org/ja/

npm run dev

動作確認

コンパイルまで完了したら動作を確認してください。
問題無く業者名が表示されればOKです。

以上で終了です。
お疲れさまでした。

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

【PHP Laravel】コントローラへのルーティングが上手くいかない

この記事は、「PHPフレームワーク Laravel入門」を使用して勉強した時につまった所になります。

目次

  • バージョン情報
  • コントローラへのルーティングが上手くいかなかった
    • 解決策1
    • 解決策2
    • 参考サイト

バージョン情報

バージョン
PHP 7.4.9
Laravel 8.16.1

コントローラへのルーティングが上手くいかなかった

書籍に倣って以下のようにコーディングした。

Route::get('hello', 'helloController@index');

実行すると以下のようなエラーが出てきた。

キャプチャ.JPG

以下のような変更をしたら実行できた。

解決策1

use App\Http\Controllers\HelloController;

Route::get('hello', [HelloController::class,'index']);

解決策2

artisanコマンドでRoute情報を確認する。

php artisan route:list

+--------+----------+------------+------+---------------------------------------------+------------+
| Domain | Method   | URI        | Name | Action                                      | Middleware |
+--------+----------+------------+------+---------------------------------------------+------------+
|        | GET|HEAD | /          |      | Closure                                     | web        |
|        | GET|HEAD | api/user   |      | Closure                                     | api        |
|        |          |            |      |                                             | auth:api   |
|        | GET|HEAD | hello      |      | App\Http\Controllers\HelloController@index  | web        |
+--------+----------+------------+------+---------------------------------------------+------------+

Actionの所がApp\Http\Controllers\HelloController@indexとなっていたので、
Route::getを以下のように変更。

Route::get('hello', 'App\Http\Controllers\HelloController@index');

参考サイト

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

[PHP] エラー解決 gyp: No Xcode or CLT version detected!

laravelに必要なnpmをインストールをすると

gyp: No Xcode or CLT version detected!

というエラーが出たのでそれの解決方法を投稿いたします。
今回はXcodeというAPPをアンインストールをして解決した方法になります。
下記はエラー画面のスクショになります。
“スクリーンショット” 2020-11-30 12.03.07.jpg

解説

gyp: No Xcode or CLT version detected!
これは「XcodeとCLTのバージョンがおかしい」というエラー内容でした。
私自身、Xcodeは暫く使うことはないのでアンインストールを実行したいと思います。

//ターミナルにて上から一つずつ実行する
sudo rm -rf /Applications/Xcode.app
sudo rm -rf /Library/Preferences/com.apple.dt.Xcode.plist
sudo rm -rf ~/Library/Preferences/com.apple.dt.Xcode.plist
sudo rm -rf ~/Library/Caches/com.apple.dt.Xcode
sudo rm -rf ~/Library/Application Support/Xcode
sudo rm -rf ~/Library/Developer/Xcode
sudo rm -rf ~/Library/Developer/CoreSimulator

無事にアンインストールはできました。しかし、npm installを実行すると

(省略)
found 2 vulnerabilities (1 low, 1 high)
  run `npm audit fix` to fix them, or `npm audit` for details
(省略)

という脆弱性が見つかりました。次回にて脆弱性が問題なのでこちらも投稿します。
次の記事のURLはこちらになります。

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

Laravel 6.x 非同期通信(Ajax) 【JavaScript】 【jQuery】 【axios】 【Vue.js】 各記述方法 ~JavaScript × FetchAPI編

制作環境

Windows 10
Laravel : 6.18.35
Laravel/ui : 1.0
Laravel-mix : 5.0.1
Bootstrap : 4.0.0
axios : 0.19
Vue : 2.5.17
XAMPP
PHP : 7.4.3
Visual Studio Code

はじめに

この記事はプログラミングをはじめたばかりの素人が、できたことをメモするのに利用しています。
内容には誤りがあるかもしれません。

前回のつづきになります。

関連記事

Laravel 6.x 非同期通信(Ajax) 【JavaScript】 【jQuery】 【axios】 【Vue.js】 各記述方法 ~事前準備編~
Laravel 6.x 非同期通信(Ajax) 【JavaScript】 【jQuery】 【axios】 【Vue.js】 各記述方法 ~JavaScript編~
Laravel 6.x 非同期通信(Ajax) 【JavaScript】 【jQuery】 【axios】 【Vue.js】 各記述方法 ~jQuery編~
Laravel 6.x 非同期通信(Ajax) 【JavaScript】 【jQuery】 【axios】 【Vue.js】 各記述方法 ~JavaScript × axios編~
Laravel 6.x 非同期通信(Ajax) 【JavaScript】 【jQuery】 【axios】 【Vue.js】 各記述方法 ~jQuery × axios編~
Laravel 6.x 非同期通信(Ajax) 【JavaScript】 【jQuery】 【axios】 【Vue.js】 各記述方法 ~Vue.js × axios編~
Laravel 6.x 非同期通信(Ajax) 【JavaScript】 【jQuery】 【axios】 【Vue.js】 各記述方法 ~jQuery × FetchAPI編~

今回作成するもの

FetchAPIを利用し非同期通信を行い、自動で仕入れ先が入力される機能を実装します。

以下作成条件

  • 基本的な記述にはJavaScriptを使用し通信にはFetchAPIを使用します。
  • 数字が4桁入力されたら自動で仕入れ先を検索し、反映します。
  • 検索するのにクリック操作を必要としません。inputに入力されたら検索します。
  • スクリプトの読み込みにはLaravel-mixを使用します。
  • 前回作成したtest.jsを編集して使用するで、必要ならtest5.js等コピーを作成してバックアップしてください。
  • app.jsを変更するので、Vue.jsの記述を残す場合はapp2.js等コピーを作成してバックアップしてください。

app.jsの修正

resources>js内のapp.jsを開き、require('./bootstrap');の下に以下を記述してください。

app.js
require('./test');

更に、Vueの記述を以下のように戻してください。

app.js
const app = new Vue({
    el: '#app',

    data() {
        return {

        }

    },
})

スクリプトの作成

resources>js内のtest.jsを開き、以下のように記述します。
※前回の内容は全て削除してください。

test.js
// ここから先はJavaScript編と同じ内容のため、詳細は割愛します
window.onload = function() {

    document.getElementById('code').addEventListener('input', function() {
        let traderCode = document.getElementById('code').value;

        if (traderCode.length < 4) {
            return;
        }

        let url = 'form_search?trader_code=' + traderCode;
// ここまでJavaScript編と同じ

        // FetchAPIを使用し非同期通信を行います
        // 引数にアクセス先のURLを渡します
        // デフォルトでGET接続のため、第二引数には何も渡しません
        // .then()で通信成功時の処理を記述します
        // 以降は別途記載します
        fetch(url).then(response => response.json())
            .then(data => {
                // この処理はJavaScript編と同じです
                document.getElementById('supplier').value = data[0].trader_name;
            })
    })

}

.then(response => response.json())

FechAPIはPromiseオブジェクトを返り値として渡します。
そのままでは使いづらいので、ResponseオブジェクトJson()メソッドを使用し、JSON形式で返すように指定します。

FechAPIの返り値サンプル

promise.jpg

.then(data => {

上のJSON形式の内容を、引数に入れた変数に代入できます。
ここではdataとしていますが、変数名は何でもかまいません。

console.log(data);の値サンプル

data.jpg

コンパイル

Laravel-mixで読み込ませるためにコンパイルを行います。

ターミナルを起動し、以下を実行してください。
※node.jsが必要です。インストールされていない方は、インストールを行ってください。

node.js
https://nodejs.org/ja/

npm run dev

確認

動作の確認を行ってください。
問題無く検索結果が反映されればOKです。

FetchAPIのデメリット

古いブラウザーに対応できないというデメリットがあります。
IEやSafariには対応できません。
対応させる場合GitHubのFetch polyfillが必要です。

以上です。
次回に続く。

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