さゆフィクション http://it.kensan.net/it aws wordpress などなどゆるーく書いてます Sat, 12 Oct 2024 03:36:51 +0000 ja hourly 1 https://wordpress.org/?v=6.5.2 https://it.kensan.net/wp-content/uploads/2023/03/cropped-icon-32x32.png さゆフィクション http://it.kensan.net/it 32 32 PHPバージョンアップの際はPHPComptibilityで静的解析をしてエラーと警告を見つけよう https://it.kensan.net/php%e3%83%90%e3%83%bc%e3%82%b8%e3%83%a7%e3%83%b3%e3%82%a2%e3%83%83%e3%83%97%e3%81%ae%e9%9a%9b%e3%81%afphpcomptibility%e3%81%a7%e9%9d%99%e7%9a%84%e8%a7%a3%e6%9e%90%e3%82%92%e3%81%97%e3%81%a6%e3%82%a8.html Sat, 12 Oct 2024 03:33:03 +0000 https://it.kensan.net/?p=2156 PHPバージョンアップの際はPHPComptibilityで静的解析をしてエラーと警告を見つけられるそうです。全部見つけられるわけではないと思いますが、PHPComptibilityで静的解析した方が安心かと思います。

ということでPHPComptibilityを試しにやってみます。

ローカルのPHP実行環境で、PHPComptibilityを動かす感じになりますが、ローカル環境がない場合は、以下のURLをご参照ください。

 

PHPプログラムのコンテナローカル開発環境を最短で立ち上げる簡単な方法(apache×php×mysql)
PHPプログラムのコンテナローカル開発環境を簡単に最短で立ち上げます! 以下を使います! apache htaccess有効な状態 ドキュメントルートの設定は.htaccessで行います! php バージョン8.3 mysql バージョン8...

PHPComptibilityで静的解析してみる

PHPComptibilityのインストール

以下のコマンドでインストールできます。

composer require --dev phpcompatibility/php-compatibility dev-develop

実際に静的解析してみる!!

以下の警告・エラーが出ない想定のプログラムに対して、静的解析してみます!


<?php
print"aaaa";
静的解析実行コマンドは以下です。「/index.php」で解析対象のファイルを指定します。
上記の解析対象のプログラムをindex.phpで作成したので、今回は「/index.php」を指定しています。
現在のディレクトリ配下全てを解析したい場合は「.」を指定することで、ディレクトリ配下全ての解析ができます。
./vendor/bin/phpcs -p ./index.php --standard=PHPCompatibility --runtime-set testVersion 8.3 -d memory_limit=1024M --report-full=8.3_report.txt

解析結果は「8.3_report.txt」に吐き出すようにしています。

上記実行結果、エラー・警告はないため、「8.3_report.txt」はカラでした。

次に警告が出るPHPファイルを上記と同様、index.phpというファイルに作成して解析してみます。

<?php
print"aaaa";

# 8.3非推奨
class foo {
    function name()
    {
        echo "My name is " , get_class() , "\n";
    }
}

以下のコマンドで再度、静的解析してみます。

./vendor/bin/phpcs -p ./index.php --standard=PHPCompatibility --runtime-set testVersion 8.3 -d memory_limit=1024M --report-full=8.3_report.txt

解析結果は以下です。

想定通り、1つ警告が出ました。


FILE: /var/www/html/index.php
--------------------------------------------------------------------------------
FOUND 0 ERRORS AND 1 WARNING AFFECTING 1 LINE
--------------------------------------------------------------------------------
 8 | WARNING | Calling get_class() without the $object argument is deprecated
   |         | since PHP 8.3.
--------------------------------------------------------------------------------


 

今度はさらにエラーが出るPHPソースをindex.phpに追加して、解析してみます。

解析対象のソースは以下です。

<?php
print"aaaa";

# 8.3非推奨
class foo {
    function name()
    {
        echo "My name is " , get_class() , "\n";
    }
}

# 8.0削除
implode([1,2,3], ',');

以下のコマンドで解析します。

./vendor/bin/phpcs -p ./index.php --standard=PHPCompatibility --runtime-set testVersion 8.3 -d memory_limit=1024M --report-full=8.3_report.txt

解析結果は以下の通りになりました。


FILE: /var/www/html/index.php
--------------------------------------------------------------------------------
FOUND 1 ERROR AND 1 WARNING AFFECTING 2 LINES
--------------------------------------------------------------------------------
  8 | WARNING | Calling get_class() without the $object argument is deprecated
    |         | since PHP 8.3.
 13 | ERROR   | Passing the $glue and $pieces parameters in reverse order to
    |         | implode has been deprecated since PHP 7.4 and is removed since
    |         | PHP 8.0; $glue should be the first parameter and $pieces the
    |         | second
--------------------------------------------------------------------------------

想定通り、1つエラーがつかされましたが出ました。

まとめ

簡単にPHPComptibilityで静的解析ができました。

PHPバージョンアップの際はPHPComptibilityで静的解析した方が安心かと思います!!

]]>
vue.jsでAdmin LTEコンポーネントを使って爆速で画面開発する https://it.kensan.net/vue-js-admin-lte.html Sat, 12 Oct 2024 02:42:19 +0000 https://it.kensan.net/?p=2153 vue.jsでAdmin LTEコンポーネントを使ってみます。

Admin LTEコンポーネントを使わせてもらった方が効率的だよね?という考えです。

開発環境は構築済みのものとして進めますので、まだの場合は以下URLを参考にしてくださいー

 

 

vue.jsをDockerコンテナ上でローカル開発できるようにする
vue.jsをDockerコンテナ上でローカル開発できるようにしてみます! 以下の流れで進めていきます docker-compose.yml作成 Dockerfile作成 コンテナ起動 コンテナ内でvueプロジェクト作成 サーバ起動 では早...

 

vue.jsでAdmin LTEコンポーネントを使う

Admin LTEのインストールをする

