- 投稿日:
あると何かと便利だよねというので。
確認環境
Env | Ver |
---|---|
PHP | 8.0.29 |
サンプルコード
取り敢えずファイルをアップロードするだけのコード
<?php
if ($_FILES['image']) {
move_uploaded_file($_FILES['image']['tmp_name'], 'files/'. $_FILES['image']['name']);
} else {
?>
<html>
<body>
<form action="upload.php" enctype="multipart/form-data" method="POST">
<input type="file" name="image">
<button>upload</button>
</form>
</body>
</html>
<?php
}
- 投稿日:
ブラウザのタブがバックグラウンド状態になっているとJSの実行が止まることがあり、そうするとsetInterval()
が死ぬので、これを回避する技。
結論としてはWeb Worker APIのWorkerインターフェースを使うことで解決できる。
確認環境
Env | ver |
---|---|
Microsoft Edge | 126.0.2592.87 |
サンプルコード
/**
* @param {() => void} cb 実行するコールバック
* @param {number} interval 実行間隔
* @returns 停止用の関数
* */
const createWorkerInterval = (cb, interval) => {
const src = "self.addEventListener('message', (msg) => { setInterval(() => self.postMessage(null), msg.data) })";
const wk = new Worker(`data:text/javascript;base64,${btoa(src)}`);
wk.onmessage = () => cb();
wk.postMessage(interval);
return wk.terminate;
}
- 投稿日:
"hoge", "piyo", "fuga"
のように綺麗なCSVであるという前提。CSVファイルが巨大なので行読み込みする。
<?php
$db = new PDO('sqlite:./hoge.db');
$db->beginTransaction();
$fp = fopen("hoge.csv", "r");
$idx = 0;
if($fp){
while ($line = fgets($fp)) {
$row = createRow($line);
$db->exec(
'INSERT INTO hogehoge (`foo`, `bar`, `baz`)'
. ' VALUES '
.'(' . '"' . $row['foo'] .'", ' . '"' . $row['bar'] .'", ' . '"' . $row['baz'] .'"' . ')'
);
$idx++;
echo $idx . "\n";
}
}
fclose($fp);
$db->commit();
function createRow($text) {
$r1 = preg_replace('/"/', '', $text);
$row = explode(',', $r1);
return [
'foo' => $row[0],
'bar' => $row[1],
'baz' => $row[2],
];
}
トランザクションを張りっぱなしだが、exec毎にトランザクションを張りなおすと劇的に遅くなるのでやめたほうがいい(恐らく毎回同期処理でWriteが走っているのだと思う)
- 投稿日:
動機としてはcurlだと見えない部分があるので、自分でHTTPメッセージを手組みして送ってみたかった。
Node.jsとPHPのサーバーでリクエストが期待通り取得できたので、メッセージの実装としては問題ないと思われる。
検証用サーバー
以下のコードをNode.js v20.11.1を用いて検証
import http from 'node:http';
http
.createServer((req, res) => {
console.log(req.headers);
req.on('data', (chunk) => {
// body
console.log(Buffer.from(chunk).toString());
});
res.statusCode = 200;
res.end();
})
.listen(9999);
netcatコマンドによるリクエスト検証
GETリクエスト
echo -e 'GET / HTTP/1.1\r\nHost: localhost:9999\r\n\r\n' | nc localhost 9999
POSTリクエスト
echo -e 'POST / HTTP/1.1\r\nHost: localhost:9999\r\nContent-Length: 4\r\n\r\nhoge' | nc localhost 9999
備考
PHPで検証サーバーを作る場合
実際にAPサーバーでリクエストの中身をパース出来るかどうかの観点で見た場合にNode.jsよりPHPのが楽なので、PHPで作ってみた結果、軽くハマったので残しておく。
以下のコードを用いてPHP 8.0.29で検証サーバーを作る場合に、php -S 0.0.0.0:9999
としてサーバーを起動すると、Content-Type
ヘッダがない場合に正常な動作をしなかった。
<?php
var_dump($_SERVER);
var_dump($_REQUEST);
ncで検証サーバーを作る場合
デバッグ用。生のメッセージが見れるのでダンプしてdiffを取るなどでcurlとecho + ncの差分を見るのに使える。
nc -l 9999
HTTPメソッド名を非標準的なものにした場合の挙動
前述のNode.jsサーバーでは400 Bad Request
、PHPサーバーでは501 Not Implemented
が応答された。
- 投稿日:
process.exit()
のラッパーだったり、throw
する関数だったりして、戻り値がnever
を取る関数で、TypeScript上、後続処理がデッドロジックになるものを作る方法。
確認環境
Env | Ver |
---|---|
TypeScript | 5.4.5 |
やりたいこと
問題点
普通に実装して型推論に任せてもうまくいかない。
解決策
何のためにこれをやるか
別の関数から呼んだときに、呼び側の関数の戻り値型を正しくするためだ。下図はデッドロジックになっていない状態のときのものだが、処理が死なずに通り抜けてしまうのでundefined
が帰ることになっており、この関数の呼び下でundefined
だった時の処理を書く必要が出てきてしまう。
しかし、デッドロジック扱いになっていれば下図のように戻り値の型が期待した通りの内容になる。この関数がundefined
を返すことはないので、この状態を実現するために行っている。
関連記事
- TypeScriptでprocess.exit()ラッパーの後をデッドロジック扱いにする
- オブジェクトをラップして、そのオブジェクトに型を付けることで解決している