独学エンジニアのメモ帳

得た知識のアウトプットとか日常のメモとか。ゆるくやる。

.envの値に「#」がある時はクォーテーションで囲まなければならない

先日、VPS上にLaravel環境を作った。

で、一通り構築し終わってmigrateしたところ、
下記エラーが発生。

$ php artisan migrate

SQLSTATE[HY000] [1045] Access denied for user...

mysql側でいくら原因を探しても分からず。
ネットを調べまわっていたところ、「これか?」と思うものを発見。

Laravel 5.8 Access denied for user 'root'@'localhost' (using password: YES)

今回作った環境では、mysqlのパスワードに

MYSQL_PASSWORD=HOGEHOGE#

のように「#」が含まれていた。
.envファイルで値に「#」が含まれていると、挙動がおかしくなるらしい。
コメントアウトの記号だし、その関係か?

とにかく

MYSQL_PASSWORD="HOGEHOGE#"

のようにクォーテーションで囲んでやり、再度migrateしてやると無事動いた。

ComposerでピュアなPHPプロジェクトを作る

PHPの依存関係管理ツールである
「Composer」

Laravelでの開発に使用しているが、何となく使ってて単体で使ったことなかったので、ちょっといじってみた。

公式にも記述があるが、
JavaScriptのnpm(yarn), RubyのBundler
に影響を受けている。
Rubyは経験ないので分からないが、JavaScriptは普段から使っているので
npmと考え方使い方だいたい似たような感じだとは思う。

前提条件

この記事でインストール方法については扱わない。調べればいくらでも出るので。

$ composer -v
   ______
  / ____/___  ____ ___  ____  ____  ________  _____
 / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
                    /_/
Composer version 2.0.4 2020-10-30 22:39:11

この状態からスタート。

プロジェクト作成

プロジェクトディレクトリを作る

$ mkdir sample
$ cd sample

composer.jsonを作る

$ composer init

もちろん、自分でも作れるが、
今回は一応対話式で作成してみた。(全てEnterでスキップ)
すると、こんな感じのファイルが作られる

[composer.json]

{
    "name": "yourname/sample",
    "authors": [
        {
            "name": "yourname",
            "email": "youremail"
        }
    ],
    "require": {}
}

パッケージを追加してみる

[composer.json]

    "require": {
        "monolog/monolog": "1.0.*"
    }
$ composer install

初回はvendorディレクトリが自動で作られ、以降はvendor内にパッケージがインストールされる。

実行ファイルを作る

まだ、パッケージしかないので、実行ファイルを空で作っておく。

$ touch index.php

とりあえず空で。後で書き足す。
土台は完成。

自動読み込みの設定

公式より

自動ロード情報を指定するライブラリーの場合、Composerはvendor/autoload.phpファイルを生成します。このファイルをインクルードして、追加の作業なしでこれらのライブラリが提供するクラスの使用を開始できます。

ということなので、index.phpに一旦これだけ書いておく。
[index.php]

<?php
require __DIR__ . '/vendor/autoload.php';

動かしてみる

最低限の準備ができたので実際に動かしてみる

実行ファイルに追記

[index.php]

<?php
require __DIR__ . '/vendor/autoload.php';

$log = new Monolog\Logger('name');
$log->pushHandler(new Monolog\Handler\StreamHandler('app.log', Monolog\Logger::WARNING));
$log->addWarning('Foo');

実行

php index.php

app.log
が作られ、ログが出力されているのが分かる。

オートロードの設定を追加する

インストールしたパッケージのオートロードはできるようになったが、
自分で作成したファイルについては、追加で設定が必要。

クラスを作る

[sample/app/Greeting/Greeting.php]

<?php
namespace App\Greeting;

class Greeting
{
    public function hello()
    {
        echo 'hello';    
    }
}

helloメソッドを呼ぶと、helloを出力するだけのクラス。
ディレクトリに合わせてnamespacceを付けた。

使ってみる

[index.php]

+ $greeting = new App\Greeting\Greeting();
+ $greeting->hello();

実行

$ php index.php

当然失敗する。
エラー文

PHP Fatal error:  Uncaught Error: Class 'App\Greeting\Greeting' not found in ~~~index.php

要するに、「そんなクラス、index.phpで見つかりませんけど」ということ。

これを、オートロードするようにする。

composer.jsonを修正

[composer.json]

    "autoload": {
        "psr-4": {"App\\": "app/"}
    }

Appというnamespaceがappディレクトリを指すように設定した。

設定を反映させる。