vue.jsのプロジェクトにAdmin LTEをインストールします。

以下のコマンドを実行すればOKです。

npm install admin-lte@^3.2 bootstrap jquery popper.js -save

ソースコードを修正する

ソースコードを修正して、Admin LTEを使ってみます。

main.jsの修正

以下のように修正します。こちらは共通設定のため、初回の1回のみ必要な修正です。

<ファイル名>

main.js

<ファイルの中身>


import { createApp } from 'vue'
import App from './App.vue'

import 'admin-lte/dist/css/adminlte.min.css';
import 'admin-lte/dist/js/adminlte.min.js';
import 'bootstrap/dist/css/bootstrap.min.css';
import 'bootstrap/dist/js/bootstrap.bundle.min.js';

createApp(App).mount('#app');

画面表示用のコード(vueファイル)を修正してAdminLTEを使ってみます

試しに以下のヘッダーを実装してみます。

Main Header Component
AdminLTE v3.2 Documentation

<ファイル名>

App.vue

<ファイルの中身>

<template>
<!-- Navbar -->
<nav class="main-header navbar navbar-expand navbar-white navbar-light">
<!-- Left navbar links -->
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" data-widget="pushmenu" href="#" role="button"><i class="fas fa-bars"></i></a>
</li>
<li class="nav-item d-none d-sm-inline-block">
<a href="index3.html" class="nav-link">Home</a>
</li>
<li class="nav-item d-none d-sm-inline-block">
<a href="#" class="nav-link">Contact</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown2" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Help
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown2">
<a class="dropdown-item" href="#">FAQ</a>
<a class="dropdown-item" href="#">Support</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Contact</a>
</div>
</li>
</ul>

<!-- SEARCH FORM -->
<form class="form-inline ml-3">
<div class="input-group input-group-sm">
<input class="form-control form-control-navbar" type="search" placeholder="Search" aria-label="Search">
<div class="input-group-append">
<button class="btn btn-navbar" type="submit">
<i class="fas fa-search"></i>
</button>
</div>
</div>
</form>

<!-- Right navbar links -->
<ul class="navbar-nav ml-auto">
<!-- Messages Dropdown Menu -->
<li class="nav-item dropdown">
<a class="nav-link" data-toggle="dropdown" href="#">
<i class="far fa-comments"></i>
<span class="badge badge-danger navbar-badge">3</span>
</a>
<div class="dropdown-menu dropdown-menu-lg dropdown-menu-right">
<a href="#" class="dropdown-item">
<!-- Message Start -->
<div class="media">
<img src="dist/img/user1-128x128.jpg" alt="User Avatar" class="img-size-50 mr-3 img-circle">
<div class="media-body">
<h3 class="dropdown-item-title">
Brad Diesel
<span class="float-right text-sm text-danger"><i class="fas fa-star"></i></span>
</h3>
<p class="text-sm">Call me whenever you can...</p>
<p class="text-sm text-muted"><i class="far fa-clock mr-1"></i> 4 Hours Ago</p>
</div>
</div>
<!-- Message End -->
</a>
<div class="dropdown-divider"></div>
<a href="#" class="dropdown-item">
<!-- Message Start -->
<div class="media">
<img src="dist/img/user8-128x128.jpg" alt="User Avatar" class="img-size-50 img-circle mr-3">
<div class="media-body">
<h3 class="dropdown-item-title">
John Pierce
<span class="float-right text-sm text-muted"><i class="fas fa-star"></i></span>
</h3>
<p class="text-sm">I got your message bro</p>
<p class="text-sm text-muted"><i class="far fa-clock mr-1"></i> 4 Hours Ago</p>
</div>
</div>
<!-- Message End -->
</a>
<div class="dropdown-divider"></div>
<a href="#" class="dropdown-item">
<!-- Message Start -->
<div class="media">
<img src="dist/img/user3-128x128.jpg" alt="User Avatar" class="img-size-50 img-circle mr-3">
<div class="media-body">
<h3 class="dropdown-item-title">
Nora Silvester
<span class="float-right text-sm text-warning"><i class="fas fa-star"></i></span>
</h3>
<p class="text-sm">The subject goes here</p>
<p class="text-sm text-muted"><i class="far fa-clock mr-1"></i> 4 Hours Ago</p>
</div>
</div>
<!-- Message End -->
</a>
<div class="dropdown-divider"></div>
<a href="#" class="dropdown-item dropdown-footer">See All Messages</a>
</div>
</li>
<!-- Notifications Dropdown Menu -->
<li class="nav-item dropdown">
<a class="nav-link" data-toggle="dropdown" href="#">
<i class="far fa-bell"></i>
<span class="badge badge-warning navbar-badge">15</span>
</a>
<div class="dropdown-menu dropdown-menu-lg dropdown-menu-right">
<span class="dropdown-header">15 Notifications</span>
<div class="dropdown-divider"></div>
<a href="#" class="dropdown-item">
<i class="fas fa-envelope mr-2"></i> 4 new messages
<span class="float-right text-muted text-sm">3 mins</span>
</a>
<div class="dropdown-divider"></div>
<a href="#" class="dropdown-item">
<i class="fas fa-users mr-2"></i> 8 friend requests
<span class="float-right text-muted text-sm">12 hours</span>
</a>
<div class="dropdown-divider"></div>
<a href="#" class="dropdown-item">
<i class="fas fa-file mr-2"></i> 3 new reports
<span class="float-right text-muted text-sm">2 days</span>
</a>
<div class="dropdown-divider"></div>
<a href="#" class="dropdown-item dropdown-footer">See All Notifications</a>
</div>
</li>
<li class="nav-item">
<a class="nav-link" data-widget="control-sidebar" data-slide="true" href="#" role="button"><i
class="fas fa-th-large"></i></a>
</li>
</ul>
</nav>
<!-- /.navbar -->

</template>

<script>

