Tagged ‘PHP’

Dropboxを使ったメモ系WEBアプリ「memotion」

memotion

去年ぐらいから意識高い系の人に人気が出てるNotionとか言うメモサービス(最近Notion AIでも話題になってますね)がありますが、おじさんには手元にファイルが無いメモサービスはなじめず、ずっとDropboxにぐだぐだなフォルダ管理で普通にメモをテキスト保存しておりました。
Notionの特徴的な自由でリッチなドキュメント制作は欲してなかったのですがタグ管理できるのが羨ましく思い、Dropboxでもいい感じにタグ管理できるWEBアプリを作りました。

https://tenhp.com/memotion/

(さらに…)

FILTER_SANITIZE_STRINGはダメです。

PHP8.1になってから「FILTER_SANITIZE_STRING」は非推奨になりました。

「FILTER_SANITIZE_STRING」はfilter_inputやfilter_varで利用するフィルターの一つです。
特に「FILTER_SANITIZE_STRING」を多様してた訳では何ですがその名前から「文字を無害化」するというイメージで簡易的に処理したいときには使っていました。
非推奨の知らせを受けて改めて調べてみました。

(さらに…)

文字コードで気をつけること

multibyte

よく「JIS(ISO-2022-JP)」と表現されますが、PHPでは「ISO-2022-JP」と「JIS」は違う文字コードになります。
「ISO-2022-JP」はメールでよく使われる文字コードで規格を厳守してるので機種依存文字(ISO-2022-JP規定外文字)や半角カナ共に扱えません。
一方「JIS」は半角カナが使え、機種依存文字が扱えない。
八方ふさがりのように見えるがPHP5.2.1からは「ISO-2022-JP-MS」が用意されており、コレだと機種依存文字も半角カナも扱える。
「メールはJISだから機種依存文字や半角カナが送信出来ない」はずだが、ISO-2022-JPのふりして中身をISO-2022-JP-MSにすると機種依存文字が送れたりします。(受け手のメールソフトが対応してた場合のみですが・・・)
(さらに…)

コンストラクタで多言語化を

PHPなどのシステムで多言語に対応する際は出力の度に言語で分岐して出力するより、言語ファイルを用意した方が効率的です。

