php+sqliteをdockerで動かすメモ
dockerの練習用にphp+sqliteなサーバを作ってみたのでメモ
Dockerfile
FROM php:5.6-apache RUN apt-get update && apt-get install sqlite3 libsqlite3-dev -y
build
docker build ./ -t php5_sqlite
run
docker run -d -p 80:80 -v /Users/fujitanao/git/htmlonly/html:/var/www/html --name php5_sqlite_container php5_sqlite
stop
docker stop php5_sqlite_container
start
docker start
container remove
docker rm php5_sqlite_container
markdownで書いたテーブル仕様書からsql文を生成する
テーブル仕様書をmarkdownで管理したいって要望があったので作ってみた
まだ開発中。markdownから階層構造作るところで多分バグがある
サンプルのテーブル仕様書はこんな感じ
contract: 契約
contract_state: 契約状態テーブル
カラム名 | 型 | NOT NULL | 補足 | index | 説明 |
---|---|---|---|---|---|
contract_id | VARCHAR(13) | o | AUTO_INCREMENT PRIMARY KEY | 契約ID | |
state | VARCHAR(10) | o | contract_state | 契約状態 |
extra: その他
term
extra_start_e: その他開始イベント
カラム名 | 型 | NOT NULL | 補足 | index | 説明 |
---|---|---|---|---|---|
contract_id | VARCHAR(13) | o | PRIMARY KEY | 契約ID | |
start | date | o | extra_start | 開始日 |
extra_end_e: その他終了イベント
カラム名 | 型 | NOT NULL | 補足 | index | 説明 |
---|---|---|---|---|---|
contract_id | VARCHAR(13) | o | PRIMARY KEY | 契約ID | |
end | date | o | extra_end | 終了日 |
extra_state: その他状態テーブル
カラム名 | 型 | NOT NULL | 補足 | index | 説明 |
---|---|---|---|---|---|
contract_id | VARCHAR(13) | o | AUTO_INCREMENT PRIMARY KEY | 契約ID | |
state | VARCHAR(10) | o | extra_state | 契約状態 |
ここからCreateTable文を生成する
以下、動作確認
RUNボタンを押してね
集中したい
最近全然時間がありません
打ち合わせや割り込みがない時間が1日のうちで連続3時間ほしい...
今日の作業
10:00-10:30 ★FREE 10:30-11:30 MTG 13:00-14:00 MTG 14:00-15:00 ★FREE 15:00-16:00 ペア作業 16:00-17:00 MTG 17:00-18:00 ★FREE
こんなんじゃ集中して作業できねぇよ
TRY: 打ち合わせを15時までにする
15時以降をフリーにする
jsのクラスってコンストラクタに全部書いた方がよくね?
jsのクラスはこんな感じで書きます
class Position { constructor(x, y) { this.x = x; this.y = y; } getX() { return this.x; } getY() { return this.y; } getDistance() { return Math.sqrt(this.x * this.x + this.y * this.y); } }
この書き方の辛いところ
- フィールドをprivateにできないからxとyが外から丸見え。セッター呼び放題
- フィールドが増えるたびに
this.v = v;
をコンストラクタに書く必要がある
それならこっちの方がよくね?
class Position { constructor(x, y) { this.getX = () => x; this.getY = () => y; this.getDistance = () => Math.sqrt(x * x + y * y); } }
辛いところは全部解消されてる
しかもコンストラクタ引数をconstな変数に入れたらimmutableにもできる
class ImmutablePosition { constructor(_x, _y) { const x = _x, y = _y; this.getX = () => x; this.getY = () => y; this.getDistance = () => Math.sqrt(x * x + y * y); } }
どや
マルっとサクッとパラメータを受け取る
最近PHP+slimでAPIをたくさん作ってますがAPIの実装が面倒になってきた
たとえばアクセストークンを使って認証的なことをやろうとした場合、IF仕様はこうなる
アクセストークンは、リクエストヘッダー、または、GETの場合はクエリーパラメータ、または、POSTの場合はbodyに入れること
いろんなところから取得しなきゃでめんどくせーー
欲しいのはパラメータ
で、欲しいのはそのパラメータであって、それがヘッダーだろうとなんだろうと別にどうでもいい
なのでパラメータの取得方法を考えなくてもよくするミドルウェアを作った
$app->add(function ($request, $response, $next) { $params = []; forEach($request->getHeaders() as $key => $value) { $params[$key] = $value; } if($request->getQueryParams() != null) { forEach($request->getQueryParams() as $key => $value) { $params[$key] = $value; } } if($request->getParsedBody() != null) { forEach($request->getParsedBody() as $key => $value) { $params[$key] = $value; } } $request = $request->withAttribute('params', $params); return $next($request, $response); });
取得するときはこんな感じ
$params = $request->getAttribute('params');
APIの実装が楽になった
めでたし、めでたし
データを保存できるWebAPIを作ったら楽になった
最近は無料で使えるナントカ as a serviceが増えてきて、サービスを簡単に作れるようになって楽しい
例えばロジックはheroku + javaで堅牢に作れるし、定期実行はgoogle apps script(以下、GAS)でできる
あと足りないのはデータストア
てことで自分の身の回りでデータストアとして使えそうなものを探したら、サクラのレンタルサーバがあった!
プランがライトプランなのでsqliteしか使えないけど、なんとかなるはず!
てことで、データストア的なwebサービスを作ってみた
仕様
要するにwebAPI経由でデータの追加・更新・参照ができるサービスです
詳細はこんな感じ
- IDと状態を保存できる
- 状態を更新できる
- ID指定で状態を取得できる
- 過去の状態遷移履歴も取れる
- データは投入から1ヶ月で消える
- 認証はリクエストに固定のトークンを入れることで行う
- 環境: PHP + slim + SQLite
データが1ヶ月で消える仕様がミソ
sqliteだから大量データを保持したくないって理由もあるけど、実際1ヶ月くらい保持してくれるだけで十分なサービスがたくさんあるのでこの仕様で問題なし
利用例:ブログ更新通知サービス
せっかくなのでデータストアを使ったブログ更新通知サービスを作ってみた
使うのはGAS
基本的に定期的にRSSをクロールしてチャットに通知すればイイだけですが、すでに通知済みの記事は通知して欲しくない
そうなると通知したものを貯めるデータストアが必要になる
そこで今回作ったデータストアを使う
通知した記事のIDをデータストアに保存して、次回クロール時はデータストアにすでにあるかを確認してなかったら通知する
1ヶ月でデータが消える仕様があるので、翌月に同じ記事を通知してしまう可能性はあるけど、そこは日付見て「1ヶ月以上たった記事は通知しない」て処理いれれば問題なし
ロジックをまとめるとこんな感じ
- 定期的にRSSを取得する
- 記事の投稿日時が1ヶ月以内のものを抽出する
- 記事IDでデータストアに問い合わせてチャットに通知済みかどうかをチェックする
- 未通知だったら
- 記事をチャットに通知する
- データストアに通知済みとして保存
作った
GASで簡単に作れた
このデータストアは汎用的に使えて良さそう
APIのインターフェースとか認証周りとかをもう少し整理して公開できる状態まで持っていきたい
認証サービスを作ればいいのか?
結局AWSみたいにマイクロサービスがたくさん作られそうな予感
まとめ
データストアサービスを作ったら新たなサービス作りが簡単になった
この他にもマイクロサービスのアイデアがいくつか浮かんで楽しくなってきた
PHPで1970年からのミリ秒を取得する
サーバサイドをPHP + SQLiteにしてフロントをjavascriptで作るなら、日時はlong型で1970年からのミリ秒にしておいた方が良さそう でもPHPの標準関数でその値を取得する方法がなかったのでメモ 使えそうなものが2つ見つかった
現在日時から取得
$t = (int)floor(microtime(true) * 1000);
リクエスト日時から取得
$t2 = (int)floor($_SERVER['REQUEST_TIME_FLOAT'] * 1000);