今日もメモをのこそう

あとでみるメモ代わり

シェルで画像を一括ダウンロードする

最近はWindowsでもWSL2でLinuxのシェルを使えるから便利。 何に使うというわけじゃないけど、規則的な名前で存在する画像(jpg or png)をローカルに落とすシェルをかいた。

#!/bin/bash

page= # ページ数を入れる
baseUrl='' # URLをいれる
for i in `seq 1 $page`
do

    ext='jpg'

    n=`printf %03d $i`
    url=$baseUrl$i
    fileName=$n.$ext
    if [ -e $fileName ]; then
        continue
    fi
    
    echo $url.$ext
    wget $url.$ext
    if [ $? != 0 ]; then
        ext='png'
        wget $url.$ext
    fi
    file=$i.$ext
    no=`echo $file | sed -e 's/\(.*\)\.\(.*\)/\1/g'`
    ext=`echo $file | sed -e 's/\(.*\)\.\(.*\)/\2/g'`
    newNo=`printf %03d $no`
    newFile=$newNo.$ext
    if [ $file != $newFile ]; then
        mv $file $newFile
    fi

    echo $i/$page
done

ローカルに落とすときに、3桁の0埋めしている。 Windows環境ではソートするときに、文字列としてソートするので。

Laravelをgit cloneしてみたら500エラーになった

勉強がてら、Laravelをいじりgitで管理してみたところ発生した事象

結論

Laravelでgit cloneしたときは特定の手順が必要
git cloneしたLaravelプロジェクト内で以下の手順を実施すると画面表示される。

$ composer install
$ cp .env.example .env
$ php artisan key:generate

.envは環境情報が入ってるので必要に応じて変更する必要があるが、いったんは画面表示までを目標としてるので完了。

気づくまでの流れ

git commitしたときにvenderフォルダはコミットしてなかったので、まずはcomposer installを実施した。 だが、アクセスすると、storage/logs/laravel.logに以下のようなログが出る。