$ composer dump-autoload
Generating autoload files
Generated autoload files

再度、実行してみる。

$ php index.php
hello

helloが出力されれば、完了。

まとめ

普段PHPを触る時、何の気なしにとりあえず慣れているLaravelでやっていた。
いろいろ便利だし。
ただ、特定のライブラリをちょっと試したいとか、
そういう時はこっちの方が準備早いし楽そうだと思った。

WSLにbrew(とnodebrew)入れてLaravel環境を作る

前提条件

Windows端末
・WSL2が使える状態になっている

この辺はググればすぐ出るので省く。

WSLにHomebrewをインストール

# WSLのbashを開く
wsl -l -v

公式をコピー
The Missing Package Manager for macOS (or Linux) — Homebrew

$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"

しばらく待つ

続いてLinux用Homebrewのセットアップ。公式に従う。
Homebrew on Linux — Homebrew Documentation

$ test -d ~/.linuxbrew && eval $(~/.linuxbrew/bin/brew shellenv)
$ test -d /home/linuxbrew/.linuxbrew && eval $(/home/linuxbrew/.linuxbrew/bin/brew shellenv)
$ test -r ~/.bash_profile && echo "eval \$($(brew --prefix)/bin/brew shellenv)" >>~/.bash_profile
$ echo "eval \$($(brew --prefix)/bin/brew shellenv)" >>~/.profile

確認

$ brew -v
Homebrew 2.5.8
Homebrew/linuxbrew-core (git revision 724b513; last commit 2020-11-02)

PHPのインストール

とりあえず確認

$ php -v

Command 'php' not found, but can be installed with:

sudo apt install php7.4-cli

phpが入っておらず、コマンドを教えられるが、brewから入れる。

$ brew install php

# 別のバージョンやパッケージを探す場合
$ brew search php

# 旧verを入れる場合
$ brew install php@7.2

しばらく待つ

$ php -v
PHP 7.4.12 (cli) (built: Oct 30 2020 08:37:38) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.12, Copyright (c), by Zend Technologies

問題なし *執筆時のstableバージョンは7.4

Composerのインストール

$ brew install composer

$ composer -v
   ______
  / ____/___  ____ ___  ____  ____  ________  _____
 / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
                    /_/
Composer version 2.0.4 2020-10-30 22:39:11
...

以上

node.jsを入れる

使い慣れているので、nodebrewで入れてみる

$ brew install nodebrew

# 確認
$ nodebrew -v
nodebrew 1.0.1

# 初期セットアップ
$ nodebrew setup

# パスを通す
$ echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.bash_profile

# 最新の安定板をインストール
$ nodebrew install-binary stable

$ nodebrew list
v14.15.0

current: none

# インストールしたバージョンを使用するよう設定する
$ nodebrew use v14.15.0
use v14.15.0

$ node -v
v14.15.0

$ npm -v
6.14.8

あとは普通にLaravelプロジェクト作成していくだけ。 以上。

SQLのWINDOW関数についての覚え書き

SQLはちょいちょい触ってはいるが、今の仕事では使ったことがないWINDOW関数というものを知った。

ちょっと特徴的な動作をするので、簡単にメモっておく。

簡単な例

SQL

SELECT sample_date AS cur_date,
    MIN(sample_date)
    OVER (ORDER BY sample_date ASC
        ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING)
    AS latest_date
FROM date_table;

取り出されるデータ

cur_date latest_date
2018-02-01
2018-02-02 2018-02-01
2018-02-05 2018-02-02
2018-02-07 2018-02-05
2018-02-08 2018-02-07
2018-02-12 2018-02-08

何が起きているのか

だいたい、下記のように理解した。

-- 1. 集計関数
MIN(sample_date)
-- 2. グループ化と順序付け
    OVER (ORDER BY sample_date ASC
-- 3. 範囲指定
        ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING)
    AS latest_date

1. 集計関数

集計関数は、SUM, AVG, MAXなど。
元のSQLの「1つのレコードの値として」取り出されるため、
後述する2, 3の条件から1つの値を取り出す必要がある。

2. グループ化と順序付け

ここでは

