もがき系プログラマの日常

もがき系エンジニアの勉強したこと、日常のこと、気になっている技術、備忘録などを紹介するブログです。

php8.1のenumを使ってみる

はじめに

こんばんは。

前回のphp8.1をインストールしてみたのですが、今回はphp8.1の目玉っぽい 列挙型を試してみます。

前回の記事は以下

kojirooooocks.hatenablog.com

www.php.net

本題

試したバージョンはこちら

$php -v
PHP 8.1.6 (cli) (built: Jun 10 2022 23:47:15) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.6, Copyright (c) Zend Technologies
    with Zend OPcache v8.1.6, Copyright (c), by Zend Technologies
    with Xdebug v3.1.4, Copyright (c) 2002-2022, by Derick Rethans

cases()

<?php

enum Status
{
  case Enable;
  case Disable;
}

var_dump(Status::cases());
// array(2) {
//   [0] =>
//   enum Status::Enable;
//   [1] =>
//   enum Status::Disable;
// }

Backed Enum

<?php

enum Status: int
{
  case Enable = 1;
  case Disable = 0;
}

var_dump(Status::Enable->value);  // int(1)
var_dump(Status::Disable->value); // int(0)
var_dump(Status::tryFrom(2));        // NULL
var_dump(Status::tryFrom(1));        // enum Status::Enable : int(1);

メソッド

<?php

enum Color: int
{
  case Red = 10;
  case Blue = 20;
  case Yellow = 30;
  case Green = 40;
  case Black = 50;
  case White = 60;

  public function isRGB(): bool
  {
    return match($this) {
      Color::Red, Color::Green, Color::Blue => true,
      default => false
    };
  }
}

var_dump(Color::Red->isRGB());   // => bool(true)
var_dump(Color::Blue->isRGB());  // => bool(true)
var_dump(Color::Black->isRGB()); // => bool(false)

終わりに

メソッドもてるのが面白いですね。

メソッドもてるからトレイトも使えるみたいです。

個人的にトレイトは混乱するので、あんま使わないかもですが、効率よく使えたらかっこいいなと思いました。

現場からは以上です。

phpenvでphp8.1をインストール

はじめまして

php8.1の案件が来るみたいでローカルに php8.1をインストールしてみました。

例のごとく phpenv です。

本題

とりあえず普通に実行してみます。

$ phpenv install 8.1.6
...
...
...
curl: (56) LibreSSL SSL_read: Connection reset by peer, errno 54

あんまり見ないエラーがでました。

調べてみるとキャッシュ不足とのことでした。

reject.tokyo

今回は参考サイトの対策1で対応してみました。

$ git config http.postBuffer 512M

これで再度実行します。

$ phpenv install 8.1.6
...
...
...
configure: error: Please reinstall the BZip2 distribution

見覚えあるエラーです。

php8.0入れたときにもおんなじようなエラーが出てました。

過去の自分のサイトで使ったインストールコマンドを持ってきて実行してみます。

kojirooooocks.hatenablog.com

$ PHP_BUILD_CONFIGURE_OPTS="--with-bz2=/usr/local/opt/bzip2 --with-iconv=/usr/local/opt/libiconv" phpenv install 8.1.6


[Info]: Loaded extension plugin
[Info]: Loaded apc Plugin.
[Info]: Loaded composer Plugin.
[Info]: Loaded github Plugin.
[Info]: Loaded uprofiler Plugin.
[Info]: Loaded xdebug Plugin.
[Info]: Loaded xhprof Plugin.
[Info]: Loaded zendopcache Plugin.
[Info]: php.ini-production gets used as php.ini
[Info]: Building 8.1.6 into /path/to/.anyenv/envs/phpenv/versions/8.1.6
[Skipping]: Already downloaded and extracted https://www.php.net/distributions/php-8.1.6.tar.bz2
[Preparing]: /var/tmp/php-build/source/8.1.6
[Compiling]: /var/tmp/php-build/source/8.1.6
[xdebug]: Installing version 3.1.4
[Downloading]: http://xdebug.org/files/xdebug-3.1.4.tgz
[xdebug]: Compiling xdebug in /var/tmp/php-build/source/xdebug-3.1.4
[xdebug]: Installing xdebug configuration in /path/to/.anyenv/envs/phpenv/versions/8.1.6/etc/conf.d/xdebug.ini
[xdebug]: Cleaning up.
Makefile:240: warning: overriding commands for target `test'
Makefile:133: warning: ignoring old commands for target `test'
[Info]: Enabling Opcache...
[Info]: Done
[Info]: The Log File is not empty, but the Build did not fail. Maybe just warnings got logged. You can review the log in /tmp/php-build.8.1.6.20220610234330.log or rebuild with '--verbose' option
[Success]: Built 8.1.6 successfully.
phpenv: cannot rehash: /path/to/.anyenv/envs/phpenv/shims/.phpenv-shim exists
$ phpenv versions
* 7.4.25 (set by /path/to/.anyenv/envs/phpenv/version)
  8.0.12
  8.1.6