production.ERROR: No application encryption key has been specified. {"exception":"[object] (Illuminate\\Encryption\\MissingAppKeyException(code: 0): No application encryption key has been specified. at /home/www/laravel/vendor/laravel/framework/src/Illuminate/Encryption/EncryptionServiceProvider.php:79)
[stacktrace]

何やら鍵がないらしい。コマンドが用意されているらしいので実行すると、、、エラーになる。

$ php artisan key:generate

   ErrorException 

  file_get_contents(/home/www/laravel/.env): Failed to open stream: No such file or directory

  at vendor/laravel/framework/src/Illuminate/Foundation/Console/KeyGenerateCommand.php:107
    103▕     {
    104▕         file_put_contents($this->laravel->environmentFilePath(), preg_replace(
    105▕             $this->keyReplacementPattern(),
    106▕             'APP_KEY='.$key,
  ➜ 107▕             file_get_contents($this->laravel->environmentFilePath())
    108▕         ));
    109▕     }
    110▕ 
    111▕     /**

      +16 vendor frames 
  17  artisan:37
      Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))

enviromentFilePath()がないというエラー。
ということで作成する。Laravelのサンプルファイルをそのまま使う。(内容は適宜変える必要があるかも)

$ cp .env.example .env 

この後、再度実施する。

$ php artisan key:generate
Application key set successfully.

問題なく実行できたので画面を見ると、Laravelが起動できた。

PHPフレームワークLaravel入門(第2版)を読みながら 

本を読みながらLaravelの勉強をしてたんですが、以下に突っかかってしまったのでメモ。
流れとしては、リクエストとレスポンスを見てみようって話の中で以下のソースがありました。
※本としては序盤も序盤なので、$responseをコントローラに渡すのおかしくない?というツッコミはなし。

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Http\Response;

class HelloController extends Controller{

    public function index(Request $request,Response $response){
        $html =  <<<EOF
        <html>
            <head>
                <title>Hello/Index</title>
                <style>
                body {font-size:16pt; color:#999;}
                h1 { font-size:120pt; text-align:right; color:#eee;
                    margin:-50px 0px -120px 0px;}
                </style>
            </head>
            <body>
                    <h1>Hello</h1>
                    <h3>Request</h3>
                    <pre>{$request}</pre>
                    <h3>Response</h3>
                    <pre>{$response}</pre>
            </body>
        </html>
EOF;
    
                $response->setContent($html);
        return $response;

    }
}

何に突っかかったかというと

$response->setContent($html);
return $response;

特に説明がなく急にでてきたので、どっから出てきた?という感じでした。
今までretun $htmlみたいにhtmlソースをそのまま返してたのに、??という感じでした。

おそらく意図としては、responseの話が出てきたので使ってみようということだと思います。
正直、今までの流れだったら以下のように書くのが筋としては正しいかなという気もします。

return $html

ただ、であればreturn内容は$responseで返すパターンでした、とか、
今まで通りhtmlで返してもLaravel上では変わりませんよとか、
何かしらの注記をつけてほしかったかなと思いました・・。

本は簡単に読めるのでとっかかりとしては楽なんですが、変なところで引っかかるので一長一短ですね。。
正しい情報をつかみたいのであれば、公式ページが一番かもです。基本的に日本語になってるし。

warning: LF will be replaced by CRLF in の強引な対処

gitでcommitするときに「warning: LF will be replaced by CRLF in」と出る場合の強引な対応。 一人で開発してるなら以下でオッケー。

git config --global core.autoCRLF false

複数人で開発してるのであれば、ほかの人とルールを確認する。
ざっくりだと、Windowsで開発してるならtrue,Linux系ならinputにする

git config --global core.autoCRLF true
か
git config --global core.autoCRLF input

dockerでLinux系環境構築して開発してるのでinputにしよう。 そもそも改行コードがばらついてるのがよくないので改行コードをちゃんと合わせるのが将来的に正しいと思われる方法。

PHPの無名関数でuse()って意味があるの?

無名関数のuseについて「これって意味あるの?」と急に思ったのでメモ。

今回のオチ

意味はもちろんある。
無名関数はコールバックでよく使われていて、その時に引数を渡すときにuseを使う必要がある。

無名関数のおさらい

無名関数って関数名を使わないので少しスマートに記載できる。
※詳しくはネットに転がってるのでさっくり記載。
例としては以下のような感じ

$example = function () {
    var_dump('hello');
};
$example();

ひっかかったところ

何にひっかかったかというと「無名関数に引数を渡す」とき。
useを使うと無名関数に引数を渡せるのですが、普通の関数と同様にuse使わなくても引数は渡せる

(useを使わない場合)
$message = 'hello';
$example = function ($message){
    var_dump($message);
};
$example($message);

(useを使う場合)
$message = 'hello';
$example = function () use ($message) {
    var_dump($message);
};
$example();

上記は、両方ともhelloが出力される。 これって、ほとんど変わらなくない?と思ってしまったんですね。

一応の納得

無名関数をコールバックの時によく利用されてる。array_filterとか、preg_replace_callbackとか。
たとえば、array_filterだと以下のような感じ。

// $arrayから10以上のものだけをフィルタリングする。
$array = [6, 7, 8, 9, 10, 11, 12];
print_r(array_filter($array, function($var) {
        if ($var > 10) { return true; }
}));

// 結果
Array
(
    [5] => 11
    [6] => 12
)

この時の無名関数の引数はarray_filterから渡される配列の中身となり外部(array_filterの外)からは渡せない。 この無名関数に、外部から引数を渡す方法が(多分)useということになる。 上記では、下限値10を関数内で指定しているが、array_filterの外で指定して渡してみる。

$array = [6, 7, 8, 9, 10, 11, 12];

$limit = 10;
print_r(array_filter($array, function($var) use($limit) {
        if ($var > $limit) { return true; }
}));

Array
(
    [5] => 11
    [6] => 12
)
無事に渡せて同じ結果になった。

ということで「コールバックの時は引数を改めて指定することができない」から、すでにある変数を引数にする場合はuseを使わないといけない。
ネットでよく見たサンプルは、無名関数を一度変数に入れているサンプルだったので、useの有用性がよくわかんなかったというお話でした。

初めてのMySQL -データベースの操作-

インストールは完了済みの想定。 ※ちなみに私はpostgresの経験しかないです。

  • MySQLにログインする
mysql --user=root --password={パスワード} --host=localhost
もしくは
mysql -user root -p{パスワード} -h localhost

postgresと違って、「MySQLサーバ」にログインするという形。
postgresだと、上位データベース(?)の「postgresDB」に入るような形なので新鮮。

  • データベースを確認する すでにあるデータベースを確認。
    デフォルトの4つが既に存在。
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)
  • データベースを作成 今回はLaravel勉強用だったので、「laravel_db」にしてみる
    show databasesをすると増えてることも確認できる。
mysql> CREATE DATABASE laravel_db;
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| laravel_db         |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)
  • データベースにログイン 作ったデータベースにログインしないといけないので、以下コマンドを打ちます。
mysql> USE laravel_db

実施した結果、Database changedと出れば、問題なく切り替え完了。
ほんとに切り替えられているか確認するコマンドは以下。

mysql> select database();
+------------+
| database() |
+------------+
| laravel_db |
+------------+
1 row in set (0.00 sec)

きちんと切り替えられている。

補足)データベースにログインする前に、上記コマンドをたたくとどうなるか?
ログイン後、すぐに以下コマンドを打つとNULLと表示される。

mysql> select database();
+------------+
| database() |
+------------+
| NULL       |
+------------+
1 row in set (0.00 sec)

DockerでMysqlを作ってみる

個人開発用にMysqlを使ってみたい。
Dockerで作ってみよう。

今回のオチ

DockerHubから取得したMysqlのイメージだったら環境変数はきちんとつけよう!

まずはDockerfileを用意

Dockerfileはシンプルに以下で試す。

    FROM mysql
    EXPOSE 3306  

※ちなみに、Mysqlのデフォルトポートは3306、postgresは5432。

イメージを作って起動(失敗編)

イメージ名、コンテナ名両方とも「mysql」とする。

docker build -t mysql .
docker run -d -p 3306:3306 --name mysql -it mysql

起動するとコンテナは作らているが、以下のようなエラーになってDockerが起動できない。

[ERROR] [Entrypoint]: Database is uninitialized and password option is not specified
    You need to specify one of the following:
    - MYSQL_ROOT_PASSWORD
    - MYSQL_ALLOW_EMPTY_PASSWORD
    - MYSQL_RANDOM_ROOT_PASSWORD

平たく言うと、Mysqlのパスワードを3つのどれかで指定してね、ということらしい。
DockerHubの使用法には「MYSQL_ROOT_PASSWORD」を指定してたので、それで試す。

イメージを作って起動(成功編)

いったん失敗したコンテナを消して、再度作り直す。
基本は変わらないですが、環境変数MYSQL_ROOT_PASSWORD」を指定。
ネーミングセンスがないので以下は全部「mysql」にしました。(なんでも大丈夫です)

docker rm mysql
docker run -d -p 3306:3306 --name mysql -e MYSQL_ROOT_PASSWORD=mysql -it mysql

これで構築は完了