OVER (PARTITION BY ~ ORDER BY ~ 

の形で記述する。

・PARTITION BY句
→グループ化(通常のGROUP BY句に近い)
・ORDER BY句
→順序付け(通常のORDEY BY句と一緒)

両方使っても良いし、片方だけでも良い。

3.範囲指定

ここでは、ROWSかRANGEで範囲を指定する。指定しなければ全範囲が対象になる。

・ROWS
→行数での範囲付け
・RANGE
→値での範囲付け

ROWSは、前後n個とか直近のとか、値が明確じゃない時に使える。
RANGEは、過去n日とか、決まった値の範囲で集計したい場合に使える。

・PRECEDING
→現在行の前に範囲を広げる
・FOLLOWING
→現在行の後ろに範囲を広げる

BETWEENを使わない場合、現在行が終点となる。

まとめ

最初見た時は一瞬「なんだこれ?」となったが、かなり便利そう。
過去、無駄に複雑に組んだサブクエリとか、 これで行けたんじゃないかってやつありそうな気がする。

中古のDynabookにUbuntuを入れて開発用PCにしてみた感想

*技術記事ではないです。

先日、PCを買い替えたいと思い、秋葉原を巡ってきた。
もともと家にあった、プログラマとは思えない低スペ端末では限界を感じたので。

端末はWindowsにして、Linuxを入れようかと思っていた。
開発をしていると、ローカルマシンでもLinuxコマンドが使えないと色々と不便な時がある。
が、それだけを理由にMacにするのも違う気がしたし、単純に使ったことのないOSへの興味があった。

使い道としては、
仮想環境を立ち上げてのweb開発(Docker,PHP,node.js)がメイン。
デザイン系のソフトは使わない。
ゲームもやらない。

以上を踏まえてのそれぞれの個人的なポイントとしては

Mac
[メリット]
UNIX系コマンドが使える
トラックパッドの操作感は心地よい
・イケてるWeb系感がある
[デメリット]
・スペックに対して割高感がある
・端子類が癖(サンダーボルトとか揃えるのだるい)
・仕事で使っているので目新しさはない

Windows端末 + Linux
[メリット]
・USB TypeA端子がある
HDMI端子も割とある
・中古でそこそこのスペックのものが安く買える
・単純に興味がある
[デメリット]
・あまりオシャレ感はない物が多い

ざっくりこんな感じだった。
トラックパッドそんなに多用しないし、Macのデメリットはもうどうにもならない類のものだし
と思うと、少なくとも自分にとってMacを選ぶ大きな理由はなかった。

そもそも、自分はカフェでPC開いてドヤるタイプではないし、オシャレさとかどうでも良い。
そうなるともうWindows端末にLinuxを入れるというのが最適解に思えた。

ゆくゆくはそこそこお高めでもスペックの良いものを買いたいが、現状では自分の理想のPC像が曖昧なので、高い買い物はしたくなかった。

そんなこんなで下記の条件を設定し、秋葉原の電気街へ。

条件

購入する条件はざっくり以下のように決めていた。

・Windows10 Pro
・メモリ8GB以上 (16欲しいが後々交換できれば良い)
・よほど安くない限りはSSD 256GB以上
・CPUがあまりに古いものでない
・通常利用に支障のある不具合がない
・でかすぎず、小さすぎず。外にも持ち出せるくらいのサイズ感 ・HDMI端子は欲しい ・予算は5万まで。(実験的な面があるためできるだけ安く)

Linux入れるならOS関係ないやんとも思ったが、
初の試みなので、最悪Windowsのまま利用できるよう保険の意味。
Proじゃないと仮想環境の勝手が異なるので。

で、買ったもの。

購入端末情報

モデル: Dynabook R73/U
型番: PR73UFAA437AD11
OS: Windows 10 Pro 64bit
CPU: インテル Core i5-6300U
メモリ: 8GB(4GB×2)
HDD: 256 SSD
購入価格: 約3万
状態:
・天板にちょっと目立つシール跡?あり
・側面に若干の打痕あり
・端子類やバッテリーその他不具合なし

天板は最悪シールで隠す。
打痕はよく見ないと分からないくらい。
ということで、見た中で1番理想に近かったものに決定。

感想

ネットで買えば、同価格でもう少し状態良いものも買えたかもしれないが、
中古PCは初なので、流石にネットで買うのは少し気が引けた。

家に帰っていろいろと調べながら、とりあえずubuntu18.04を入れてデュアルブート化した。
いまのところ、かなり快適に感じる。
ただ、仮想環境立ち上げて、node.jsでHMRやって、ブラウザタブ立ち上げまくって...
となるとたまに重くなる。
これに関しては、メモリ拡張すれば改善されそう。

バッテリーは少し心配していたが、しばらく外して使ってても急激に減るようなことはない。 数時間は普通に大丈夫そう。

ハードに関しては、いろいろなWindows端末を触った経験がないので、あまり分からない。 キーボードは若干硬めな感じ。
ビジネスモデルなので、なかなか頑丈そう。
USB端子が3個あり、HDMIも繋げるので、使い勝手は良い。
それなりに軽いし、13.3インチというサイズもちょうどよい。
12.5インチから15インチくらいのものまでひと通り見てきたが、個人的には14前後がベストだった。
13以下はかなり小さく見えるし、14超えてくると、そこそこ重い。
最近のは大きくて軽いのも増えてるが。

しばらく使って気づいたことがあればまた追記したい。
半分お遊びのような感覚だったが、
3万で快適に使えるマシンと考えれば結構良い買い物をしたと思う。

RESTful APIのresponseのdataについて

SPA開発をしているが、正直ノウハウがなさすぎる状態なので
後になっていろいろと不都合な点が出てくる。

その中でも先に考えておきたかったことがこの記事。

qiita.com

書いてあることそのままなんだけど、
何かしらの登録処理

正常に登録できたらその値を使って次の処理
みたいなことがちょくちょくある。
SPAの場合、もう一度GET飛ばす?ローカルのstateでやる?みたいなことになるけど、
・GET飛ばす→無駄な通信が多く走る
・ローカルのstate→実際のサーバー内の処理を通せないので、形式を正確に合わせられない
とか問題がある。

なので、正常に処理が完了したからと言って

return true;

のような返却はしないようにする。

設計って大事だなあ。
設計するにしても、こういう経験をして一つ一つ身につけて行くしかないんだけど。

最近使ったVueのUIライブラリメモ


ここ最近業務で触れたVue用UIライブラリのメモです。

vue-carousel
普通のカルーセル
採用しなかったが触れてみたので。
Vue Carousel

vue-awesome-swiper
もうひとつカルーセル
こっちの方がいろいろ出来そうで良さげだったので採用した。
vue-awesome-swiper | Homepage | Surmon's projects

vuedraggable
ドラッグアンドドロップで移動できる。
VueでD&Dやるならほぼこれで決まりっぽい。
調べてもこれ以外あまり出てこないし、機能的にも十分。
vuedraggable

vue-scrollto
ページ内リンクへのスムーススクロールが簡単にできる。
GitHub - rigor789/vue-scrollto: Adds a directive that listens for click events and scrolls to elements.

vue-multiselect
高機能なサジェスト対応セレクトボックス。
高機能な分、ちょっと癖がある。
Vue-Multiselect | Vue Select Library

v-odometer
回転しながら数値を表示できるアニメーションライブラリ。
odometer.jsのラッパー。
必要で使ったは良いが、個人的にはあまり好きなUIではない。
GitHub - JefferyHus/v-odometer: Odometer VueJS component

v-tooltip
ツールチップ表示。使い方がめっちゃ簡単。
v-tooltip demo

vuejs-datepicker
シンプルなdatepicker。
日付単体だけであれば、十分。
GitHub - charliekassel/vuejs-datepicker: A simple Vue.js datepicker component. Supports disabling of dates, inline mode, translations

vue-ctk-date-time-picker
高機能な日時選択カレンダーライブラリ。
複数、レンジでの選択、時間の選択までカバー。
マテリアルデザイン&レスポンシブ対応でかなり強い。
欠点として、重い。日付操作の重量級ライブラリ「moment」に依存しているので余計に。
GitHub - chronotruck/vue-ctk-date-time-picker: VueJS component to select dates & time, including a range mode

v-calendar
カレンダー表示。
インライン表示のカレンダーとして使ったが、datepickerとしても使える。 Introduction | V-Calendar

vue-chartjs
Chart.jsのラッパー。
グラフといえばとりあえずこれ。
最初に | 📈 vue-chartjs

vue-fontawesome
Fontawesomeのvue版。
GitHub - FortAwesome/vue-fontawesome: Font Awesome 5 Vue component

vue2-google-maps
Googlemap表示に使える。
高度なことは難しそうなので、その場合はライブラリ使わない方が良い。
UIライブラリとはちょっと違うけどついでに。
GitHub - xkjyeah/vue-google-maps: Google maps component for vue with 2-way data binding

まとめ

VuetifyのようなUIコンポーネントライブラリを使えば、たいていのものは実装できた印象。
デザイン的に統一感も出しやすいので、以下のような場合は素直に頼るのもあり。
・UIに強いこだわりがない
・ある程度の規模になることが見込まれる
・強いエンジニアがいない

ただ、この手のライブラリは初期の学習コストがかかるので、
都度ライブラリ選定する方が、必要に応じて調べれば良いので簡単といえば簡単。