かきスタンプ

福岡でフリーランスの物流系のエンジニアやってます。

Laravel:artisan route:list コマンド実行時の「_debugbar..」の情報をカットする

Laravel Debugbar は便利なんだけど、artisan route:list コマンドでルーティング情報をリストアップする時、先頭が「_debugbar」というノイズが入って来ます。

ですが、Laravel 8.34 以上なら、「--except-path」のオプションを付けると、上記のノイズを除去できます。

コマンド内容

php artisan route:list --except-path _debugbar

以下、Laravel 8.5.16 で実行しています。

--except-path オプションなし

f:id:kakisoft:20210507005726p:plain

--except-path オプションあり

f:id:kakisoft:20210507005749p:plain


参考
https://github.com/barryvdh/laravel-debugbar/issues/1046

Laravel:migration 実行時、MySQL の時だけ実行するコマンドを設定する

Laravel の migration は便利なのですが、テーブルのスキーマ定義が、Laravel の命令だけで解決できない事があります。

例えば、「テーブル名にコメントを付ける」といった命令は用意されていないため、実行したい場合は DBドライバごとの固有のコマンドを使用する必要があります。( Laravel 8 時点)

具体的には、DB::statement メソッドにて、ALTER TABLE コマンドを実行します。

しかし、ALTER TABLE コマンドは、ほとんどの場合、RDB固有のコマンドとなってしまうため、migration の本流に載せるのは避けたい。

そんな感じで、「データベースドライバが MySQL の時だけ実行したい」または「SQLite の時だけ実行したい」といった場合、getDriverName() にて、データベースドライバを名を取得して、識別する方法があります。

具体的には、以下のようなコード。

    public function up()
    {
        if (DB::getDriverName() !== 'mysql') {
            return;
        }

        DB::statement("ALTER TABLE `users` COMMENT 'ユーザマスタ'");
    }

上記の場合、MySQL の時のみ、ALTER TABLE コマンドを実行します。
SQLite の場合、DB::getDriverName() にて 'sqlite' という値を取得します。)

コードを書く場合、変に switch文で分岐させるよりも、個別のドライバ用に migration ファイルを用意して、該当のドライバでなければ早期リターンする、という構造がいいんじゃないかと思います。

Laravel : 【MySQL】int のサイズを指定しているにも関わらず、column_type が「int(11)」となってしまう

MySQL のバージョン : 5.7
Laravel のバージョン: 8.16.1
PHP のバージョン: 7.4.7
 
Laravel で migration ファイルにてテーブルのカラムを追加する時、こんな感じで intのサイズを指定する事ができる。

    Schema::table('projects', function (Blueprint $table) {
        $table->integer('category_code')->length(3);
    });

が、実際に生成された MySQLスキーマを見ると、column_type は「int(11)」。
何故? 何か間違えた?

と思って調べてみたら、こんなのが見つかった。

https://stackoverflow.com/questions/25772759/schema-builder-length-of-an-integer

If you're using MySQL, you can't specify the length of an integer column. You can only choose between one of the available integer types, described at http://dev.mysql.com/doc/refman/5.1/en/integer-types.html

要は、「MySQL を使っている場合、長さの指定はできない」らしい。

どういう事かと言うと、MySQL の一部の型は、型によって既にサイズが確定しており、サイズを好き勝手に変える事は出来ないとの事。

その表が、こちら。
https://dev.mysql.com/doc/refman/8.0/en/integer-types.html

結論

MySQL で int を使うなら必ず『 int(11) 』になるけど、MySQL の仕様上、仕方ないから勘弁してね 」

じゃ、tinyint はどうなの?
という事で調べてみたら、こんなのがあった。

Laravelにてテーブルの既存カラムをtinyint型に変更できない問題

要は、
「int → tinyint に変更できない」
との事。(逆なら可)

逆が出来ないという事は、rollback が正常に動かないという事なので、採用は慎重に、というか見送った方がいいだろ。

実際、自分も余計なエラーに悩まされたし。

という訳で、int、bigint を使う場合は、デフォルトの長さでOK。
(というかそれ以外できない)

NVM for Windows を使ったけど Node.js のバージョンが切り替わらない! そんな時は、環境変数を見てみよう。

NVM for Windows を使うと、Windows 上で Node.js のバージョン管理ができるのですが、バージョンが切り替わらない現象に遭遇しました。
以下、その対策です。

NVM for Windows のインストール

Chocolatey(パッケージマネージャー)を使用しています。Chocolateyのインストール方法は、こちらでも。
ちなみに公式サイトはこちら

choco install nvm

別バージョンの Node.js をインストール

例:v13.7.0

nvm install v13.7.0

Node.js のバージョンを切り替え

例:v13.7.0

nvm use 13.7.0

これで Node.js のバージョンが切り替わってるはずが

λ node -v
v14.4.0

こんな感じで、マシンにインストールされている Node.js のバージョンが表示されました。

対策

環境変数が正常に設定されていない可能性があるので、設定し直します。

まず、コマンドプロンプトで「where nvm」と入力し、nvm のパスを調べます。
PowerShell には where コマンドは無いみたい)

C:\>where nvm
C:\ProgramData\nvm\nvm.exe

今回のケースの場合、「C:\ProgramData\nvm」を使用します。

システムの環境変数に、以下を追加します。

変数名 : NVM_HOME
変数値 : C:\ProgramData\nvm

続いて、コマンドプロンプトで「where node」と入力し、node.js のパスを調べます。