export default {
name: 'App'
}
</script>

動作確認する

以下のようなヘッダーが表示されれば成功です。

 

まとめ

vue.jsでAdmin LTEコンポーネントが使えました!!

これから頑張って開発していきますーー

]]>
vue.jsをDockerコンテナ上でローカル開発できるようにする https://it.kensan.net/vue-local-container.html Sat, 12 Oct 2024 01:47:45 +0000 https://it.kensan.net/?p=2147 vue.jsをDockerコンテナ上でローカル開発できるようにしてみます!

以下の流れで進めていきます

  1. docker-compose.yml作成
  2. Dockerfile作成
  3. コンテナ起動
  4. コンテナ内でvueプロジェクト作成
  5. サーバ起動

では早速やってみます!

 

 

vue.jsのローカル開発環境構築

docker-compose.ymlファイル作成

 

<ファイル名>

docker-compose.yml

<ファイルの中身>


services:
  web:
    build: .
    image: vueweb
    volumes:
      - .:/app
    container_name: 'web'
    ports:
      - '8080:8080'
    tty: true

Dockerfile作成

<ファイル名>

Dockerfile

<ファイルの中身>


FROM node:22
RUN npm install -g @vue/cli
EXPOSE 8080

コンテナ起動

以下のコマンドでコンテナを立ちあげます

docker-compose up --build

コンテナ内でプロジェクト作成します

まず以下のコマンドでコンテナの中に入ります。

docker-compose exec web bash

次に以下のコマンドでプロジェクトを作成します。

vue create sample

サーバ起動

以下のコマンドでサーバ起動します。

cd sample && npm run serve

動作確認

以下のURLにブラウザからアクセスして画面表示されればOKです!

http://localhost:8080/

以下のような画面が表示されるはずですー

 

docker-compose.ymlの微調整

vueがコンテナ上で正常に動くようになりましたが、このままですと、コンテナ起動のたびにコンテナ内で「cd sample && npm run serve」を実行する必要があります。

これは面倒なので以下のように、docker-compose.ymlに「cd sample && npm run serve」を追加して、コンテナ起動時にサーバ起動するようにします。

修正後のファイルは以下のようになります。

<ファイル名>

docker-compose.yml

<ファイルの中身>


services:
  web:
    build: .
    image: vueweb
    volumes:
      - .:/app
    command: sh -c "cd sample && npm run serve"
    container_name: 'web'
    ports:
      - '8080:8080'
    tty: true

 

まとめ

vue.jsのローカル開発環境構築をして、vue.jsをコンテナ上で動かしてみました。

ここから本格的にvue.jsの開発をしていきます!!

]]>
PHPプログラムのコンテナローカル開発環境を最短で立ち上げる簡単な方法(apache×php×mysql) https://it.kensan.net/php_container_apache_mysql.html Thu, 10 Oct 2024 05:40:50 +0000 http://13.231.168.135/it/?p=2139 PHPプログラムのコンテナローカル開発環境を簡単に最短で立ち上げます!

以下を使います!

  • apache
    • htaccess有効な状態
      • ドキュメントルートの設定は.htaccessで行います!
  • php
    • バージョン8.3
  • mysql
    • バージョン8

必要なファイル作成

以下のファイルをphpファイルが格納されているフォルダの直下に作成します。

  • docker-compose
  • Dockerfile
  • .htaccess

docker-composeファイル

<ファイル名>

docker-compose.yml

<ファイルの中身>

version: '3'

services:
    php:
        build:
            # Dockerfileを格納するフォルダのパス
            context: .
            # Dockerfileのファイル名
            dockerfile: Dockerfile
        volumes:
            - .:/var/www/html
        ports:
            - 8000:80
        container_name: php8.3
    mysql:
        image: mysql:8.0
        volumes:
            - /var/lib/mysql
        environment:
            - MYSQL_ROOT_PASSWORD=root
            - MYSQL_DATABASE=test
            - MYSQL_USER=test
            - MYSQL_PASSWORD=test
        container_name: mysql8.0

mysqlはimageの指定箇所のバージョン変更することで別バージョンで立ち上げることも可能です。

Dockerfile

<ファイル名>

Dockerfile

<ファイルの中身>


FROM php:8.3-apache
# htaccess有効化
RUN  a2enmod rewrite
#composer install
COPY --from=composer /usr/bin/composer /usr/bin/composer

Fromの後のバージョンをいじることで、8.3以外のPHPを入れることも可能です。

composerは一応入れておきます。なくてもOK

.htaccess

<ファイル名>

.htaccess

<ファイルの中身>


RewriteEngine on
RewriteBase /
RewriteRule ^$ {ドキュメンルートへのパス} [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ {ドキュメンルートへのパス}$1 [L]

{ドキュメンルートへのパス}はご自身の環境に合わせてくださいー

動作確認

以下のコマンドでコンテナを立ち上げます。

docker compose up

以下のURLでPHPプログラムが想定通り動いていれば成功です!

http://localhost:8000/

ちなみに以下のコマンドでコンテナに入れます

docker compose exec php bash

まとめ

簡単に、PHPプログラムのコンテナローカル開発環境ができましたー

ちょっと動かしてみたい場合に使えると思います!

]]>
Vue.jsのバージョン3でVue Routerを使用して画面を新規作成する(複数画面構成にする) https://it.kensan.net/vue-js_version3_vue-router.html Thu, 10 Oct 2024 05:19:58 +0000 http://13.231.168.135/it/?p=2136 Vue.jsのバージョン3でVue Routerを使用して画面を新規作成してみます。

Vueのインストールからはじめます!

 

 

Vueインストール

以下のコマンドでインストールします。

npm install -g @vue/cli

次にプロジェクト作成します。

プロジェクト作成

以下のコマンドで「sample」というプロジェクトを作成します。

vue create sample

