POTI-boardのレス先検索

$fp = fopen("hoge/tree.log", "r"); //ログファイルの場所
while ($line = fgets($fp)) {
//ログファイルの書式から変数を取得
$tree = explode(",", $line);//コンマ区切り形式のログの解析
$i=0;
$a=mb_substr_count("$line", ",")+1; //レスの数
//コンマ区切りなのでコンマの数+1。
while ($i < $a) {//0からレスの数までループ
if(rtrim($tree[$i], "\n")==$resno){
$resno=rtrim($tree[0], "\n");//スレッドの番号は$tree[0]
$count_end=true;//カウント終了
break;
}
if($count_end){break;}//レス先が見つかったのでbreak
echo "$i</br>";//確認用、実際には使わない。
$i++;
}
}
fclose($fp);
↑過去の自分が書いたコード。
$find=false:
$fp = fopen('hoge/tree.log', "r");
while($line=fgets($fp,4096)){
$treenos=explode(",",rtrim($line));
foreach($treenos as $treeno){
if($treeno===$no){
$resno=$treenos[0];
$find=true;
break;
}
}
if($find){
break;
}
}
fclose($fp);
↑今ならこう書きます。
配列がまったく理解できていなかった事がよくわかります…。

お絵かき掲示板はこちら。

POTI-boardのforをforeachに書き直し

forで配列の反復をしているところがたくさんあったので、foreachに書き直し。
配列のcountをしてそれから…では可読性が落ちる。
配列の書き直しなら参照渡しを使えばシンプルにまとめる事ができる。キーを取得しなくてもいいのでスマート…。
と思ったら…。
PHPの繰り返し処理大全 - Qiita

foreachでリファレンスが取れますが、使用してはいけません。
そもそもリファレンスはあらゆる場面で一切使用禁止です。
PHPのforeachで参照渡しをしたいときに気をつけること - Qiita

参照渡しはどうしても必要じゃないとき以外は使用しない方が良さそうです。
配列の書き直しに参照渡しを使っていたのですが、かなり強い口調で使ってはいけない…。

それならキーを取得して配列を書き直し…と思ったのですが…。
バグりました…。

問題なく動いているのにこの作業を行う事でバグを作ったらどうにもならないので、foreachで参照渡しを使ったらを忘れずにunset($value)すれば…。

と思ったら何箇所か抜けていました。

Bracket Pair Colorizer - Visual Studio MarketplaceをインストールしたVScodeで確認してみたら…。
ループの中でunset()している箇所が見つかったり…。

foreach 参照渡し php

インデントの位置がおかしいですが…。少し前のコードです。
foreachを使っていますが参照渡しは使っていません。

foreach 参照渡し php

参照渡しを使って配列を書き換えるコード。

$line[$i]と$valueがごちゃごちゃ入るより、参照渡しにして$valueだけにしてしまったほうがコードが見やすくなるような気もするんですけどね…。

参照渡しのforeachを使っているのにunset($value)が無い、もしくは位置がおかしいのはまずいので修正しました。
その事でトラブルが起きた…という事例は無いようなのですが…。

この修正はPOTI-board改 v1.53.6 lot.190926に反映されました。

お絵かき掲示板はこちら。

POTI-boardのパスワードハッシュをpassword_hash()に

2018年のパスワードハッシュ - Qiita

ログイン認証と称してmd5とかsha1とか書いてあるソースはゴミなので投げ捨てましょう。
単純なMD5やSHA1ハッシュを元に戻す | Bamboo lath 日々の記録
ハッシュ値は非可逆なので元に戻す事ができない筈なのですが、「aiueo」や「12345」のような単純なパスワードはデーターベースと照合して元に戻す事ができるようです。

POTI-boardは md5() から途中の8文字を抽出してハッシュ化しているので、紹介されている逆引きサイトに8文字のハッシュ値をいれても何もでてきませんが、パスワードが同じならハッシュ値も同じである事に変わりはありません。
PHP: password_hash - Manual

password_hash − パスワードハッシュを作る
password_hash() という簡単に導入できるハッシュ化のための関数があるのに使わない手はない…ですね。

簡単なテストコード。
<?php
$h= password_hash("aiueo", PASSWORD_DEFAULT);
//パスワードは aiueo
echo $h."\n";//ハッシュ値が表示される
$v=password_verify("aiueo",$h);
//ハッシュ値とパスワードを照合
echo $v."\n";//1
var_dump($v);//true
同じパスワードなのにリロードする度にハッシュ値が入れ替わります。

しかし…。
$h= password_hash("aiueo", PASSWORD_DEFAULT);
ではcostが10になってしまいます。
<?php
/**
* このコードは、サーバーをベンチマークして、どの程度のコストに耐えられるかを判断します。
* サーバーに負荷をかけすぎない範囲で、できるだけ高めのコストを設定したいものです。
* 基準として 8 から 10 程度からはじめ、サーバーが十分に高速なら、できるだけ上げていきましょう。
* 以下のコードでは、ストレッチングの時間を 50 ミリ秒以内にすることを狙っています。
* 対話形式のログインを扱う際の許容時間としては、このあたりが妥当なところでしょう。
*/
$timeTarget = 0.05; // 50 ミリ秒

$cost = 8;
do {
$cost++;
$start = microtime(true);
password_hash("test", PASSWORD_BCRYPT, ["cost" => $cost]);
$end = microtime(true);
} while (($end - $start) < $timeTarget);

echo "Appropriate Cost Found: " . $cost . "\n";
?>
さくらのレンタルサーバ ライトでこのテストコードを実行してみたところ最適なcostは9でした。

一番安いライトプランではありますが有料のサーバでもcost10ではサーバに負荷がかかるという事です。
costを10から9に下げると処理時間が半分に。
8にしたらさらに半分…。costが1下がると処理時間が半分になるようです。

ログイン認証を一度だけ行ってログインしたらそのまま…という想定ならcostが10でも耐えられるのかもしれませんが何か一言書き込むだけでパスワードのハッシュ化が行われる掲示板でcost10だとサーバの負荷が高くなってしまうかもしれません。
$pass = $pwd ? password_hash($pwd,PASSWORD_BCRYPT,['cost' => 5]) : "*";
costを5に引き下げました。

cost5では低すぎるのでは?と思ったりもしましたが、コメントを書き込むたびにパスワードをハッシュ化する掲示板なのでこれぐらい下げないと無料のレンタルサーバでは高負荷になる…という判断です。

それでも同じパスワードなら同じハッシュ値という従来のmd5の8文字のハッシュ値とは比べ物にならないぐらい安全性を向上できた…と思うのですが。

この変更は、lot.190823に反映されました。

POTI-board改のダウンロードはこちらから。

お絵かき掲示板はこちら。