言語ファイルと言えばプログラム業界では「.po」「.mo」といったファイルがよく見られます。(はてなの場合
これらの言語ファイルをPHPで使うには下記の流れの作業する事になります。

1. 翻訳元の「.pot」ファイルを作成
2. ファイルを元に翻訳元と翻訳後の書かれた「.po」ファイルを作成
3. 「.po」ファイルを「.mo」ファイルにバイナリ変換
4. GetTextというライブラリで翻訳させる。

大規模なシステムだと分業しやすいというメリットはありますが「TASK4BOX」みたいな規模の小さいシステムだと大袈裟なので自前で言語ファイルを作る事にした。
(さらに…)

iPhoneに元号アイコン

元号アイコン
WEBは西暦表記が多いですが書類を書いたりする際には未だ元号(年号)で記入する事が多々あります。
Siriに「今年は平成何年?」と聞いたらも答えてくれますが恥ずかしいです。
IT4コマ漫画:今って平成何年だっけ? – ITmedia ニュース
によるとそういうアプリがあるとの事ですが年号がバッジ(右上の数字)で表現されていて見た目が微妙です。
そこで、巷にあるアイコンをカスタムするアプリの方法を使って元号の書かれたアイコンを貼れないか試してみた。
(さらに…)

○○で始まる文字列検索の速度比較

PHPにて「○○で始まる文字列」を検索する場合、一番に思いつくのは正規表現だけど重いのでstrposで検索していたがstrposは検索位置を返すし全体を検索するのでなんとなく遅いかなと思い別の方法を模索してみた。

PHPのパフォーマンス改善(3) | Selfkleptomaniac
という記事にstrncmpを含んだ3つの方法が書かれていたので計5つの方法のベンチを取って比較してみた。
(各秒数は約8万行を検索したしたベンチの10回分の平均値。)

strncmp版(先頭から特定文字数分検索する関数)
if (!strncmp($myvalue, $searchstr, 5)) ~
0.0312 sec

substr版(文字列を部分抽出する関数)
if (substr($myvalue, 0, 5) == $searchstr) ~
0.0447 sec

preg_match版(正規表現を利用した検索)
if (preg_match(‘!^’.$searchstr.’!’, $myvalue)) ~
0.0578 sec

substr_compare版(特定部分から特定文字数分検索する関数)
if (substr_compare($myvalue, $searchstr, 0, 5) == 0) ~
0.0415 sec

strpos版(文字列の開始位置を検索する関数)
if (strpos($myvalue, $searchstr) === 0) ~
0.0297 sec

おっしゃる通り「strncmp」は速く「preg_match」は遅いが「strpos」が予想以上に速く、単純な文字列の検索も今回のような特定位置の文字列検索も「strpos」が最速という結果になった。

PHPの高速化

MyReleaseの新規セッションの割合が低下していた。
Yahoo!が検索エンジンをGoogleの検索エンジンに切り替えた為だ。

そこで、PHPの高速化をとスクリプトを調整していたが限界が来たのでサーバーの設定を変更することにしました。
とりあえず「eAccelerator」を入れてみた。
MyReleaseはCPIのVPSで元々PHP4でPleskという環境に、無理やりPHP5を導入してるので不安だったが何の問題もなくインストールできた。体感できるほど速くはならなかったがコンパネから利用状況が分かり頑張ってる様子がわかる。

次に「eAccelerator」と同居できるという事で「ZendOptimizer」もインストールした。
これは入会する手間はあるが簡単にインストールできた。
ただ、バージョンが3.3.9と新しく色んなサイトで紹介されてるインストーラーを使ったインストールができないが、必要なファイルをコピーしてphp.iniにコピーした場所を記述するだけでOKという簡単な作業でインストール完了。

更にmySQLのインデックスも微調整した。query_cacheを調整したりすると、ようやく体感できるレベルに改善された。

このおかげかは分からないけどランキングは約一年ぶりに5位に戻った。

PHPで複数のURLを404チェックする関数の速度比較

amazonのAPIなんかを利用して画像のパスを取得し保存していると稀に画像が削除されてしまってる事がある。
毎回、amazonのAPIを叩く様にしてもいいかもしれないけど頻繁にアクセスするとamazonに怒られるかもしれない。
そこで、ファイルが存在するかチェックする事にしたのだけどPHPには色々関数があるのでそれぞれチェックしてみた。
(さらに…)

マルチバイト文字のtrim

yahoo!の検索エンジンがGooleの検索エンジンになるというニュースはありましたが
とうとう切り替わったのを確認してしまいました。(徐々に切り替わっていくらしい)

Googleはページの表示スピードも見てるらしいので少しでもPHPのスピードを上げたくて最近ではベンチを使って速度を比較している。
他者の計ったベンチがGoogleで調べればすぐに出てくるのになぜ自分で調べるかというと、例えば文字の置換はstr_replaceを使い。
$str = str_replase(“AAA”, “BBB”, $str);
とするが普通で速度も早いが、検索文字(例の場合”AAA”)の出現がレアな場合
if (strpos($str,”AAA”) !== false) $str = str_replase(“AAA”, “BBB”, $str);
と置換する前に先に検索した方が早かったりするので、実際のデータが無いと分からないのでベンチを計る必要が出てきたりする。

そんな中、比較的遅いというmb_ereg_replaceを使ってるマルチバイトのtrimを調査してみることにした。
$str = mb_ereg_replace(“^[  ]+”, “”, $str);
$str = mb_ereg_replace(“[  ]+$”, “”, $str);
昔、Shift-JISで単純にtrimの第2引数に全角スペースを入れてトリムすると文字化けしたのでmb_ereg_replaceを使ってるが、安全だけど遅い。
そこで昔文字化けした理由を調べに文字コードをwikipediaで見てみた。
Shift_JIS
第1バイトが81-9FとE0-FC、
第2バイトが40-7Eと80-FC
EUC-JP
第1バイトがA1-A8とADとB0-F4とF9-FC、(亜種は8FとF5-FEも)
第2バイトがA1-FE(亜種は第3バイトにもA1-FE)
UTF-8
第1バイトがC2-FD、
第2バイト以降が80-BF
trimのデフォルトの第2引数は
” ” (0x20), 半角スペース
“\t” (0x09), タブ
“\n” (0x0A), 改行
“\r” (0x0D), 復帰
“\0” (0x00), NUL バイト
“\x0B” (0x0B), 垂直タブ
とどの文字コードにも危険なコードが含まれていないので普通に使える。
ただtrimはマルチバイトには対応していないのでシングルバイトに変換され削除されるので全角スペースを除去しようとすると下記のように問題が発生する。
Shift_JISの全角スペースは0x8140でtrimの第2引数に全角スペースを入れると81と40が削られアウト
(http://charset.7jp.net/sjis.htmlの81と40が絡む行や列が文字化けする。)
EUC-JPの全角スペースは0xA1A1でtrimの第2引数に全角スペースを入れるとA1が削られアウト
(http://charset.7jp.net/euc.htmlのA1が絡む行や列が文字化けする。)
UTF-8の全角スペースは0xE38080でtrimの第2引数に全角スペースを入れるとE3と80が削られアウト

正しく全角スペースをトリムするならmb_ereg_replaceしか無く、すべての全角スペースが半角スペースになってもよければ
$str = trim(str_replase(“ ”, ” “, $str));
と先に全角スペースを半角スペースに変換するなど、シチュエーションによって使い分けるしか無いようだ。