$ phpenv global 8.1.6
8.1.6


$ php -v
PHP 8.1.6 (cli) (built: Jun 10 2022 23:47:15) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.6, Copyright (c) Zend Technologies
    with Zend OPcache v8.1.6, Copyright (c), by Zend Technologies
    with Xdebug v3.1.4, Copyright (c) 2002-2022, by Derick Rethans

問題なく入りました!

終わりに

かんたんでしたが、インストールログでした。

php8.1のenum試してみたいから、試したらまた書くかも。

現場からは以上です。

ダイエットの成果が出てきた

こんばんは。

めちゃめちゃプライベートのブログですが、5月1ヶ月間のダイエットがやっと出てきました。

どうもここ最近勉強や仕事にあまり身が入らない。やる気が起きないという現象がおきてまして、

「運動不足が原因かも...」

と思って、毎回挫折していたダイエットを先月1ヶ月間ガチのダイエットを行いました。

運動

メインとなる運動はこのゲーム

このゲームで有酸素運動をして無駄な贅肉を落とす方針です。

サブでこちら

こちらで筋肉つけて基礎代謝上げていきました。

食事

食事は基本的に以下の方針

朝食

  • ゆで卵x3

昼食

  • ゆで卵x3

夕食

これを5月は31日中、25日間程やり続けました。 旅行等に行ったのでその期間はできなかったのですが、それ以外は頑張りました。

その結果

76kg だった体重が5/31では 69.4kg まで下げることに成功しました。

終わりに

6月現在も食事を バナナx1, ゆで卵x2 に変更したくらいで、頑張って運動も継続中です。

6月の目標は 66kg です。頑張るぞ!

おまけ

今の悩みは運動で疲れすぎて勉強が手に付かないことです...

MySQLのFIND_IN_SET知らなかった

はじめに

こんばんは。

今回も知らなかったシリーズです。

恥をかきにいくスタイルでブログ化します。

今回はMySQLのFIND_IN_SETです。

dev.mysql.com

本題

1,2,3,4,5 のようなカンマ区切りで登録されているカラムに対して、カンマごとの値に対して検索が行なえます。

id type
1 aaa,bbb,ccc,ddd,eee
2 ccc,bbb
3 ddd
4 eee

上記のようなデータがあったときに、 ddd をもっているデータを抽出したいってなったときに役立ちます。

SELECT * FROM test_table WHERE FIND_IN_SET('ddd', types);

これで IDの 1, 3 がとれます。

便利〜

一歩進んで見る

FIND_IN_SETはカンマ区切りが絶対条件なのですが、例えば、スラッシュ区切りとかはどうすればいいのかと考えてたのですが、ありましたw

stackoverflow.com

SELECT * FROM test_table WHERE FIND_IN_SET('ddd', REPLACE(types, '/', ','))

やることは単純で 区切り文字を カンマ区切りに変換されば FIND_IN_SET が使えるようになります。

終わりに

結構知らないことが多い自分で恥ずかしい... ><

そういえば、最近ダイエットで運動頑張っているのですが、初めて3週間くらいたって、やっと成果が出始めてきました。

5月の目標が達成するかどうかは微妙ですが、がんばります!!

laravelのクエリログ確認方法知らなかった

はじめに

こんばんは。

laravelのクエリログ確認方法恥ずかしながら Illuminate\Database\Query\Builder\toSQL() しか知らなかったんですが、他の方法をここ最近知りました....w

自分の無知を噛みしめるために備忘録にしておきます。

本題

Illuminate\Support\Facades\DB::enableQueryLog();Illuminate\Support\Facades\DB::getQueryLog() を使うだけです。

