TIL

Today I Learned. 知ったこと、学んだことを書いていく

【MySQL】 TBL2のレコードの値によって、TBL1のレコードをUPDATEする

  • 以下のようなデータを用意
CREATE TABLE table1(id int not null, name varchar (15)); 
CREATE TABLE table2(id int not null, gender char (1));

INSERT INTO table1 VALUES (1, 'takuya');
INSERT INTO table1 VALUES (2, 'taro');
INSERT INTO table1 VALUES (3, 'jiro');
INSERT INTO table1 VALUES (4, 'saburo');
INSERT INTO table1 VALUES (5, 'siro');

insert into table2 values (1, 1);
insert into table2 values (2, 2);
insert into table2 values (3, 1);
insert into table2 values (4, 2);
insert into table2 values (5, 2);
mysql> select * from table1;
+----+--------+
| id | name   |
+----+--------+
|  1 | takuya |
|  2 | taro   |
|  3 | jiro   |
|  4 | saburo |
|  5 | siro   |
+----+--------+
5 rows in set (0.00 sec)

mysql> select * from table2;
+----+--------+
| id | gender |
+----+--------+
|  1 | 1      |
|  2 | 2      |
|  3 | 1      |
|  4 | 2      |
|  5 | 2      |
+----+--------+
5 rows in set (0.00 sec)

複数テーブルを使ったUPDATE文の実行をしてみる

カンマを使う場合

table2.gender = 2のレコードと紐づくtable1のデータの値を更新してみる

update table1
, (select * from table2 where gender = 2) tbl2 
set
  table1.name = 'gender2' 
where
  table1.id = tbl2.id;
  • 結果は以下のようになる
mysql> select table1.id, table1.name, table2.gender from table1 left join table2 on table1.id = table2.id;
+----+---------+--------+
| id | name    | gender |
+----+---------+--------+
|  1 | takuya  | 1      |
|  2 | gender2 | 2      |
|  3 | jiro    | 1      |
|  4 | gender2 | 2      |
|  5 | gender2 | 2      |
+----+---------+--------+
5 rows in set (0.00 sec)

カンマを使わない場合

update table1 
  inner join (select * from table2 where gender = 2) tbl2 
    on table1.id = tbl2.id 
set
  table1.name = 'gender2'

inner joinを使っているところに注意する
もし、left joinにしてしまうと、table1の全レコードがupdateされてしまう

参考文献

【MySQL】MySQLでのBooleanの扱い

Mysqlのboolean型について調べてみた - Qiita の内容を自分の手で確かめてみた

環境

> docker-compose exec mysql mysql --version
mysql  Ver 8.0.16 for Linux on x86_64 (MySQL Community Server - GPL)

まとめ

  • booleantinyint(1)のどちらともtinyint(1)で CREATE TABLE される
  • true1false0で INSERT される
  • 値の比較は=isで変わる
    • where col = true1のデータ、where col = false0のデータ(想定通り)
    • where col is true0以外のデータ、where col is false0のデータ(想定と違う)

CREATE

booleanとtinyint(1)のテーブルを作成し、全く同じデータを入れてみた

> create table test_boolean (bool_col boolean);
> create table test_tinyint (bool_col tinyint(1));

booleantinyint(1)のどちらともtinyint(1)でカラムが作成される