C:\>where node
C:\Program Files\nodejs\node.exe

今回のケースでは、「C:\Program Files\nodejs」を使用します。

システム環境変数に、以下を設定します。

変数名 : NVM_SYMLINK
変数値 : C:\Program Files\nodejs

こんな感じになります。
f:id:kakisoft:20200607113304j:plain

その後、環境変数の設定内容を反映させます。
(コンソールのウィンドウを開きなおす)

それでもバージョンが切り替わらない場合

公式サイトから配布されているインストーラを使用してください。
https://github.com/coreybutler/nvm-windows/releases/

nvm-setup.zip を選択し、「nvm-setup.exe」を起動してインストール。

f:id:kakisoft:20200607113316j:plain

こんなメッセージが出た場合は「はい」を選択します。
多分、この時に Node.js と上手い事やってくれてるんじゃないかと思います。

Laravel : $this->validate にて、カスタムメッセージを使用する

Laravel でバリデーションをする時、FormRequest を継承したクラスを定義しなくても、コントローラに以下のように書く事でバリデーションができます。

FormRequest を使うほどの汎用性もボリュームもない場合は、この方法でも良いのではないでしょうか。

    $this->validate(
        $request,
        [
            'title' => 'required|min:3',
            'body'  => 'required'
        ],
    );

エラーメッセージをカスタマイズしたい場合、フォームリクエストを使用したときは messages() メソッドにその内容を書いていくけど、この場合はどうすれば?
と思って調べてみた。

単に、validate の第2引数に、メッセージの内容を渡すだけでOKです。

    $this->validate(
        $request,
        [
            'title' => 'required|min:3',
            'body'  => 'required'
        ],
        [
            'title.required' => 'please enter title.',
            'body.required'  => 'please enter body.'
        ]
    );

Validatorファサードを使用する場合、こんな感じ。

      \Validator::make($request->all(),
          [
              'title' => 'required|min:3',
              'body' => 'required',
          ],
          [
              'title.required' => 'please enter title.',
              'body.required'  => 'please enter body.'
          ]
      )->validate();

PHP:JSON エンコードした時に「/」が「\/」になる挙動を回避

通常、json_encode した場合、「/」は「\/」にエスケープされます。

$array_data = [
    'message' => 'Please register as /regist_users',
];

echo json_encode($array_data);
//=> {"message":"Please register as \/regist_users"}

エスケープさせず、そのまま「/」を表示したい場合、JSON_UNESCAPED_SLASHES オプションを使います。

$array_data = [
    'message' => 'Please register as /regist_users',
];


echo json_encode($array_data, JSON_UNESCAPED_SLASHES);
//=> {"message":"Please register as /regist_users"}

 
 


<参考>
https://www.php.net/manual/ja/function.json-encode.php
https://www.php.net/manual/ja/json.constants.php

PHP:ファイルを読み込む関数の使い分け(file, fopen, readfile, file_get_contents)

PHP:ファイルを読み込む関数の使い分け(file, fopen, readfile, file_get_contents)

PHPでファイルを読み込むビルトイン関数は、結構色々あります。

  • file
  • fopen
  • readfile
  • file_get_contents

等。

以下の条件によって、使い分けをしていけばよいのではないでしょうか。

  • テキストか、バイナリか
  • ファイルサイズ
  • どんな使い方をするのか

という訳で、以下、各関数について。

file

https://www.php.net/manual/en/function.file.php

テキストファイル限定。(改行コードを区切り文字として使うため。)
すべてを変数(メモリ)に一旦貯めるので、あまりにも大きいファイルの使用には向かない。

ファイルの中身が配列になる。
改行区切りのテキストファイルを扱うのに適している。

使用例
// ファイルの内容を配列に取り込みます。
$file = file(__FILE__);

// 行単位で出力
foreach ($file as $lines => $line) {
    echo "Line #{$line_num} : " . htmlspecialchars($line);
}

fopen

https://www.php.net/manual/ja/function.fopen.php

テキスト・バイナリどちらでも使える。
ファイルの大小に関係なく使用可。

自身で色々制御する際に使う。

使用例
// ファイルを開く(戻り値は、FilePointer と呼ばれる特殊な変数)
$handle = fopen(__FILE__, "r");  // readonly

// ファイル内容を出力
while ($line = fgets($handle)) {
  echo $line;
}
// ファイルポインタをクローズ
fclose($handle);

readfile

https://www.php.net/manual/ja/function.readfile.php

テキスト・バイナリどちらでも使える。
巨大なファイルでも使用可。(詳細は上記リンクを参照)

ファイルの中身をそのまま表示する。
何かしらの制御を加えたいなら、別のを使った方がいいかも。

使用例
readfile(__FILE__);     // コンソールに、このファイルの内容が出てくる

file_get_contens

https://www.php.net/manual/ja/function.file-get-contents.php

テキスト・バイナリどちらでも使える。
file と同じ理由で、あまりにも大きいファイルの使用には向かない。

使用例
$current = file_get_contents(__FILE__);

print_r($current);

引数に URLを使用すると、GETリクエストとして使用可。
というか、そっちの使い方しかしてない人も多いかもしんない。
パラメータ次第で PUTにする・パラメータを渡す・SSLエラーを無視する、といった HTTPリクエストライブラリと同様に使う事が出来なくはない。

その他

xml ファイルを読むときは simplexml_load_file を、
ini ファイルを読むとき parse_ini_file を使えばいいんじゃないかと思います。

間違ってたら、ご指摘いただけると助かります。