public function find()
{
    Illuminate\Support\Facades\DB::enableQueryLog();

    User::find(1);

    dump(Illuminate\Support\Facades\DB::getQueryLog());
}

これだけでOK。

array:1 [
  0 => array:3 [
    "query" => "select * from `users` where `id` = ?"
    "bindings" => array:1 [
      0 => 1
    ]
    "time" => 8.26
  ]

らく〜

最近追加されたのかなとか思ってたら、めちゃめちゃ古くからありました...

恥ずかしい...

ORMでSQLを組み立てるから発行されるSQLを結構確認するタイプなのですが、 今まで頑張って toSQLで確認していたのが馬鹿みたいです...

middleware作ってみた

好きなときだけ クエリログをログに出力して開発したいなと思ったので、middlewareを作ってみました。

<?php

namespace App\Http\Middleware;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class QueryLogMiddleware
{
    public function handle(Request $request, \Closure $next, ...$guards)
    {
        if (config('app.debug') === false || config('app.query_log') === false) {
            return $next($request);
        }

        DB::enableQueryLog();

        $response = $next($request);

        $queryLogs  = DB::getQueryLog();
        $queryCount = count($queryLogs);
        if ($queryCount === 0) {
            return $response;
        }

        Log::debug("========== Query Logs Start (count: {$queryCount}) ==========");

        array_map(static function(array $log) {
            $parameter = implode(", ", $log['bindings']);
            Log::debug("{$log['query']}    parameter: [{$parameter}]    time: {$log['time']}");
        }, $queryLogs);

        Log::debug("==========  Query Logs End (count: {$queryCount})  ==========");

        DB::disableQueryLog();

        return $response;
    }
}

ログの結果はこちら

[2022-05-28 00:00:00] local.DEBUG: ========== Query Logs Start (count: 1) ==========  
[2022-05-28 00:00:00] local.DEBUG: select * from `users` where `id` = ?    parameter: [1]    time: 8.26
[2022-05-28 00:00:00] local.DEBUG: ==========  Query Logs End (count: 1)  ==========  

設定で出し分けられるので地味に開発助かります。

でもこれくらいであれば、普通にありそうだけど、ないのかなぁ?

終わりに

これからも無知の知を心がけて恥をかきながら仕事していこうとおもいます。

circleciのslack通知が知らない間に新しくなっていた

はじめに

こんばんは。

最近 circleci のslack通知が新しくなっていたのを知りました。

設定ファイルとか全然いじってなかったので知りませんでした。。。

公式サイトによるとSlack Orbなるものを使うみたいです。

circleci.com

早速やってみます。

本題

初期設定

1. circleci側設定

とりあえずサンプルの laravelプロジェクトをcircleciに追加します。

追加すると circleci-project-setup というブランチが出来て一発目が回ります。

該当ブランチには circleciの設定ファイルが .circleci/config.yml 追加されてます。

# Use the latest 2.1 version of CircleCI pipeline process engine.
# See: https://circleci.com/docs/2.0/configuration-reference
version: 2.1

# Define a job to be invoked later in a workflow.
# See: https://circleci.com/docs/2.0/configuration-reference/#jobs
jobs:
  say-hello:
    # Specify the execution environment. You can specify an image from Dockerhub or use one of our Convenience Images from CircleCI's Developer Hub.
    # See: https://circleci.com/docs/2.0/configuration-reference/#docker-machine-macos-windows-executor
    docker:
      - image: cimg/base:stable
    # Add steps to the job
    # See: https://circleci.com/docs/2.0/configuration-reference/#steps
    steps:
      - checkout
      - run:
          name: "Say hello"
          command: "echo Hello, World!"

# Invoke jobs via workflows
# See: https://circleci.com/docs/2.0/configuration-reference/#workflows
workflows:
  say-hello-workflow:
    jobs:
      - say-hello

2. slack app作成

slack通知のために諸々設定します。 解説してくれているページがあったのでこちら見ればそこまで迷わないです。

github.com

上記の設定ができたあとは、 サイドバーの OAuth & Permisions を選択して、下記設定を行います。

その後は サイトバーの Install App を選択してアプリをワークスペースへインストールします。

インストールすると tokenが発行されます。

3. circleciに設定を追加

次は circleci側の設定でtokenと通知するチャンネルを登録します。

先程追加された config.ymlを以下のように修正してjobを回してみます。

version: 2.1

orbs:
  slack: circleci/slack@4.10.1

jobs:
  say-hello:
    docker:
      - image: cimg/base:stable
    steps:
      - checkout
      - run:
          name: "Say hello"
          command: "echo Hello, World!"
      - slack/notify:
          event: fail
          template: basic_fail_1
      - slack/notify:
          event: pass
          template: basic_success_1

workflows:
  say-hello-workflow:
    jobs:
      - say-hello

絶対に成功するので、successで通知が来ました!

一歩進んで見る

毎回通知するのは個人的にだるいので、基本的には fail 通知だけにして、特定のブランチに関しては successとfailの通知が飛ぶようにしたいです。

公式見ると branch_pattern ってやつを使えば行けそうでしたので、やってみます。

circleci.com

      - slack/notify:
          event: pass
          branch_pattern: develop,main ← こちらを追加
          template: basic_success_1

これで 先程出来た circleci-project-setup というブランチでpushしてciが回って成功しても通知が来なくなりました。

circleci-project-setup で failが来ることを確認してみます。

config.ymlを以下みたいに修正します。

      - run:
          name: "Say hello"
          command: "echo Hello, World! && exit 1" ←こんな感じで変更

来ましたー!

最後に、mainとdevelopだけsuccessが来るように設定したので、その設定が生きているかを確認します。

問題なく来ました。

さらにもう一歩進んで見る

通知が来たときにメンションが飛ばせるみたいです。

例えば重要な develop, main のブランチの失敗のみ @here でメンションをつけて、それ以外のブランチの失敗はメンションをつけないとかやってみたいです。

      # こちらを追加
      - slack/notify:
          event: fail
          branch_pattern: develop,main
          mentions: "@here"
          template: basic_fail_1

develop, mainブランチではメンションがついて、それ以外のブランチではメンションがつかないことを確認できました。

終わりに

すごく簡単に設定できて、かつカスタムも結構効く感じでした。

もう過去の設定方法は完全に忘れているので新鮮にやりやすいと感じてました...w

複数のチャンネルに通知したり、通知のテンプレートをカスタムしたりもできるので、やろうと思えばもっと作り込めそうです。

現場からは以上です。

mermaid大好きになっている

はじめに

こんばんは。

最近 mermaid 書くのにはまっています。

今までは ER図は tbls で シーケンス図は PlantUML を使ってたんですが、全部 mermaid使ってます。

githubが判断してくれるのがありがたいですよね。

github.com

plantuml.com

本題

mermaidで僕が現在使っているのは、ER図、フローチャート図、シーケンス図です。

ER図

%%{init:{'theme':'default'}}%%
erDiagram

users {
  integer id PK "ユーザーID"
  string email "メールアドレス"
  string password "パスワード"
}

users ||--|| user_profiles : "1:1"
user_profiles {
  integer user_id FK "ユーザーID"
  string name "ユーザー名"
  string tel "電話番号"
  integer gender "性別"
  date birthday "誕生日"
  string postal_code "郵便番号"
  string address "住所詳細"
}

items {
  integer id PK "アイテムID"
  string name "アイテム名"
}

tags {
  integer id PK "タグID"
  string name "タグ名"
}

items ||--|{ item_tags: "1:N"
tags ||--|{ item_tags: "1:N"
item_tags {
  integer item_id FK "アイテムID"
  integer tag_id FK "タグID"
}

orders }|--|| users: "N:1"
orders }|--|| items: "N:1"
orders {
  integer id PK "オーダーID"
  integer user_id FK "ユーザーID"
  integer item_id FK "アイテムID"
}

フローチャート

%%{init:{'theme':'forest'}}%%
flowchart TD
    A[注文実行] --> B{リピーターかどうか}
    B -->|リピーター| C[10%OFFクーポン配布]
    C --> D[決済実行]
    B -->|初回| E[5%OFFクーポン配布]
    E --> D

シーケンス図

sequenceDiagram
autonumber

participant user as ユーザー
participant site as サイト
participant api as 決済API
rect rgb(100, 100, 100)
    user ->>+ site: 注文実行
    site ->>+ api: 決済実行
    api ->>+ site: 決済OK
    site ->>+ site: 注文確定
    site ->>+ user: 注文完了ページ
end

終わりに

マジでかんたんでこういうの書くハードルが下がりました。

クラス図とかもかけるっぽいんで、今後積極的に書いていきたいです。

現場からは以上です。