> show create table test_boolean;
+--------------+--------------------------------------+
| Table        | Create Table                         |
+--------------+--------------------------------------+
| test_boolean | CREATE TABLE `test_boolean` (        |
|              |   `bool_col` tinyint(1) DEFAULT NULL |
|              | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+--------------+--------------------------------------+

> show create table test_tinyint;
+--------------+--------------------------------------+
| Table        | Create Table                         |
+--------------+--------------------------------------+
| test_tinyint | CREATE TABLE `test_tinyint` (        |
|              |   `bool_col` tinyint(1) DEFAULT NULL |
|              | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+--------------+--------------------------------------+

INSERT

falseをINSERTすると0

> insert into test_boolean values (false);
> select * from test_boolean;
+----------+
| bool_col |
+----------+
| 0        |
+----------+

trueをINSERTすると1

> truncate test_boolean;
> insert into test_boolean values (true);
> select * from test_boolean;
+----------+
| bool_col |
+----------+
| 1        |
+----------+

WHERE

  • where col = true1のデータ、where col = false0のデータが抽出できる
  • where col is true0以外のデータ、where col is false0のデータが抽出できる
    • これ知ってないとハマりそう。でも、基本、isじゃなくて、=で比較すればいいのかも?

以下のようなデータを用意

> insert into test_tinyint values (false), (true), (1), (0), (100), (-100);
> select * from test_tinyint;
+----------+
| bool_col |
+----------+
| 0        |
| 1        |
| 1        |
| 0        |
| 100      |
| -100     |
+----------+

=を使った抽出

> select * from test_tinyint where bool_col = true;
+----------+
| bool_col |
+----------+
| 1        |
| 1        |
+----------+

> select * from test_tinyint where bool_col = false;
+----------+
| bool_col |
+----------+
| 0        |
| 0        |
+----------+

isを使った抽出

> select * from test_tinyint where bool_col is true;
+----------+
| bool_col |
+----------+
| 1        |
| 1        |
| 100      |
| -100     |
+----------+

> select * from test_tinyint where bool_col is false;
+----------+
| bool_col |
+----------+
| 0        |
| 0        |
+----------+

参考文献

【PHP】LaravelでのCSRF対策

LaravelにはCSRF対策が簡単にできるような仕組みが組み込まれている。また、必ずCSRF対策をしないといけない。
そのため、formを使うときには必ず<form>内に@csrfを記述する必要がある

<form action="/create" method="POST">
    @csrf
    ...
</form>

@csrfは以下のように展開される(Ub7ebV8XbFCTtZyenNoFYyK9ctDzaj09wbp2R7IIの部分は毎回、ランダムな値になる)

<form action="/create" method="POST">
    <input type="hidden" name="_token" value="Ub7ebV8XbFCTtZyenNoFYyK9ctDzaj09wbp2R7II">
</form>

この_tokenも他の値と一緒に送信され、検証が行われる。もし、用意したトークンと一致しなかった場合、419 Page Expiredというエラーになる

CSRF(cross-site request forgeries: クロスサイトリクエストフォージェリ)

しーさふ と読む

Webアプリケーションの脆弱性の1つ

よそのサイトの機能を呼び出す攻撃
CSRFについてかみ砕いて説明してみる – blog.ISHINAO.net

別のサイトのページから悪意のあるリクエストを受け付けないようにする必要がある

以下のような方法が一般的

  1. トークンを埋め込んでページを表示
  2. ユーザがフォームに入力し、submitする
  3. 送られてきたトークンが正しいかどうかチェックする

参考文献

【PHP】composer globalでのインストール先

composer globalでインストールされるディレクトリは

composer global config home

で確認できる

> ls `composer global config home`
Changed current directory to /Users/user_name/.config/composer
composer.json composer.lock keys.dev.pub  keys.tags.pub vendor

参考文献

【PHP】MacにPHPとComposerをインストール

MacPHPとComposerをインストールした

PHP

brew install php

Composer

php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('sha384', 'composer-setup.php') === '48e3236262b34d30969dca3c37281b3b4bbe3221bda826ac6a9a62d6444cdb0dcd0615698a5cbe587c3f0fe57a54d8f5') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"
mv composer.phar /usr/local/bin/composer

しっかりとインストールされている

> composer -V
Composer version 1.8.5 2019-04-09 17:46:47

参考文献

【MySQL】CONVERT関数

CONVERT(expr, type)

例)符号付き数値に変換する

CONVERT(TBL.COL1, SIGNED)


以下のように暗号化されたカラムを復号化し、数値に変換するときに使う?

CONVERT(AES_DECRYPT(TBL.COL1, 'key-code'), SIGNED) 


暗号化されたデータがblobのカラムに入っていて、数値で比較しようとしたときにバグが出たから、SIGNEDに変換するようにして対応した

CONVERT(expr USING transcodinf_name)

例)文字コードUTF-8の文字列に変換する

CONVERT(TBL.COL1 USING utf8)

参考文献

【PHP】DockerでPHPの環境を作る

仕事で使えそうなPHPというものを家で勉強したいと思ったから、環境を作ることにした。

環境構築につまづきたくないから、Dockerを使うことにした

Docker で PHP の開発環境を構築する方法 - UPDATE をまんま実行したらできたけど、メモしておく。

Dockerfileを作成する

> mkdir php7-apache; cd php7-apache
> echo "FROM php:7.3.4-apache" > Dockerfile

imageのbuild

php_apache_imageという名前のimageをbuildする

> docker build ./ -t php_apache_image

マウント用ディレクトリの作成

ホスト側のディレクトリをコンテナにマウントするためのディレクトリを作成する

> mkdir html

このディレクトリにファイルを作成していく

コンテナの起動

> docker run -d -p 80:80 -v /Users/tamago324/src/php/php7-apache/html:/var/www/html --name php_apache_container php_apache_image

docker run -d -p {ホストのポート}:{コンテナのポート} -v {ホストのディレクトリ}/{コンテナのディレクトリ} --name {コンテナ名} {イメージ名}

こんな簡単にマウントできるのすごい

起動の確認

> docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
f19ca19f6f55        php_apache_image    "docker-php-entrypoi…"   2 minutes ago       Up 2 minutes        0.0.0.0:80->80/tcp   php_apache_container

STATUSがUPになっていれば起動している

Webページの作成

ホスト側のhtml/index.phpを作成する

<?php
phpinfo();

localhost/index.php にアクセスし、作成したページを確認する

いろいろ情報が出ていればOK!

とりあえず、PHPが動かせる環境ができたからよかった

少しずつやってみよう

Laravelというものを使いたい!!

参考文献