→上記コマンド実行時の設定については以下を参照

  1. 「Manually select features」を選択してエンター
  2. 組み込むモジュールの選択が求められるので、「Router」にチェックを追加してエンター
  3. バージョン選択が求められるので「3.x」を選択してエンター
  4. そのほかはお好みの設定をしてプロジェクト作成

サーバ起動

以下のコマンドで、プロジェクト直下に移動してサーバ起動

 cd sample

 npm run serve

動作確認

以下のURLで画面表示の確認をします。

http://localhost:8080/ 

問題なく表示されればOKです。

次に画面を追加してみます

画面を追加してみる

フォルダ構成

ざっくり以下の構成になっていて「src/views」と「src/router」配下のファイルを追加・修正することで画面を追加できます。

src/views

→viewファイル格納フォルダ

→配下のテンプレート修正で画面の見た目を修正できる

src/router

→配下のindex.jsでルーティングを追加・変更可能

src/viewsにテンプレートファイルを追加

<ファイル名>

TestView.vue
<ファイルの中身>
<template>
<div class="about">
<h1>This is an test</h1>
</div>
</template>

src/routerにルーティングを追加

<修正するファイル名>

index.js

<修正内容>

以下のように、routesの定義にtestのビューへのルートを追加します。


const routes = [
  {
    path: '/',
    name: 'home',
    component: HomeView
  },
  {
    path: '/about',
    name: 'about',
    component: () => import( '../views/AboutView.vue')
  },
  {
    path: '/test',
    name: 'test',
    component: () => import('../views/TestView.vue')
  }
]

src/App.vueに新しい画面へのリンクを追加する

<修正するファイル>

src/App.vue

<修正内容>

以下のようにテストページへのリンクを追加します。

<template>
<nav>
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link> |
<router-link to="/test">Test</router-link>
</nav>
<router-view/>
</template>

動作確認

以下のURLで画面表示の確認をします。

http://localhost:8080/ 

以下のような画面が表示されれば成功です!

まとめ

Vue.jsのバージョン3でVue Routerを使用して画面を新規作成してみました。

意外と簡単に作成できましたが、画面の作り込みは大変そうだな〜〜

]]>
LaravelでSendGrid-smtp送信のメール送信をテスト・デバッグする最短の方法ーSendGridの設定方法 https://it.kensan.net/laravel-sendgrid-smtp-mail-send.html Fri, 05 Jul 2024 10:54:47 +0000 http://18.179.19.147/it/?p=2113 LaravelでSendGrid-smtp送信のメール送信をテスト・デバッグする最短の方法について記載します。

こうすれば、SendGridのメール設定ができて、簡単に設定後の動作確認ができるよ、ということを記載していきます。

SendGridのテスト・デバッグ時のメール送信確認の設定周りを中心に記載します。

メール送信のLaravelプログラムの書き方については記載していません。

Laravelのローカル開発環境構築

ローカル開発環境構築は以下の記事をご参照ください。本記事ではローカル開発環境構築が済んでいることを前提に記載します。

DockerでLaravel 11のローカル開発環境を構築する。ついでにphpmyadminも入れてみる。
DockerでLaravel 11のローカル開発環境を構築していきます。 DB確認用に、phpmyadminもインストールします。 コンテナは以下のような構成です。本番環境に応用できるように、あえてSailは使いません。 アプリコンテナ P...

SendGrid側の設定

本記事ではSendGrid側の設定ができていることを前提に記載します。

SendGrid側の設定がまだの場合は以下のステップで設定できます。

  1. 以下の記事を参考に申し込みをする
  2. 申し込みが終わったら、以下の記事を参考に、差出人情報を設定する

LaravelにSendGrid-smtp送信の設定をして動作確認

メールをSendGridで送信するように設定変更

.envファイルでメールをSendGridで送信するように設定します。

以下のコマンドでプロジェクト直下の「.env」ファイルを開きます

vi .env

以下のとおり、「.env」ファイルを編集します。

MAIL_MAILER=smtp 
MAIL_HOST=smtp.sendgrid.net
MAIL_PORT=587
MAIL_USERNAME=apikey
MAIL_PASSWORD=<SendGridで払い出されたAPIキーを設定>
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS="<送信元メールアドレスを設定>"
MAIL_FROM_NAME="${APP_NAME}"

MAIL_PASSWORDには「SendGridで払い出されたAPIキー」を設定し、MAIL_FROM_ADDRESSには「送信元メールアドレス」を設定します。

メールを送って受信確認してみる

以下のコマンドでメールを送信可能です。

// コンテナの中に入る
docker compose exec app php artisan tinker
// メール送信
Mail::raw('test mail',function($message){$message->to('<実際に送信する送信先アドレス>')->subject('test');});

送付先のメールアドレスに実際にメールが届いていれば、SendGridの設定完了です。

まとめ

SendGridのメール設定ができて、簡単に設定後の動作確認ができたと思います。

]]>
Laravelのローカル開発環境でメール送信をテスト・デバッグする最短の方法(メール送信のための設定確認方法) https://it.kensan.net/laravel-mail-send-test.html Fri, 05 Jul 2024 10:17:45 +0000 http://18.179.19.147/it/?p=2106 Laravelのローカル開発環境でメール送信をテスト・デバッグする最短の方法について記載します。

以下の2つの方法を記載します。

  • ログで確認する方法
  • mailhog(コンテナ)で確認する方法

こうすれば、テスト時のメール設定ができて、簡単に設定後の動作確認ができるよ、ということを記載していきます。

テスト・デバッグ時のメール送信確認の設定周りを中心に記載します。

メール送信のLaravelプログラムの書き方については記載していません。

Laravelのローカル開発環境構築

ローカル開発環境構築は以下の記事をご参照ください。本記事ではローカル開発環境構築が済んでいることを前提に記載します。

DockerでLaravel 11のローカル開発環境を構築する。ついでにphpmyadminも入れてみる。
DockerでLaravel 11のローカル開発環境を構築していきます。 DB確認用に、phpmyadminもインストールします。 コンテナは以下のような構成です。本番環境に応用できるように、あえてSailは使いません。 アプリコンテナ P...

メール送信をログで確認する方法

メールの内容をログ出力するように設定変更

.envファイルでメールをログに吐き出すように設定します。

以下のコマンドでプロジェクト直下の「.env」ファイルを開きます

vi .env

以下のとおり、「.env」ファイル内のMAIL_MAILERにlogを設定します。

MAIL_MAILER=log

メールを送ってログを確認してみる

以下のコマンドでメールを送信可能です。

// コンテナの中に入る
docker compose exec app php artisan tinker
// メール送信
Mail::raw('test mail',function($message){$message->to('test@example.com')->subject('test');});

以下のようにcatコマンドなどを使ってログを確認します。

cat storage/logs/laravel.log 

以下のようにメールのログが確認できれば成功です。

From: Laravel <hello@example.com>
To: test@example.com
Subject: test
MIME-Version: 1.0
Date: Fri, 05 Jul 2024 09:41:54 +0000
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable

test mail  

メール送信をmailhog(コンテナ)で確認する方法

メールをmailhog(コンテナ)に送信する設定変更

.envファイルでメールをmailhogに吐き出すように設定します。

以下のコマンドでプロジェクト直下の「.env」ファイルを開きます

vi .env

以下のとおり、「.env」ファイル内のMAIL_HOSTmailhogを設定します。

ポートは1025を指定します。

MAIL_MAILER=smtp
MAIL_HOST=mailhog
MAIL_PORT=1025

次にdocker-compose.ymlを編集します。

vi docker-compose.yml

ファイルの中身は以下のように記載します。

services:
  mailhog:
    image: mailhog/mailhog
    ports:
      - target: 8025
        published: ${MAILHOG_PUBLISHED_PORT:-8025}
        protocol: tcp
        mode: host

dockerを立ち上げます

// コンテナを立ち上げている場合は一度落とす
docker compose down
// コンテナを立ち上げる
docker compose up

メールを送ってをmailhogで送信内容を確認してみる

以下のコマンドでメールを送信可能です。

// コンテナの中に入る
docker compose exec app php artisan tinker
// メール送信
Mail::raw('test mail',function($message){$message->to('test@example.com')->subject('test');});

http://127.0.0.1:8025/にアクセスして、以下のようにメール受信を確認できればOKです。

まとめ

以下の2通りでのメールの確認方法を記載しました。

  • ログで確認する方法
  • mailhog(コンテナ)で確認する方法

これでメール実装の設定準備はできたと思いますー

]]>
ALB(ロードバランサー)でCloudFront経由のアクセスに絞るときは、カスタム HTTP ヘッダーとマネージドプレフィックスリストを併用する https://it.kensan.net/alb-cloudfront-accesss.html Sun, 30 Jun 2024 07:40:39 +0000 http://35.77.216.202/it/?p=2095 ALB(ロードバランサー)でCloudFront経由のアクセスに絞る方法として、以下の方法があると思います。

  • マネージドプレフィックスリスト(managed prefix list)によりアクセスを絞る
  • カスタム HTTP ヘッダーによりアクセスを絞る

    上記はよく知られた方法かと思いますので、詳細は割愛します。

    本記事で記載したいことは、上記2つを併用した方が安心だよということです。

    まずは、用語の説明からです。

    用語の説明

    マネージドプレフィックスリスト(managed prefix list)とは

    AWS Managed Prefix Listは、AWSによって管理されるIPアドレスのプレフィックスリストです。特定のAWSサービス(例えばCloudFrontやAmazon S3など)のIPアドレス範囲を含んでおり、ネットワーク設定やセキュリティ設定を簡素化するために使用されます。

    本記事では、「マネージドプレフィックスリスト=CloudFrontのIP」として記載します。

    カスタム HTTP ヘッダー

    カスタム HTTP ヘッダーは、HTTP リクエストやレスポンスに含まれるユーザー定義のヘッダーであり、標準の HTTP ヘッダーではカバーされない追加の情報を送信するために使用されるものです。

    なぜ併用した方がいいのか

    ALB(ロードバランサー)でCloudFront経由のアクセスに絞る際に、マネージドプレフィックスリストとカスタム HTTP ヘッダーを併用する場合、以下のようになります。

    • マネージドプレフィックスリスト(managed prefix list)によるアクセス制限
      • IP制限により、CloudFront経由のアクセスを絞る
        • CloudFront経由であれば、別アカウントのものでも許可してしまう
    • カスタム HTTP ヘッダーによるアクセス制限
      • カスタムHTTPヘッダーにより、CloudFront経由にアクセスを絞る
        • 自分が作成したCloudFrontのみにアクセスを絞ることができる
    • →マネージドプレフィックスリストとカスタム HTTP ヘッダーを併用することで、自分が作成したCloudFrontのみにアクセスを絞ることができる

    マネージドプレフィックスリスト(managed prefix list)だけでは、CloudFrontのIP制限のため、CloudFrontからの接続であれば、別アカウントのものでも許可してしまいます。

    そのため、カスタム HTTP ヘッダーも併用が必要となります。カスタム HTTP ヘッダーにより、自分が作成したCloudFrontのみにアクセスを絞ることができます。

    2段階で網をかけておいた方が安心ですね。

    カスタム HTTP ヘッダーとマネージドプレフィックスリストの設定方法

    公式記事に詳しく書いてあるので、以下の公式の記事をご参照ください。

    Application Load Balancer へのアクセスを制限する - Amazon CloudFront
    Amazon CloudFront でカスタムオリジンヘッダーを使用して、ユーザー(閲覧者)が Application Load Balancer に直接アクセスできないようにします。

    まとめ

    ALB(ロードバランサー)でCloudFront経由のアクセスに絞るときは、カスタム HTTP ヘッダーとマネージドプレフィックスリストを併用するのが良いです。

    マネージドプレフィックスリスト単体でも、https(443)の通信にしているから問題とならないケースもあると思いますが、基本的にはカスタム HTTP ヘッダーとマネージドプレフィックスリストを併用した方が安心かと思います。

    ]]>
    Laravel Adminのgridでの細かい検索とformでの1対多のデータ登録のやり方~todoリストを作成しつつ解説~ https://it.kensan.net/laravel-admin-grid-form.html Sat, 08 Jun 2024 03:22:02 +0000 http://35.78.204.110/it/?p=2052 Laravel Adminのgridとformの使い方について記載していきます。

    Laravel Adminって何者?という方は以下の記事をご参照ください。

    Laravel Adminで効率的に管理画面を作成する。Dockerを使用した環境構築と使い方について記載。
    Laravel Adminは、ウェブアプリケーションの管理画面を効率的かつ簡単に作成できるツールです。 この記事では、Laravel Adminの利点と使い方について詳しく記載します。 Laravel Adminを利用すると、データベースの...

    gridとformについて簡単に書くと、以下のようになります。gridとformを理解することでLaravel Adminの大部分を使いこなせると思います。

    • grid:一覧表示
    • form:新規登録・編集機能

    本記事でやること

    • 登録・編集(formメソッド)
      • セレクトボックスの設置
        • 選択肢はDBから取得
      • 入力ボックスを使わないデフォルト値設定
      • 1対多のテーブルでのデータ登録
    • フィルター・一覧(gridメソッド)
      • デフォルトでの検索条件の指定
      • チェックボックスでor検索の実装
      • 一覧の文字色変更

     

    では、todoリストを作成しつつ、説明していきます

    Laravel Adminを動作させる環境構築

    環境構築は以下の記事をご参照ください。Dockerで簡単に構築できます。

    Laravel Adminで効率的に管理画面を作成する。Dockerを使用した環境構築と使い方について記載。
    Laravel Adminは、ウェブアプリケーションの管理画面を効率的かつ簡単に作成できるツールです。 この記事では、Laravel Adminの利点と使い方について詳しく記載します。 Laravel Adminを利用すると、データベースの...

    テーブルとModelとControllerの準備

    テーブルの作成

    テーブル構成は以下のようになります。

    • todo情報を格納するtodosテーブル
    • todo情報に対するコメントを格納するcommentsテーブル

    では、以下のコマンドでマイグレートファイルを作成します。

    php artisan make:migration create_todos_table --create=todos
    
    php artisan make:migration create_comments_table --create=comments

    マイグレーションファイルは以下のように修正します。

    <todosテーブル>

    
    <?php
    
    use Illuminate\Database\Migrations\Migration;
    use Illuminate\Database\Schema\Blueprint;
    use Illuminate\Support\Facades\Schema;
    
    return new class extends Migration
    {
        /**
         * Run the migrations.
         */
        public function up(): void
        {
            Schema::create('todos', function (Blueprint $table) {
                $table->increments('id');
                $table->string('todo_name')->nullable(false)->index();    # todoの名前
                $table->string('target_user_id')->nullable(false);    # todoの担当者
                $table->string('regist_user_id')->nullable(true);    # todoの登録者
                $table->integer('status')->nullable(true)->default(0);    # 完了ステータス 0:未完了、1:完了
                $table->timestamps();
            });
        }
    
        /**
         * Reverse the migrations.
         */
        public function down(): void
        {
            Schema::dropIfExists('todos');
        }
    };

    <commentsテーブル>

    
    <?php
    
    use Illuminate\Database\Migrations\Migration;
    use Illuminate\Database\Schema\Blueprint;
    use Illuminate\Support\Facades\Schema;
    
    return new class extends Migration
    {
        /**
         * Run the migrations.
         */
        public function up(): void
        {
            Schema::create('comments', function (Blueprint $table) {
                $table->increments('id');
                $table->integer('todo_id');
                $table->text('comment');
                $table->string('regist_user_id')->nullable(true);
                $table->timestamps();
            });
        }
    
        /**
         * Reverse the migrations.
         */
        public function down(): void
        {
            Schema::dropIfExists('comments');
        }
    };
    

    Modelの準備

    以下のコマンドでModelを作成します。

    php artisan make:model Todo
    php artisan make:model Comment

    Modelは以下のように修正します。

    <Todo.php>

    
    <?php
    
    namespace App\Models;
    
    use Illuminate\Database\Eloquent\Factories\HasFactory;
    use Illuminate\Database\Eloquent\Model;
    
    class Todo extends Model
    {
        use HasFactory;
        public function comments()
        {
            return $this->hasMany(comment::class);
        }
    }
    

    <Comment.php>

    
    <?php
    
    namespace App\Models;
    
    use Illuminate\Database\Eloquent\Factories\HasFactory;
    use Illuminate\Database\Eloquent\Model;
    
    class Comment extends Model
    {
        protected $fillable = [
            'todo_id',
            'comment',
            'regist_user_id',
        ];
        use HasFactory;
        
        public function todo()
        {
            return $this->belongsTo(Todo::class);
        }
    }
    

    動作確認

    http://localhost:8000/admin/todos にアクセスして、以下のようにカラのリスト画面が表示されればOKです。

    準備ができましたので、formメソッドを編集しつつ、説明していきます。

    Laravel adminのformメソッドの使い方

    まずformメソッドについて記載します。

    formメソッドとは

    以下のような機能を持っています。新規登録・編集用のメソッドですね。

    • 入力フィールド:テキスト、数値、パスワード、セレクトボックス、ラジオボタン、チェックボックスなど。
    • バリデーション:入力データの検証機能。
    • リレーション管理:関連するデータモデルの管理。
    • イベントフック:フォームの保存前後に処理を追加。

    それではformメソッドを編集していきます。

    formメソッドの編集内容

    編集前(コマンドでコントローラ作成直後)は、以下の登録画面になっています。

    直したいポイントは以下です。

    1. Target user id(todoの担当者) を選択形式にしたい
    2. Regist user id(todoの作成者)はセッション情報から自動的に登録したい
    3. Statusは「0:未完了」で自動的に登録したい
    4. コメントを登録できるようにしたい(1対多のデータ登録)

    完成系の画面イメージは以下のような感じです。

    では順番に修正していきます。

    Target user id(todoの担当者) を選択形式にしたい

    ファイル上部でLaravel-adminのAdminクラスの名前空間を宣言します。

    use Encore\Admin\Facades\Admin;

    次に以下のように「target_user_id」をテキストからセレクトボックスに変更し、セレクトボックスの選択肢に、Adminユーザを指定します。

    // $form->text('target_user_id', __('Target user id'));  //コメントアウト
    $form->select('target_user_id', __('Target user id'))->options(Admin::user()->pluck('username', 'id')); //追加

    完了です。次にいきます。

    Regist user id(todoの作成者)はセッション情報から自動的に登録したい

    regist_user_idの入力ボックスをコメントアウトします。

    //$form->text('regist_user_id', __('Regist user id'));

    次に$form->savingを使ってregist_user_idにログイン中ユーザのIDを登録します。

            $form->saving(function (Form $form) {
                // regist_user_idは「Admin::user()->id」を設定する
                $form->model()->regist_user_id = Admin::user()->id;
            });

    完了です。次にいきます。

    Statusは「0:未完了」で自動的に登録したい

    statusの入力ボックスをコメントアウトします。

    //$form->number('status', __('Status'));

    次に$form->savingを使ってstatusに「0」を登録します。

            $form->saving(function (Form $form) {
                // regist_user_idは「Admin::user()->id」を設定する
                $form->model()->regist_user_id = Admin::user()->id;
                // statusは「0」を設定する
                $form->model()->status = 0;   //ここを追加
            });

    完了です。次はコメントです。

    コメントを登録できるようにしたい(1対多のデータ登録)

    以下のように記載することで、コメントを登録できるようになります。

            # コメント
            $form->hasMany('comments', 'コメント欄', function (Form\NestedForm $form) {
                $form->hidden('regist_user_id', __('regist_user_id'))->default(Admin::user()->id);
                $form->textarea('comment','コメント');
            });

    hasManyメソッドを使い、複数のコメントをフォームに追加できるようにしています。

    完成した画面

    以下の通り、実現したかった画面が出来上がりましたー

     

    編集画面でステータスを完了できるようにする

    このままだと、ステータスを完了にできないので、編集画面でステータスを完了できるようにします。

    以下のコードを書いてあげれば、ステータス更新可能になります。

            // ステータス更新(編集時のみ更新可能)
            if ($form->isEditing()) {
                $form->switch('status', '完了')->states([
                    'on' => ['value' => 1, 'text' => '完了', 'color' => 'success'],
                    'off' => ['value' => 0, 'text' => '未完了', 'color' => 'danger'],
                ]);
            }

    $form->isEditing()で登録か更新かの判定をしています。

    更新の場合、入力パーツswitchを表示するコードになっています。

    編集画面の完成系は以下のようになります!

     

    Laravel adminのgridメソッドの使い方

    まずgridメソッドについて記載します。

    gridメソッドとは

    以下のような機能を持っています。一覧ページ表示用のメソッドですね。

    • データ表示:データベースのレコードをテーブル形式で表示。
    • フィルタリング:条件に基づいてデータを絞り込む。
    • ソート:特定のカラムでデータを昇順または降順に並べ替え。

    一覧画面の直したいポイント

    直したいポイントは以下です。

    1. 自分が登録したtodoまたは自分が担当のtodoで検索したい
    2. 一覧で自分が担当のtodoは赤文字表示したい

    自分が登録したtodoまたは自分が担当のtodoで検索したい

    以下のコードを書いてあげれば、検索可能になります。

    作成者(regist_user_id)と担当者(target_user_id)のor検索になります。

            $grid->filter(function ($filter) {
                $filter->where(function ($query) {
                    if(array_search('1', $this->input) !== false) {
                        $query->orWhere('regist_user_id', Admin::user()->id);
                    }
                    if(array_search('2', $this->input) !== false) {
                        $query->orWhere('target_user_id', Admin::user()->id);
                    }
                }, '自分のtodoを表示', 'search_tantou')->checkbox([
                    '1' => '作成したtodoを表示',
                    '2' => '担当のtodoを表示',
                ]);
            });

    デフォルトで(画面アクセス時に)「作成者(regist_user_id)と担当者(target_user_id)のor検索」で絞り込みをしたい場合は、メニュー編集で対応できます。http://localhost:8000/admin/auth/menu にアクセスし、メニューを編集します。編集時に、URIを以下の通り設定します。

    todos?&search_tantou%5B%5D=1&search_tantou%5B%5D=2

    画面で説明すると、以下の画面のURIに上記の値を入力して保存です。

    一覧で自分が担当のtodoは赤文字表示したい

    以下のコードで、自分が担当のtodoを赤字で表示できます。

            // 文字色設定
            $grid->rows(function ($row) {
                # 自分が担当のtodoは、赤字にする
                if ($row->target_user_id == Admin::user()->id ) {
                    $row->style('color: red');
                }
            });

    完成した画面

    完成した一覧画面は以下の通りです。

    URIを「todos?&search_tantou%5B%5D=1&search_tantou%5B%5D=2」に変更した場合、画面表示直後は、「自分のtodoの表示」のチェックボックスはONになっているはずです。

    以下が実現できましたー

    • デフォルトでの検索条件の指定
    • チェックボックスでor検索の実装
    • 一覧の文字色変更

    修正後のコントローラの全体ソース

    修正後のコントローラの全体ソースは以下の通りです。

    
    <?php
    
    namespace App\Admin\Controllers;
    
    use App\Models\Todo;
    use Encore\Admin\Controllers\AdminController;
    use Encore\Admin\Form;
    use Encore\Admin\Grid;
    use Encore\Admin\Show;
    use Encore\Admin\Facades\Admin;
    
    class TodoController extends AdminController
    {
        /**
         * Title for current resource.
         *
         * @var string
         */
        protected $title = 'Todo';
    
        /**
         * Make a grid builder.
         *
         * @return Grid
         */
        protected function grid()
        {
            $grid = new Grid(new Todo());
    
    
            $grid->filter(function ($filter) {
                $filter->where(function ($query) {
                    if(array_search('1', $this->input) !== false) {
                        $query->orWhere('regist_user_id', Admin::user()->id);
                    }
                    if(array_search('2', $this->input) !== false) {
                        $query->orWhere('target_user_id', Admin::user()->id);
                    }
                }, '自分のtodoを表示', 'search_tantou')->checkbox([
                    '1' => '作成したtodoを表示',
                    '2' => '担当のtodoを表示',
                ]);
            });
    
            $grid->column('id', __('Id'));
            $grid->column('todo_name', __('Todo name'));
            $grid->column('target_user_id', __('Target user id'));
            $grid->column('regist_user_id', __('Regist user id'));
            $grid->column('status', __('Status'));
            $grid->column('created_at', __('Created at'));
            $grid->column('updated_at', __('Updated at'));
    
            // 表示色
            $grid->rows(function ($row) {
                # 自分が担当のtodoは、赤字にする
                if ($row->target_user_id == Admin::user()->id ) {
                    $row->style('color: red');
                }
            });
    
            return $grid;
        }
    
        /**
         * Make a show builder.
         *
         * @param mixed $id
         * @return Show
         */
        protected function detail($id)
        {
            $show = new Show(Todo::findOrFail($id));
    
            $show->field('id', __('Id'));
            $show->field('todo_name', __('Todo name'));
            $show->field('target_user_id', __('Target user id'));
            $show->field('regist_user_id', __('Regist user id'));
            $show->field('status', __('Status'));
            $show->field('created_at', __('Created at'));
            $show->field('updated_at', __('Updated at'));
    
            return $show;
        }
    
        /**
         * Make a form builder.
         *
         * @return Form
         */
        protected function form()
        {
            $form = new Form(new Todo());
    
            $form->text('todo_name', __('Todo name'));
    //        $form->text('target_user_id', __('Target user id'));
            $form->select('target_user_id', __('Target user id'))->options(Admin::user()->pluck('username', 'id'));
    //        $form->text('regist_user_id', __('Regist user id'));
    //        $form->number('status', __('Status'));
    
            # コメント
            $form->hasMany('comments', 'コメント欄', function (Form\NestedForm $form) {
                $form->hidden('regist_user_id', __('regist_user_id'))->default(Admin::user()->id);
                $form->textarea('comment','コメント');
            });
    
            // ステータス更新(編集時のみ更新可能)
            if ($form->isEditing()) {
                $form->switch('status', '完了')->states([
                    'on' => ['value' => 1, 'text' => '完了', 'color' => 'success'],
                    'off' => ['value' => 0, 'text' => '未完了', 'color' => 'danger'],
                ]);
            }
    
            $form->saving(function (Form $form) {
                // regist_user_idは「Admin::user()->id」を設定する
                $form->model()->regist_user_id = Admin::user()->id;
                // statusは「0」を設定する
                $form->model()->status = 0;
            });
    
            return $form;
        }
    }
    

     

    まとめ

    Laravel adminで以下の修正をしてみました。結構短時間でできたと思います。Laravel admin素晴らし〜

    • 登録・編集(formメソッド)
      • セレクトボックスの設置
        • 選択肢はDBから取得
      • 入力ボックスを使わないデフォルト値設定
      • 1対多のテーブルでのデータ登録
    • フィルター・一覧(gridメソッド)
      • デフォルトでの検索条件の指定
      • チェックボックスでor検索の実装
      • 一覧の文字色変更
    ]]>
    【初心者向け】意外と知らない便利なLinuxコマンド(「cd+スペース+ハイフン」とcalとtouchコマンドのご紹介) https://it.kensan.net/linux_command.html Fri, 07 Jun 2024 23:34:46 +0000 http://35.78.204.110/it/?p=2046 意外と知らない便利なLinuxコマンド集です。

    以下のコマンドを紹介します。

    • cd -(cd+スペース+ハイフン)コマンド
      • 前に居たフォルダと今居るフォルダを行き来できる
    • calコマンド
      • カレンダーを確認できます。
    • touch
      • ファイルのタイムスタンプを更新できる

    「cd -」で前に居たフォルダと今居るフォルダを行き来する

    以下のコマンドで、前に居たフォルダと今居るフォルダを行き来できます。

    cd -

    ぜひ使ってみてください。

    「cal」コマンドでカレンダーを確認する

    以下のコマンドで、カレンダーを確認できます。

    cal

    以下のようにカレンダーが表示されます。

    「touch」でファイルのタイムスタンプを更新する

    以下のコマンドで、ファイルのタイムスタンプを更新できます。

    touch {ファイル名}

    ファイルが存在しない場合、空ファイルを作成する挙動となります。

    まとめ

    意外と知らない便利なLinuxコマンドを紹介させていただきました。

    サーバ監視で使える便利なコマンドの記事もありますので、よろしければ以下をご参照ください!

    【初心者向け】サーバー監視で使える便利なLinuxコマンド(topとdfとlessとtailコマンドのご紹介)
    サーバー監視で使える便利なLinuxコマンド集です。 以下のコマンドを紹介します。 topコマンド CPU・メモリ・プロセスが確認できる dfコマンド ディスク空き容量が確認できる ログ確認コマンド lessコマンド 安全にファイルを開ける...
    ]]>