「Develop」の版間の差分

提供:senooken JP Wiki
(Config class)
(Algorithm 再帰処理)
 
(同じ利用者による、間の86版が非表示)
4行目: 4行目:
[https://asciiflow.com/#/ ASCIIFlow]: 画面構成図などの作成でテキストなので便利かもしれない。
[https://asciiflow.com/#/ ASCIIFlow]: 画面構成図などの作成でテキストなので便利かもしれない。


=== Design ===
=== Project ===
* [https://gigazine.net/news/20240217-open-source-non-code-contribution/ オープンソースの開発プロジェクトではコーディング以外のドキュメント化やサポートなどの貢献が特に重要 - GIGAZINE]
* [https://gigazine.net/news/20240229-open-source-project-business/ オープンソースプロジェクトを有料化して月収100万円の事業家に転身したソフトウェア開発者 - GIGAZINE]
 
=== 名簿付きの寄付 ===


==== Atomic Design ====
* Vim: <nowiki>https://vim-jp.org/vimdoc-ja/sponsor.html</nowiki>
* Vim (list): <nowiki>https://www.vim.org/sponsor/hall_of_honour.php</nowiki>
* KDE: <nowiki>https://relate.kde.org/</nowiki>
* KDE (list): <nowiki>https://relate.kde.org/civicrm/profile?gid=18&search=0</nowiki>
* Conservancy (list): <nowiki>https://sfconservancy.org/sponsors/</nowiki>
* Conservancy: <nowiki>https://sfconservancy.org/donate/</nowiki>
=== Kanboard ===


* [https://atomicdesign.bradfrost.com/chapter-2/ Atomic Design Methodology | Atomic Design by Brad Frost]
==== クローズ時に自動移動 ====
* [https://zenn.dev/bizlink/articles/b5c8985af8407a Atomic Designの概念]
[Configure project]-[Automatic actions]


最近のUIのコンポーネントの組み方。UIコンポーネントを粒度に分けて、ディレクトリー分けして流用するという考え方。
* action=[Move the task to another project]
* Event name=Closing a task
* Column=Done
* Project=


* atoms: 原子。これ以上分割不能な最小単位。input/label/buttonなど。
これでDoneをclose時にアーカイブ用のプロジェクトに移動できる。
* molecules: 分子。atomsを組み合わせたり、atomsに多少修正したもの。入力フォーム、ナビゲーション、カードなど。
* organisms: 有機体。分子+アルファ。入力フォーム+ヘッダーなど。複数の分子。
* templates: テンプレート。複数の有機体。ヘッダー、メイン、フッターなど。
* pages: ページ。テンプレートを使用したページ。


==== インターフェイスと抽象クラス ====
=== Communication ===
[https://qiita.com/nogson/items/e6575d6617f854ed6e25 PHPでインターフェイスと抽象クラスを使う #PHP - Qiita]


* インターフェイスは、クラスに複数実装できるが、抽象クラスは1つしか継承できない。→不特定のクラスで、共通のメソッドを定義したい場合。
==== Skype ====
* インターフェイスは、実装のあるメソッドを持つことができないが、抽象クラスは、実装のあるメソッドを持つことができる。→抽象クラスは、複数のクラスの、共通処理の中に、一部違う処理が入る場合、プロパティーが必要な場合などに使用する。
[https://support.microsoft.com/ja-jp/skype/%E3%81%99%E3%81%B9%E3%81%A6%E3%81%AE%E3%82%A8%E3%83%A2%E3%83%BC%E3%83%86%E3%82%A3%E3%82%B3%E3%83%B3%E3%81%AE%E3%83%AA%E3%82%B9%E3%83%88%E3%81%AF%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%81%8B-01af0c65-529f-4a4d-8e3a-a393033a359a すべてのエモーティコンのリストはありますか? - Microsoft サポート]


インターフェイス
Skyepで使用可能な絵文字の一覧。


* メソッド宣言のみ。
== Tool ==
* static/constの場合に限定して、メソッド定義、定数もOK。
 
=== General ===


==== Config class ====
==== Call tree ====
kcachegrindだったかな。


* [https://softwareengineering.stackexchange.com/questions/197272/best-practice-for-creating-a-global-config-class-used-by-numerous-components c++ - Best practice for creating a 'global' config class used by numerous components - Software Engineering Stack Exchange]
kscopeもこれか。
* [https://softwareengineering.stackexchange.com/questions/386212/best-way-to-provide-configuration-parameters-for-objects-far-away-from-the-start Best way to provide configuration parameters for objects far away from the starting point - Software Engineering Stack Exchange]
* [https://softwareengineering.stackexchange.com/questions/114924/config-class-struct-pattern-or-anti-pattern-alternatives?newreg=b46538fc865f46b08f6bf06d317925bf design - Config Class/Struct: Pattern or Anti-Pattern? Alternatives? - Software Engineering Stack Exchange]
* [https://softwareengineering.stackexchange.com/questions/441985/best-practice-design-pattern-for-working-with-a-config-file json - Best practice/design pattern for working with a config file - Software Engineering Stack Exchange]


アプリケーションの設定を管理するクラスの設計方法。いくつか方法があり、議論がある。「[https://softwareengineering.stackexchange.com/questions/386212/best-way-to-provide-configuration-parameters-for-objects-far-away-from-the-start Best way to provide configuration parameters for objects far away from the starting point - Software Engineering Stack Exchange]」で特によく議論されている。
Doxygen+GraphVizで関数コールグラフ


# シングルトン/グローバル変数: ただし、テストなどで並列アクセスが必要な場合に困ることがあるらしい。
==== kscope ====
# DI/設定クラス引数: これがよく支持されている。テストしやすいなど。グローバル変数への参照を渡すようなイメージ。ただし、依存性の伝播のように、上から下に設定を渡す際に、関係ない大量の設定を渡すことがあったりする。
https:/github.com/ivan0124/Linux-programming/wiki/How-to-use-KScope-to-trace-code


2のDIが最近の主流。引数で値渡し相当にすれば、並列アクセス時も無影響。伝播の問題は設計の問題。
https:/sourceforge.net/projects/kscope/


メソッドをmain関数で呼び出すことを想定して、
http:/www.lemis.com/grog/software/kscope.php


==== cscope ====
cbrowser/kbrowserというGUIもある。


cscopeの大文字小文字無視検索


=== Regular Expression ===
<nowiki>http://vim.1045645.n5.nabble.com/how-to-search-with-cscope-ignoring-case-td5715043.html</nowiki>
正規表現。重要。覚えにくいが重要なものをメモしておく。


後ろからマッチ。cが置換対象。
DBを別にする必要がありそう。


/[^c]*$/: cより右端
==== expect ====
端末の手動操作を自動化するソフト。


=== glob ===
<nowiki>*</nowiki> ^と$は使えない。代わりに、\nを使う。


* [https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/functions/glob.html glob]
<nowiki>*</nowiki> 文字列の囲みに一重引用符 (') は使えない。二重引用符 (") のみ有効。
* [https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/utilities/V3_chap02.html#tag_18_13 Shell Command Language]


重要。正規表現とは似ているが異なる、パターンマッチング記法 (Pattern Matching Notation)。主に、globで採用されており、ディレクトリー・ファイルのマッチングで使われる。
<nowiki>*</nowiki> expect文はawkみたいな感じ。


使用可能な記号は以下3個。以下の3文字は\でエスケープできる。
<nowiki>*</nowiki> ただし、expectは注意が必要。最初のexpectにマッチしないと先に進めない。タイムアウトとかするしかない。


* ?: 任意の1文字にマッチ。
expect -c "set timeout 5; spawn cat cat.txt; expect \nFAIL {send pwd/n; expect :; exit}"
* *: 任意の0以上の文字にマッチ。
* [: []内の1文字にマッチ。正規表現の各括弧と同じ。ただし、先頭の否定が^ではなく、!。


ファイル名マッチ時には、追加で特殊なルールがある。
https:/linuxjm.osdn.jp/html/expect/man1/expect.1.html


.から始まるファイル名へのマッチには、.が必要。つまり、*?は先頭の.にはマッチしない。[!a] のような否定形の各括弧記法も.にはマッチしない。加えて、先頭の[.]もマッチするかは不定(unspecified)。
```


globで.ファイルを含めたい場合、工夫が必要 ([https://www.php.net/manual/ja/function.glob.php PHP: glob - Manual])。
sh -eux <<-"EOT"
.[!.]* *
 
上記のように.ファイルのマッチとそれ以外を指定する必要がある。
expect -c "set timeout 5; spawn ssh senooken@senooken-linux; expect :; send ieneko/n; expect aho {send echo aho} +x {send pwd/n}; expect /$; exit"


<code>.[!.]*</code> は、<code>.</code>と<code>..</code>以外の.<code>.</code>始まりのファイルにマッチする。
expect -c "set timeout 5; spawn ssh senooken@senooken-linux; expect :; send ieneko/n; expect + {send pwd/n}; expect /$; exit"


<code>.*</code>を指定すると、<code>.</code>/<code>..</code>がマッチするので注意する。最近のシェルは、シェル側で気を利かせているようで、<code>.*</code>だと<code>.</code> /<code>..</code>はマッチしない。
expect -c "set timeout 5; spawn cat cat.txt; expect \nFAIL {send pwd/n; expect :; exit}"


=== 引用符のネスト ===
expect -c 'set timeout 10; spawn cat cat.txt; expect "aa F" {set AAA "abc"}; expect FAIL {send "$AAA/n"; expect " "; exit}'
シェルやプログラミング言語で、文字列リテラルの表現などで、一重引用符'と二重引用符"を使う。


JSON作成や変数展開などで、これらをネストさせたいことがある。その基本的な考え方を整理する。
EOT


交互にしていい場合は簡単二重。引用符内に一重引用符を配置、一重引用符内に二重引用符を配置すればいい。
```


問題はこれがNGな場合。特にありがちなのが、JSONの生成。JSONの引用符は二重引用符のみ。一重引用符の中だと、二重引用符の変数展開が使用不能。外側を二重引用符にする必要がある。
== Coding ==


二重引用符は、内部で変数展開が可能。この都合で、バックスラッシュ\によるエスケープが有効。
=== タイムゾーン ===
[https://qiita.com/dmikurube/items/15899ec9de643e91497c タイムゾーン呪いの書 #timezone - Qiita]


基本的な方法。
3文字形式は避けたほうが無難。


# 既存の一重/二重引用符などをバックスラッシュでエスケープ。
タイムゾーン名で判定する実装があるので、UTC-9なども避けたほうがいい。
# 全体を一重/二重引用符で囲む。


何かAwkの本か何かで、基本的な考え方の説明の記載があった気がする。
tz databaseのAsia/Tokyoなどの確実性が高い。
=== Regular Expression ===
正規表現。重要。覚えにくいが重要なものをメモしておく。


[{"ke\y":"valu\e"}] を例として考える。
後ろからマッチ。cが置換対象。


# {"ke\y":"valu\e"}
==== Case ====
# エスケープ: {\"ke\\y\":\"valu\\e\"}
/[^c]*$/: cより右端
# 全体囲み: "{\"ke\\y\":\"valu\\e\"}"


これでOK。また何か考慮不足があればそのときに考える。
===== マッチの前後の挿入 =====
https:/vim.fandom.com/wiki/Power_of_g
:g/GST_.*("/s/^/LOG(INFO) << "DEBUG";/r/
行頭・行末で引っ掛ける。


ただ、元データに修正が必要なので、そのまま行きたい。ヒアドキュメント的なものが使えるならそれを使うのがいい。
===== 関数にログ =====
:%s/([^")]*)/) /([a-z]* /)*{/&/rLOG(INFO) << "/1";/r/g
考慮するケース
double currentTime() const override { return m_element->currentTime(); }


例えば、シェルなら、catコマンドとコマンド置換で生テキストを使える。
=== glob ===
echo $(cat <<-'EOT'
{"ke\y":"valu\e"}
EOT
)
.envなどで使える技?いや使えない。.envではシンプルなコマンドしか使えず、ヒアドキュメントは使えない模様。


* [https://stackoverflow.com/questions/15637429/how-to-escape-double-quotes-in-json How to escape double quotes in JSON - Stack Overflow]
* [https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/functions/glob.html glob]
* [https://stackoverflow.com/questions/64011248/how-to-handle-double-quotes-in-json-value python - How to handle double quotes in JSON value? - Stack Overflow]
* [https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/utilities/V3_chap02.html#tag_18_13 Shell Command Language]


JSONのvalue部分に適用したい場合。データの二重引用符をバックスラッシュでエスケープする。これはこうするしかない。JSONが二重引用符しか認めないから。
重要。正規表現とは似ているが異なる、パターンマッチング記法 (Pattern Matching Notation)。主に、globで採用されており、ディレクトリー・ファイルのマッチングで使われる。


基本的な考え方がある。
使用可能な記号は以下3個。以下の3文字は\でエスケープできる。


# JSON value用に二重引用符"を\"で置換。
* ?: 任意の1文字にマッチ。
# \"がPHP/JavaScriptで二重引用符に扱いにならないように、\を\\に置換。
* *: 任意の0以上の文字にマッチ。
# JSON項目の二重引用符"を\"で置換。
* [: []内の1文字にマッチ。正規表現の各括弧と同じ。ただし、先頭の否定が^ではなく、!。
# 全体を二重引用符"で囲む。


こういう感じ。JSONはawkでも任意の最終データで考える。途中にプログラミング言語でのパースがあるので、それを考慮する必要がある。
ファイル名マッチ時には、追加で特殊なルールがある。


=== Kanboard ===
.から始まるファイル名へのマッチには、.が必要。つまり、*?は先頭の.にはマッチしない。[!a] のような否定形の各括弧記法も.にはマッチしない。加えて、先頭の[.]もマッチするかは不定(unspecified)。


==== クローズ時に自動移動 ====
globで.ファイルを含めたい場合、工夫が必要 ([https://www.php.net/manual/ja/function.glob.php PHP: glob - Manual])。
[Configure project]-[Automatic actions]
.[!.]* *
上記のように.ファイルのマッチとそれ以外を指定する必要がある。
 
<code>.[!.]*</code> は、<code>.</code>と<code>..</code>以外の.<code>.</code>始まりのファイルにマッチする。


* action=[Move the task to another project]
<code>.*</code>を指定すると、<code>.</code>/<code>..</code>がマッチするので注意する。最近のシェルは、シェル側で気を利かせているようで、<code>.*</code>だと<code>.</code> /<code>..</code>はマッチしない。
* Event name=Closing a task
* Column=Done
* Project=


これでDoneをclose時にアーカイブ用のプロジェクトに移動できる。
=== 引用符のネスト ===
シェルやプログラミング言語で、文字列リテラルの表現などで、一重引用符'と二重引用符"を使う。


=== Modelio ===
JSON作成や変数展開などで、これらをネストさせたいことがある。その基本的な考え方を整理する。


==== クラス図 ====
交互にしていい場合は簡単二重。引用符内に一重引用符を配置、一重引用符内に二重引用符を配置すればいい。
* 汎化 (generalization): 実線白矢印。継承。   
* 実現 (realization): 点線矢印。interfaceの継承。
* 集約: 白ひし形。
* コンポジション: 黒ひし形。子が単体で存在できない場合。親と生存期間が同一の場合。   
* 関連: 実線矢印。メソッド内インスタンスなど。
* 依存: 点線矢印。引数やローカル変数、返却値。


== VCS ==
問題はこれがNGな場合。特にありがちなのが、JSONの生成。JSONの引用符は二重引用符のみ。一重引用符の中だと、二重引用符の変数展開が使用不能。外側を二重引用符にする必要がある。


==== Git ====
二重引用符は、内部で変数展開が可能。この都合で、バックスラッシュ\によるエスケープが有効。


===== 差分ファイル抽出 =====
基本的な方法。
情報源: [https://qiita.com/kaminaly/items/28f9cb4e680deb700833 gitで差分ファイルを抽出する #Git - Qiita]。


git archiveとgit diffを組み合わせる。
# 既存の一重/二重引用符などをバックスラッシュでエスケープ。
git archive --format=zip --prefix=root/ HEAD `git diff --diff-filter=d --name-only HEAD^ HEAD` -o archive.zip
# 全体を一重/二重引用符で囲む。
ただし、この方法はファイル数がARG_MAX以下の場合だけ。ファイル数が多い場合だめ。


git diff --name-onlyで一覧を出力させて、1個ずつcp -pで階層を維持してコピーするしかないかも?
何かAwkの本か何かで、基本的な考え方の説明の記載があった気がする。


:
[{"ke\y":"valu\e"}] を例として考える。
mkdir -p archive
git diff --name-only new_base 44765_upgrade-base-version | xargs -i cp -p --parent "{}" archive/


===== マージコミット後のコミット追加 =====
# {"ke\y":"valu\e"}
マージコミット後に次の開発作業を始めることが多い。が、直後の初回のコミットを追加したい場合困る。
# エスケープ: {\"ke\\y\":\"valu\\e\"}
# 全体囲み: "{\"ke\\y\":\"valu\\e\"}"


git rebase -iにすると、コミットが残るから。編集はできるが、その直前にコミットの追加ができない。マージコミットは扱いが特殊で直接rebaseで編集できない。
これでOK。また何か考慮不足があればそのときに考える。


しかたないので、該当コミットでブランチを作成して、コミット。その後、既存の修正ブランチをrebaseでそのコミットの後にくっつける。これでいける。
ただ、元データに修正が必要なので、そのまま行きたい。ヒアドキュメント的なものが使えるならそれを使うのがいい。


===== core.autocrlf =====
例えば、シェルなら、catコマンドとコマンド置換で生テキストを使える。
<blockquote>warning: in the working copy of 'docker/README.md', LF will be replaced by CRLF the next time Git touches it</blockquote>Windowsでは改行にCR+LFを使うが、mac/LinuxはLFのみ。これの違いの処理のための設定がcore.autoclrlf
echo $(cat <<-'EOT'
 
{"ke\y":"valu\e"}
* true=コミット時にCRLFをLFに自動変換。チェックアウト時に逆。Windows向けの設定。
EOT
* false=変換しない。
)
* input=コミット時にCRLFをLFに自動変換のみ。mac/Linux向け。Windowsではチェックアウト時にCRLFになるが、mac/LinuxはLFになる。
.envなどで使える技?いや使えない。.envではシンプルなコマンドしか使えず、ヒアドキュメントは使えない模様。


わかりにくい。基本はfalseで良いと思われる。
* [https://stackoverflow.com/questions/15637429/how-to-escape-double-quotes-in-json How to escape double quotes in JSON - Stack Overflow]
* [https://stackoverflow.com/questions/64011248/how-to-handle-double-quotes-in-json-value python - How to handle double quotes in JSON value? - Stack Overflow]


===== gitkの文字化け対策 =====
JSONのvalue部分に適用したい場合。データの二重引用符をバックスラッシュでエスケープする。これはこうするしかない。JSONが二重引用符しか認めないから。
[https://www.pistolfly.com/weblog/2010/02/gitk.html gitkのエンコーディングを設定する - Pistolfly]


gitkはシステムのデフォルトエンコーディングで表示しようとするので、文字エンコーディングを指定しておく。
基本的な考え方がある。
git config --global gui.encoding utf-8


===== 改名と修正 =====
# JSON value用に二重引用符"を\"で置換。
# \"がPHP/JavaScriptで二重引用符に扱いにならないように、\を\\に置換。
# JSON項目の二重引用符"を\"で置換。
# 全体を二重引用符"で囲む。


* [https://qiita.com/yukimura1227/items/fbb076db61a2e43a32e3 gitでrename&modifyしたファイルのログを追跡できるようにしたい場合 #Git - Qiita]
こういう感じ。JSONはawkでも任意の最終データで考える。途中にプログラミング言語でのパースがあるので、それを考慮する必要がある。
* [https://zenn.dev/yoichi/articles/how-git-handles-renaming Gitはファイルのリネームをどう扱うか]


改名と修正を同時にすると、改名を検知できない。
=== ケース変換 ===
[https://stackoverflow.com/questions/63116039/camelcase-to-kebab-case javascript - camelCase to kebab-case - Stack Overflow]


-Mオプションを指定すると、類似度で同時も検知できる。が、基本はリネーム・改名と修正は別コミットにしたほうがよさそう。
キャメルケースをチェインケースにしたり、逆にしたりなどケース変換したいことがある。正規表現を駆使して実現する。


===== 差分無視 =====
=== encode ===
[https://qiita.com/odekekepeanuts/items/8a056b87c9e481e07e57 git diffの--ignoreオプションにおけるスペース、タブ、改行の扱いを理解する #Git - Qiita]
[https://www.sejuku.net/blog/25909 【PHP入門】URLエンコードする方法(urlencode) | 侍エンジニアブログ]


-wでインデント違いを無視してくれる。
日本語や記号を他のコードに変換 (エンコード) する方式が何通りかある。把握しておくと役立つ。
 
* パーセントエンコーディング/URLエンコード: URLで使用不能な文字を%16進数で連結。
* UTF-8
* base64: 全データを「A-Z」「a-z」「0-9」「+」「/」の64文字で表現。文末に=を使うので実質は65文字。
* HTMLエンコード: HTMLで特殊な意味を持つ文字を&amp;lt;などに変換する。


===== squash =====
==== Percent-encoding ====
squashすると、squash対象コミットが、対象の直前のコミットに含められる。


===== gitignore =====
* [https://ja.wikipedia.org/wiki/%E3%83%91%E3%83%BC%E3%82%BB%E3%83%B3%E3%83%88%E3%82%A8%E3%83%B3%E3%82%B3%E3%83%BC%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0 パーセントエンコーディング - Wikipedia]
[https://git-scm.com/docs/gitignore/en Git - gitignore Documentation]
* [https://developer.mozilla.org/ja/docs/Glossary/Percent-encoding Percent-encoding (パーセントエンコーディング) - MDN Web Docs 用語集: ウェブ関連用語の定義 | MDN]
* [https://datatracker.ietf.org/doc/html/rfc3986 RFC 3986 - Uniform Resource Identifier (URI): Generic Syntax]


====== Format ======
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
記述方法を整理する。
上記文字はエンコードの対象外。


* 空行は無視。
==== 英数変換 ====
* #始まりの行はコメント扱い。
[https://stackoverflow.com/questions/28110062/php-how-to-encode-all-characters-with-rawurlencode string - PHP How to encode all characters with rawurlencode - Stack Overflow]
* 終端スペースは無視。
* !接頭辞はパターン否定。つまり、除外ではなく含める。以前除外された一致を再び含める。ただし、親ディレクトリーが除外されている場合、以下のファイルは含められない。パフォーマンス上の理由。順番に注意する。
* /はディレクトリー区切りとして使用。先頭、中間、末尾で登場する。
** 先頭と中間の/は相対パスを意味する。
** それ以外、末尾の//なしの場合、現在以下のディレクトリーにもマッチする。
** 末尾が/で終わる場合、ディレクトリーのみに一致。/がない場合、ディレクトリーとファイルの両方に一致。
* *は/以外にマッチ。?は/以外の任意の1文字にマッチ。[a-zA-Z] の範囲記法も使用可能。fnmatch(3) FNM_PATHNAMEフラグのパス名展開に準じる。
* **は特殊な意味がある。
** **/=全ディレクトリー。**/fooは配下の全fooにマッチ。**/foo/barはfoo以下の全barにマッチ。
** /**=配下のすべてにマッチ。
** a/**/b=a/b a/x/b a/x/y/bのすべてにマッチ。


後は特に明記がないが、上から順番に評価されて、最後のマッチが優先されるので、記述の順番に注意する。
変数名への変換などで、日本語や記号を英数字 [0-9a-zA-Z] に変換したいことがある。


反転の!と/の扱いに特に注意が必要。
こういう目的だと%エンコーディングが適している。


先頭スラッシュをつけないと、再帰的になる。
ただし、一部の記号を許可しているので、自前で変換する。
     $ cat .gitignore
function encode_all($str) {
    # ディレクトリ foo/bar 以外のすべてを除外
     $hex = unpack('H*', $str);
    /*  
    return preg_replace('~..~', '%$0', strtoupper($hex[1]));
    !/foo
}
    /foo/*
    !/foo/bar
$str = 'big ƒüßchen';
print_r(encode_all($str));
 
==== Term ====
紛らわしい用語がある。
 
* ミドルウェア: 名前通り中間のソフトウェア。DBやアプリケーションサーバーなどが該当。単独で動作が重要なポイント ([https://sackle.co.jp/blog/detail/1248-2 ミドルウェアとは何か?代表的な製品や使用例とあわせて解説! - サックルMAGAZINE]、[https://system-kanji.com/posts/middleware-development ミドルウェアとは?アプリ・システム開発との関係・仕組み・役割・具体例を解説【2024年最新版】 | システム幹事])。
* フレームワーク: 単体で動作しない。アプリ開発のテンプレート。Django/Ruby on Rails/Vue.jsなど ([https://www.pentasecurity.co.jp/pentapro/entry/framework_library 【3分ITキーワード】 フレームワークとライブラリの違いは? - ペンタPRO:ペンタセキュリティが提供するセキュリティ情報まとめサイト])。
* ライブラリー: 単体で動作しない。よく使われるコードの集まり。機能単位。jQuery/Numpy/matplotlib/Qtなど。
 
フレームワークの中にライブラリーも含めていいと思う。
 
==== Category ====
「[https://ja.wikipedia.org/wiki/%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E9%96%8B%E7%99%BA%E5%B7%A5%E7%A8%8B ソフトウェア開発工程 - Wikipedia]」


====== 空ディレクトリーの維持 ======
ソフトウェアの分類、ページ分類時に役立つ。
[https://stackoverflow.com/questions/115983/how-do-i-add-an-empty-directory-to-a-git-repository How do I add an empty directory to a Git repository? - Stack Overflow]


gitは空ディレクトリーを履歴管理できない。何かファイルが必要。
* 言語
* ツール: 静的解析、テスト、文書など。
* フレームワーク


logなど維持したい空ディレクトリーに、以下の内容の.gitignoreを置く。
MediaWikiのページ名は全体で固有が条件なので、言語名+分類名でページを作るといい。
!.gitignore
.gitignore以外を無視する。これで.gitignoreのみがあるので管理できる。


====== 指定ファイルのみ除外 ======
*
!.gitignore
ディレクトリーを残す以外 (.gitignore1ファイル以外) に、サンプルファイルなど複数ファイルを残したい場合は、上記のように*で最初に全部除外して指定ファイルのみ含める。/は必要に応じてつける。


===== gitattributes =====
* PHP language
[https://git-scm.com/docs/gitattributes Git - gitattributes Documentation]
* PHP tool
* PHP framework


gitignoreに似ていて、パターンにマッチしたパスに対する設定を行える。
==== 成功時連続継続処理 ====
一度の取得件数の上限が決まっていて、終了・失敗するまで取得を継続したいという処理がそれなりに発生する。


* text
# 処理実行。
* eol
# 成功ならA、失敗なら終了。
* working-tree-encoding
# 処理実行。
* ident
# 成功ならA、失敗なら終了。
* filter
 
* diff
こういうパターン。いくつか実装方法があるが、while (true) のパターンが重複がなくてベストだと思う。
* merge
        /*
* conflict-marker-size
        // 無限ループで終了条件でブレイク
* whitespace
        while (true) {
* export-ignore: git archiveなどに含めないことをマーク。
            // 処理実行
* export-subst
            if (失敗) {
* delta
                break;
* encoding
            }
            成功時処理
        }
       
        // do while
        do {
            処理実行
            if (成功時) {}           
        } while ();
        // for (初期化; 継続判定・終了判定; 成功時式) {
            処理実行
        }
        */
do-whileは成功・終了判定を2回書く必要がある。


===== 過去コミットのメールアドレスの変更 =====
forだと成功処理を式でしか書けない。成功処理を関数や即時実行関数式などで書くなら悪くはないし、ベストになりえる。


* [https://www.git-tower.com/learn/git/faq/change-author-name-email How can I change the author (name / email) of a commit? | Learn Version Control with Git]
いや、成功時処理内の処理の結果次第で反復の終了条件などが追加で入るならNGになる。なので、やっぱりwhile(true)が無難。コード行数もそんなに変わらない。
* [https://zenn.dev/flyingbarbarian/articles/241627cae5988a Gitのcommitの名前やメールアドレスを過去からまとめて変更する]


単一コミットのメールアドレスを指定する場合、commitに--authorを指定する。
これにさらに初回だけ、ヘッダーの取得、書き込み処理などが発生する場合、初回だけループの外でやるのがきれいだろうか?初回処理が2回登場することになるけれど。
git commit --author="John Doe <john@doe.org>"
--amendと併用することで、過去コミットも変更できる。


数が少ないなら、rebase -iで1個ずつamendする。数が多いならfilter-branch。
offsetなどで初回の判定が反復内でできるから、それで分けるのがいいか?
        $offset = 0;
        while (true) {
            $currentReturnCode = $service->sendRequest(Raku2Config::API_TYPE_CSV_EXPORT, Raku2Config::CONFIG_API_URL_MULTI_API, [
                json_encode([
                    'dbSchemaId' => $table_info['dbSchemaId'],
                    'offset' => $offset,
                    'limit' => $limit,
                ])
            ]);
            $response = $service->getApiResultJson();
            // 終了条件: 戻り値が成功以外、か応答本体が1行 (ヘッダーのみ) の時。
            if (($currentReturnCode !== Raku2Config::EXIT_SUCCESS) || (substr_count($response, "\n") <= 1)) break;
            // 2回目からはヘッダー除去して書き込み。
            $start = strpos($response, "\n") + 1;
            $flat = FILE_APPEND;
            if ($offset === 0) {
                $start = $flag = 0;
                $path = stream_get_meta_data($fp = tmpfile())['uri'];
            }
            file_put_contents($path, substr($response, $start), $flag);
            $offset += $limit;
            sleep(3);
        }


===== 第一コミットの変更 =====
        for ($offset = 0;
            ($currentReturnCode === Raku2Config::EXIT_SUCCESS) && (substr_count($response, "\n") > 1);
            (function() use (&$offset, $limit, $response) {
                // 2回目からはヘッダー除去して書き込み。
                $start = strpos($response, "\n") + 1;
                $flag = FILE_APPEND;
                if ($offset === 0) {
                    $start = $flag = 0;
                    $path = stream_get_meta_data($fp = tmpfile())['uri'];
                }
                file_put_contents($path, substr($response, $start), $flag);
                $offset += $limit;
                sleep(3);
            })()
        ) {
            $currentReturnCode = $service->sendRequest(Raku2Config::API_TYPE_CSV_EXPORT, Raku2Config::CONFIG_API_URL_MULTI_API, [
                json_encode([
                    'dbSchemaId' => $table_info['dbSchemaId'],
                    'offset' => $offset,
                    'limit' => $limit,
                ])
            ]);
            $response = $service->getApiResultJson();
        }


* [https://dev.classmethod.jp/articles/git-rebase-from-root/ [Git] 最初のコミットを含めてrebase -iする方法 | DevelopersIO]
=== character ===
* [https://git-scm.com/docs/git-rebase Git - git-rebase Documentation]


通常、第一コミットはammend以外では変更できない。
==== BOM ====
UTF-8のBOM
\xef\xbb\xbf
この文字を先頭につけるとUTF-8のBOMになる。


rebase --root [branch] でブランチの第一コミットも参照して改変可能。
=== Convert ===


===== ファイルのインデックスのみ削除 =====
==== IP/CIDR ====
git rmは単独だと、gitの履歴とローカルファイルからも削除する。追跡対象から削除のみで、ローカルファイルとして残したい場合、--cachedを指定する。
// JavaScript
  git rm --cached
<nowiki> </nowiki>  /**
<nowiki> </nowiki>    * サブネットマスクをIPアドレス形式 (x.x.x.x/255.255.255.0) からCIDR形式 (x.x.x.x/24) に変換する。
<nowiki> </nowiki>    * @param {string} ipaddress - IPアドレス文字列 (x.x.x.x/x.x.x.x形式)。
<nowiki> </nowiki>    */
<nowiki> </nowiki>  toCIDR(ipaddress) {
<nowiki> </nowiki>    const [address, mask] = ipaddress.split('/')
<nowiki> </nowiki>    const segments = mask.split('.')
<nowiki> </nowiki>    const CIDR = segments
<nowiki> </nowiki>      .map((e) => Number(e).toString(2))
<nowiki> </nowiki>      .join(<nowiki>''</nowiki>)
<nowiki> </nowiki>      .replace(/0*$/, <nowiki>''</nowiki>).length
<nowiki> </nowiki>    return address + '/' + CIDR
<nowiki> </nowiki>  },
<nowiki> </nowiki>  /**
<nowiki> </nowiki>    * サブネットマスクのCIDR形式 (24) をIPアドレス形式 (255.255.255.0)に変換する。
<nowiki> </nowiki>    * @param {number} cidr - ciderの数字。
<nowiki> </nowiki>    * @return {string} x.x.x.x形式のIPアドレス文字列。
<nowiki> </nowiki>    */
<nowiki> </nowiki>  cidrToIp(cidr) {
<nowiki> </nowiki>    const digit = 32
<nowiki> </nowiki>    const ip = ('1'.repeat(cidr) + '0'.repeat(digit)).substr(0, digit)
<nowiki> </nowiki>    return ip
<nowiki> </nowiki>      .match(/.{8}/g)
<nowiki> </nowiki>      .map((e) => parseInt(e, 2))
<nowiki> </nowiki>      .join('.')
  <nowiki> </nowiki>  },


=== Algorithm ===


==== 再帰処理 ====
https://chatgpt.com/c/673d9bfe-2414-800b-9922-f94be6dbe950


=== Fossil ===
再帰関数で実装するほかに、スタックで処理する方法がある。
* [https://gigazine.net/news/20231231-why-sqlite-does-not-use-git/ SQLiteがバージョン管理システムとしてGitを採用しない理由 - GIGAZINE]
* [https://gigazine.net/news/20201229-fossil/ GitとGitHubの機能をひとつのバイナリに詰め込んだ「Fossil」レビュー - GIGAZINE]


外部依存を排除しており、CGIでも動作するという点が非常に良い。気になる。Phorgeの検討が不要になる。
再帰関数のほうが簡単に実装できるが、関数呼び出しのオーバーヘッドがある。ネスト10-100程度くらいなら問題ない。


=== GitHub ===
パフォーマンスや再帰中の細かい制御が必要なら、スタックが有利。ただし、実装がやや複雑。


==== Account ====
最初は再帰関数で実装して、後でボトルネックになったらスタックというのも手。
Username may only contain alphanumeric characters or single hyphens, and cannot begin or end with a hyphen.
ユーザー名は、英数字と-のみが使用可能。


組織別にアカウントを分けるなら、かぶらないように末尾に-組織名のようなサフィックスがあるとよいだろう。
== UML ==


== Shell ==
=== Umbrello ===


=== ワイルドカード ===
==== Problem ====
ワイルドカードで.始まりのファイルをマッチさせたい。
altなどの重なり順番、アクティブの下になっちゃう


以下ならマッチするが、ブレース展開 (brace expansion) はPOSIX shでは使えなかった気がする。
optの条件が表示されない。
echo {.*,*}


=== BOM ===
=== Modelio ===
[https://stackoverflow.com/questions/3127436/adding-bom-to-utf-8-files unicode - Adding BOM to UTF-8 files - Stack Overflow]


ExcelでUTF-8ファイルを開けるように、UTF-8のBOMをファイルにつけたい。
==== クラス図 ====
printf '\xEF\xBB\xBF' > with_bom.txt
* 汎化 (generalization): 実線白矢印。継承。
上記コードでBOMを最初に書き込んで、後は追記する。
* 実現 (realization): 点線矢印。interfaceの継承。
* 集約: 白ひし形。
* コンポジション: 黒ひし形。子が単体で存在できない場合。親と生存期間が同一の場合。
* 関連: 実線矢印。メソッド内インスタンスなど。
* 依存: 点線矢印。引数やローカル変数、返却値。


=== awk ===
=== Design ===
[https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/ The Open Group Base Specifications Issue 7]


==== 変数 ====
==== Atomic Design ====
 
* [https://atomicdesign.bradfrost.com/chapter-2/ Atomic Design Methodology | Atomic Design by Brad Frost]
* [https://zenn.dev/bizlink/articles/b5c8985af8407a Atomic Designの概念]


===== 特別 =====
最近のUIのコンポーネントの組み方。UIコンポーネントを粒度に分けて、ディレクトリー分けして流用するという考え方。
* NF: 列数。列の全表示などで使う基本的で重要な変数。
* NR: 行番号。


===== スコープ =====
* atoms: 原子。これ以上分割不能な最小単位。input/label/buttonなど。
[http://www.fukano.jp/study_of_awk/basic/basic08.htm 変数のスコープ]
* molecules: 分子。atomsを組み合わせたり、atomsに多少修正したもの。入力フォーム、ナビゲーション、カードなど。
* organisms: 有機体。分子+アルファ。入力フォーム+ヘッダーなど。複数の分子。
* templates: テンプレート。複数の有機体。ヘッダー、メイン、フッターなど。
* pages: ページ。テンプレートを使用したページ。


関数の仮引数のみ、ローカル変数扱いで、それ以外はグローバル変数。
==== インターフェイスと抽象クラス ====
[https://qiita.com/nogson/items/e6575d6617f854ed6e25 PHPでインターフェイスと抽象クラスを使う #PHP - Qiita]


==== 文/statement ====
* インターフェイスは、クラスに複数実装できるが、抽象クラスは1つしか継承できない。→不特定のクラスで、共通のメソッドを定義したい場合。
* インターフェイスは、実装のあるメソッドを持つことができないが、抽象クラスは、実装のあるメソッドを持つことができる。→抽象クラスは、複数のクラスの、共通処理の中に、一部違う処理が入る場合、プロパティーが必要な場合などに使用する。


* actions
インターフェイス
** if/else
 
** while/do...while/for
* メソッド宣言のみ。
** break/continue
* static/constの場合に限定して、メソッド定義、定数もOK。
** delete
 
** next
==== Config class ====
** exit
* output
** print
** printf


==== 関数 ====
* [https://softwareengineering.stackexchange.com/questions/197272/best-practice-for-creating-a-global-config-class-used-by-numerous-components c++ - Best practice for creating a 'global' config class used by numerous components - Software Engineering Stack Exchange]
* [https://softwareengineering.stackexchange.com/questions/386212/best-way-to-provide-configuration-parameters-for-objects-far-away-from-the-start Best way to provide configuration parameters for objects far away from the starting point - Software Engineering Stack Exchange]
* [https://softwareengineering.stackexchange.com/questions/114924/config-class-struct-pattern-or-anti-pattern-alternatives?newreg=b46538fc865f46b08f6bf06d317925bf design - Config Class/Struct: Pattern or Anti-Pattern? Alternatives? - Software Engineering Stack Exchange]
* [https://softwareengineering.stackexchange.com/questions/441985/best-practice-design-pattern-for-working-with-a-config-file json - Best practice/design pattern for working with a config file - Software Engineering Stack Exchange]


===== 組込関数 =====
アプリケーションの設定を管理するクラスの設計方法。いくつか方法があり、議論がある。「[https://softwareengineering.stackexchange.com/questions/386212/best-way-to-provide-configuration-parameters-for-objects-far-away-from-the-start Best way to provide configuration parameters for objects far away from the starting point - Software Engineering Stack Exchange]」で特によく議論されている。


* Arithmetic
# シングルトン/グローバル変数: ただし、テストなどで並列アクセスが必要な場合に困ることがあるらしい。
** atan2
# DI/設定クラス引数: これがよく支持されている。テストしやすいなど。グローバル変数への参照を渡すようなイメージ。ただし、依存性の伝播のように、上から下に設定を渡す際に、関係ない大量の設定を渡すことがあったりする。
** cos
 
** sin
2のDIが最近の主流。引数で値渡し相当にすれば、並列アクセス時も無影響。伝播の問題は設計の問題。
** exp
** log
** sqrt
** int
** rand
** srand
* String
** gsub
** index
** length
** match
** split
** sprintf
** sub
** substr
** tolower
** toupper
* I/O
** close
** getline
** system


print/printfは関数ではなく、statement/文扱い。
メソッドをmain関数で呼び出すことを想定して、必要なものだけ渡るようにして、余計なものは削除する。上位・下位の関係を明確にすれば、渡すだけのパラメーターを排除できる。


==== ヘッダー出力、列別最大長さ出力。 ====
==== do-while/if ====
<nowiki>awk -F, '{if(NR==1) print $0} {for(i=1; i<=NF; ++i){if (line[i] < length($i)) line[i] = length($i)}} END {for (i=1; i<=NF; ++i) {printf line[i]","}}' data/101542.csv</nowiki>
複雑なif文と相性がいい。


==== CSV ====
for whileの無限ループで最後にbreakでも同じか
[https://qiita.com/ko1nksm/items/19407c1c53cbbc50569a シェルスクリプトの実験のために作った POSIX 準拠 awk 実装の CSVパーサー (RFC4180対応) #ShellScript - Qiita]<syntaxhighlight lang="awk" line="1">
do {
# csvparser.awk
  if (true) break;
} while(false);
if文が複雑な場合、do-whileで囲んで、breakでスキップできる。gotoに近い。
 
==== GoF ====
基本的に、具象クラスを使わずに、インターフェイスや抽象クラスを使ってインスタンスを生成するというのが、共通する基本パターン。
 
これにより、いろんなケースに同じコードで対応できる。
 
===== Factory Methodパターン =====
[https://blog.ecbeing.tech/entry/2021/01/20/114000 なぜあんなに難しい?Factory Methodパターン - ecbeing labs(イーシービーイング・ラボ)]
 
コンストラクターの代わりに、インスタンスを生成 (工場=factory) となるメソッドを使うから、FactoryMethodパターン。
 
引数の内容に応じて、異なるクラスを作成する。
 
ただ、Factory Methodパターンを採用すると、コード量が増えて複雑になる。


## Usage
複雑でややこしいだけなので、基本的に使わなくてよいと思う。
# awk -f csvparser.awk data.csv


# CSV の論理的な一行毎に呼び出されるコールバック関数(サンプル)
==== Naming ====
# row: 行番号(最初の行は1) len: フィールド数 fields: フィールドデータ
function callback(row, len, fields,  col, field) {
    for ( col = 1; col <= len; col++ ) {
        field = fields[col]
        gsub(/\\/, "&&", field)  # \ は \\ にエスケープする
        gsub(/\n/, "\\n", field) # 改行は \n にエスケープする
        print row ":" col " " field
    }
}


BEGIN { row = max_idx = 0 }
===== camelCase =====
{
https://gnusocial.jp/notice/7694551
    idx = 0
    sub(/\r$/, "")
    while ($0 != "") {
        if (match($0, /^(["]([^"]|["]["])*["]|[^,"]*)(,|$)/)) {
            fields[++idx] = ""
        } else if (match($0, /^["]/)) {
            fields[++idx] = substr($0, 2)
            for (;;) {
                if (getline == 0) exit 1
                sub(/\r$/, "")
                if (match($0, /^([^"]|["]["])*["](,|$)/)) break
                gsub(/["]["]/, "\"")
                fields[idx] = fields[idx] "\n" $0
            }
            fields[idx] = fields[idx] "\n"
        } else {
            exit 1
        }
        field = substr($0, RSTART, RLENGTH)
        $0 = substr($0, RSTART + RLENGTH)
        lastcomma = sub(/,$/, "", field) > 0
        gsub(/^["]|["]$/, "", field) && gsub(/["]["]/, "\"", field)
        fields[idx] = fields[idx] field
    }
    if (lastcomma) fields[++idx] = ""
    while (idx < max_idx) delete fields[max_idx--]
    callback(++row, idx, fields)
    max_idx = idx
}


</syntaxhighlight>awkのCSVパーサー。
!it 命名規則のキャメルケース。これ英語前提です。関数名に英語以外を使うと破綻します。


=== Other ===
getキーバリュー()みたいな関数の定義。日本語ですると境界がわからなくなるので、getキー_バリューみたいにアンダーバーで区切ったほうが分かりやすい。なるほど…


==== binary ====
===== getMyVariable() vs myVariable() =====
[https://qiita.com/ko1nksm/items/dc8f247cdc5b7b58b736 POSIX準拠のシェルスクリプトでバイナリデータを扱う #Bash - Qiita]
 
* [https://stackoverflow.com/questions/3532828/php-methods-getmyvariable-vs-myvariable naming conventions - PHP methods: getMyVariable() vs myVariable() - Stack Overflow]
* [https://stackoverflow.com/questions/139427/which-coding-convention-to-follow-for-php Which Coding convention to follow for PHP? - Stack Overflow]
 
getterとsetterの命名規則。
 
getVar()にするか、Var()にするか。C++だと後者のパターンがあったりする。getを省略できるので、省スペースになる。
 
ただ、コード補完で探しやすさがちょっと変わる。getを前置したほうがわかりやすいか。


バイナリーデータの読込はodコマンド。なければhexdump。
===== namePrefixed() vs prefixedName() =====
https://chatgpt.com/c/673bd358-3dc8-800b-8ec9-d745cc0eba85


書込はprintf。
名詞+修飾語 (形容詞) の場合のメソッドの命名規則。name+修飾語が複数ある場合name+修飾語がいい。オブジェクト指向でnameをオブジェクトとして扱う形に近い。name.methodみたいな。


head/tailの-cはPOSIXで使えたか?
例えば、nameMax、nameMinのような場合は後ろのほうが都合がいい。ただ、こういう場合はそもそもnameをオブジェクトにしてname.max()、name.min()にしたほうがいいという説がある。


== cmd.exe ==
そうではないならば、getPrefixedName()などが自然。getQueryString()など。StringQueryではない。


=== bitsadmin ===
PHPでは以下のような命名規則が好まれる。
Windowsでのファイルダウンロードコマンド


Windows 7以降ではbitsadminコマンドがあり、これがwget相当となる。
* 動詞+修飾対象=getPrefixedName/isPrefixed()
* 修飾対象+状態/修飾語=prefixdName


書式:
getPrefixedNameがいいか。後置修飾にしたいならば、そもそもオブジェクト+メソッドにすることを検討する。
bitsadmin /transfer <job name> <URL> <output path>
<job name>と<output path>は必須なので注意する。


=== certutil ===
===== map =====
Windowsでのハッシュの確認に使える。
連想配列とかハッシュ、オブジェクトなどでキーバリュー形式のデータ構造を扱うことがある。そういう変数の命名規則。
certutil -hashfile file


SHA1 ハッシュ (対象 C:\moconavi\windows\Moconavi\ext\chromium\moconavium.exe):
<code>map_[key]_[value]</code> のような形式にすると、キーとバリューが何を意味するか分かってわかりやすい。
e0da85b04b6970ac1f0c33db7a9ad607fdbd44eb
CertUtil: -hashfile コマンドは正常に完了しました。


=== rlogin.cmd ===
===== foreach =====
コマンドキーの送信を自動化できる?
[https://wiki.senooken.jp/PHP#Name_2 PHP - senooken JP Wiki]
rem rlogin.cmd
@Echo off
Set SERVER=192.168.0.0
Set USERNAME=
Set PASSWORD=
Cmdkey /generic:TERMSRV/%SERVER% /user:%USERNAME% /pass:%PASSWORD%
Start mstsc /v:%SERVER%
Timeout 5
Cmdkey /delete:TERMSRV/%SERVER%


=== 実行中プロセスのパスの確認 ===
foreach系のfor文ではキーとバリューを変数に格納して反復する。ファイルや配列に対して行うことが多い。
出典: [https://superuser.com/questions/768984/show-exe-file-path-of-running-processes-on-the-command-line-in-windows Show EXE file path of running processes on the command-line in Windows - Super User]。
  foreach (table as $row => $line)
  wmic process get ProcessID,ExecutablePath
その際の変数名は、上記のように$row/$lineにすると、行番号と行の値がはっきりしてわかりやすい。
wmic process where "name='mysqld.exe'" get ProcessID, ExecutablePath
wmic process where "name='mysqld.exe'" get ProcessID, ExecutablePath /FORMAT:LIST


=== 簡易編集モード/挿入モード ===
===== Function argument order =====
関数の引数は入力、変更、出力の順番にする。理由はこの順番で使うから。<blockquote><nowiki>https://social.senooken.jp/notice/67270</nowiki>


* [https://softantenna.com/blog/windows-10-command-prompt-no-stop/ 【Tips】Windows 10のコマンドプロンプトが意図せず止まってしまう問題を回避する方法 | ソフトアンテナ]
うーん。今晩は,CODE COMPLETEでC言語の関数の引数の順番を調べたりしていて,勉強時間がないな…
* [https://superuser.com/questions/419717/windows-command-prompt-freezing-randomly Windows command prompt freezing randomly - Super User]


Windows 10のcmd.exeは [簡易編集モード] が有効になっており、コマンドプロンプトを左クリックすると、テキストの選択が始まる。テキスト選択中はコマンドの実行が止まる。長時間かかるコマンドの実行中に誤操作で止まると困るので、これは無効にしたほうがよい。
int func(入力,変更,出力)


cmd.exeを起動-左上のアイコンをクリック-[規定値]/[プロパティ]-[オプション]-[□簡易編集モード] を選ぶ。
この順番。理由は,この順番で使うから。


そのほか、 <code>git log</code> のような制御が移るコマンドを実行してしばらくすると、操作できなくなる。
memcpyとかは例外が多い。


[□挿入モード] にすると回避できる模様。
x = bの語順からきているからとの憶測がある。


== Web ==
<nowiki>https://okwave.jp/qa/q4202225.html</nowiki></blockquote>


=== HTTP ===
==== DB ====
[https://www.rfc-editor.org/rfc/rfc9110.html RFC 9110: HTTP Semantics]
[http://blog.tojiru.net/article/277021312.html PDOの真の力を開放する - PHPでデータベースを扱う(3): Architect Note]


==== Content-Disposition ====
DBアクセスのモデル化。行をクラスとすると扱いやすい模様。
[https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Content-Disposition Content-Disposition - HTTP | MDN]


[https://datatracker.ietf.org/doc/html/rfc6266 RFC 6266 - Use of the Content-Disposition Header Field in the Hypertext Transfer Protocol (HTTP)]
getterを作ったり、データの妥当性のチェックなどもできる。
Content-Disposition: inline
 
Content-Disposition: attachment
select/insert/などはmapperでクラスとDB列名を対応付けて処理する。自前で実装する場合はこういうつくりがいいらしい。
Content-Disposition: attachment; filename="filename.jpg"
 
filenameでファイル名を指定する。ここの値は二重引用符で囲む。スペースを含む場合に必須になる。
データベース関係のデザインパターンがいくつかある。
 
* Active Record
* Data Mapper
 
===== Active Record pattern =====
 
* [https://ja.wikipedia.org/wiki/Active_Record Active Record - Wikipedia]
* [https://www.techscore.com/tech/Ruby/Rails/other/designpattern/ デザインパターンから見たActive Record | TECHSCORE(テックスコア)]
 
テーブルレコードに対応するクラスを用意して、そのクラス自体にDB操作もさせる。
 
シンプルだが、複雑な操作が苦手。
 
エンティティーがテーブルと密接なため、例えばテーブル構造が変わった場合に大量に修正必要。


==== multipart/form-data ====
Ruby on Rails/Laravel+Eloquentなどで採用。
rfc7578


* [https://datatracker.ietf.org/doc/html/rfc7578 RFC 7578 - Returning Values from Forms: multipart/form-data]
===== Data Mapper pattern =====
* [https://qiita.com/sivertigo/items/14957200af5ad953d63b Multipart/form-dataの仕様メモ #HTTP - Qiita]
[https://gihyo.jp/dev/serial/01/ruby/0014 第14回 DataMapperの使い方 | gihyo.jp]


ファイルアップロード用のMIME type。
テーブルのレコードをクラスにするのはARと共通。


リクエストヘッダー
ただし、DB操作用のクラスを用意してそちらでDB操作する。
Content-Type: multipart/form-data; boundary=--hogehoge
リクエストボディー
--hogehoge
Content-Disposition: form-data; name="user_name"
Content-Type: text/plain
test
--hogehoge
Content-Disposition: form-data; name="email"
sample@mail.com
--hogehoge
Content-Disposition: form-data; name="gender"
male
--hogehoge
Content-Disposition: form-data; name="user_profile" filename="image.jpeg"
Content-Type: image/jpeg
\xff\xd8\....
--hogehoge--
ヘッダーでmultipart/form-dataを明記して、ボディーでデータを指定する。


[https://weblabo.oscasierra.net/curl-post/ curlコマンドでPOSTする, 様々な形式別メモ |]
その都合、1テーブルに2クラス必要。


curlでの送信理由。
User/UserMapperのような対応関係。


-Fで送信データをname=data形式で指定する。ファイルの内容を指定する場合、@filenameで指定する。これを指定すると、リクエストボディーのfilename扱いにしてくれる模様。-Fを指定すると、-H 'Content-Type: multipart/form-data'が自動付与される。たぶん、-dと同様に-X POSTもつく。
2クラス必要だが、テーブル構造が変わった場合でも基本はMapperで吸収できる。
curl -X POST -F file1=@/var/tmp/sample.jpg <nowiki>https://xxxxx.net/xxxxxx</nowiki>
データとテキストを同時送信したい場合、-Fで複数指定する。
curl -X POST -F 'age=30' -F file1=@/var/tmp/sample.jpg <nowiki>https://xxxxx.net/xxxxxx</nowiki>
curlだと上記のboundaryなどをうまくやってくれるのだと思う。


リクエストボディー全体をファイルデータにする場合。
===== JOIN =====
curl -X POST -H 'Content-Type: image/jpeg' --data-binary @/var/tmp/sample.jpg <nowiki>https://xxxxx.net/xxxxxx</nowiki>
Active RecordもData MapperもJOIN時の扱いが一番重要。単一エンティティーしか扱わないならどちらも同じ。


=== IP address ===
基本はエンティティーのプロパティーに持たせる感じ。
出典: [https://glocalnet.jp/vpn/topix/archives/67#:~:text=%EF%BC%94%EF%BC%8E%E5%9B%BA%E5%AE%9AIP%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E3%81%AE%E5%8F%96%E5%BE%97%E6%96%B9%E6%B3%95%20%E5%8F%96%E5%BE%97%E6%96%B9%E6%B3%95%E3%81%AF%E4%B8%BB%E3%81%AB3%E3%81%A4%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82,%E3%83%BB%E5%A5%91%E7%B4%84%E3%81%97%E3%81%A6%E3%81%84%E3%82%8B%E3%83%97%E3%83%AD%E3%83%90%E3%82%A4%E3%83%80%E3%81%A7%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%A8%E3%81%97%E3%81%A6%E7%94%B3%E3%81%97%E8%BE%BC%E3%82%80%E6%96%B9%E6%B3%95%20%E3%83%BB%E5%9B%BA%E5%AE%9AIP%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E3%81%AB%E5%AF%BE%E5%BF%9C%E3%81%97%E3%81%A6%E3%81%84%E3%82%8BSIM%E3%82%92%E5%A5%91%E7%B4%84%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95%20%E3%83%BBVPN%E3%82%92%E5%88%A9%E7%94%A8%E3%81%97%E3%81%9F%E5%9B%BA%E5%AE%9AIP%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E3%81%AE%E6%8F%90%E4%BE%9B%E4%BC%9A%E7%A4%BE%E3%82%92%E5%88%A9%E7%94%A8%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95 固定IPアドレスの取得方法 ~実は簡単!フリーランスの方も必見です~|VPN活用日記|トピックス|グローカルネットの快適VPN【公式】| 株式会社グローカルネット]。


自宅サーバーを行う際、固定IPアドレスが必要になる。
<blockquote>datamapperパターンでjoinする場合、エンティティーの扱いはどうなるの?


取得方法がいくつかある。
`DataMapper`パターンで`JOIN`を行う場合、エンティティの扱いは設計次第ですが、いくつかの注意点があります。`DataMapper`パターンは、データベースのテーブルとエンティティの間にマッピングを行い、エンティティはドメインロジックを持ち、データベースアクセスの責務を持たないことが特徴です。そのため、`JOIN`の処理をどの層で行うかを慎重に設計する必要があります。


* 契約しているプロバイダでオプションとして申し込む方法
以下、`JOIN`を行う際のエンティティの扱いと実装方法について解説します。
* 固定IPアドレスに対応しているSIMを契約する方法
* '''VPNを利用した固定IPアドレスの提供会社を利用する方法'''


VPNの固定IPアドレスが安いらしい。ryoかsuwakoが解説していた気がする。
### 1. マッパークラスでの`JOIN`実装


=== Authentication ===
`JOIN`を伴う複雑なクエリが必要な場合、マッパーが直接`JOIN`を使って複数テーブルを組み合わせた結果を取得し、それを複数のエンティティとしてマッピングする方法があります。例えば、ユーザーと注文を持つシステムで、ユーザーとその注文を一緒に取得したい場合、`UserMapper`で`JOIN`を行い、結果セットを`User`と`Order`エンティティに分割してマッピングします。
認証方式がいくつかある。HTTPで定義される認証方式 (HTTP認証) が有名。


==== Basic認証 ====
```python
出典: [https://ja.wikipedia.org/wiki/Basic%E8%AA%8D%E8%A8%BC Basic認証 - Wikipedia]。


Authorization HTTPヘッダーにBasicのあとに [username:password] をBASE64でエンコードして送信する認証方式。
class UserMapper:
GET /private/index.html HTTP/1.1
Host: example.com
Authorization: Basic cm9vdDpwYXNzd29yZA{{=}}{{=}}
盗聴や改ざんが簡単だが、シンプルという利点がある。


==== OAuth ====
    def find_user_with_orders(self, user_id):
Ref


* [https://ja.wikipedia.org/wiki/OAuth OAuth - Wikipedia]
        sql = """


OAuth (オーオース) 権限の認可のための標準。OAuth 2.0が最新の標準。
            SELECT * FROM users


以下が登場人物。
            JOIN orders ON users.id = orders.user_id


* resource owner: あるサイトのユーザー。
            WHERE users.id = %s
* resource server: あるサイトのユーザーのデータの保有サーバー。
* clent: クライアントアプリ。リソースサーバーのデータを使用したい。
* authorization server: クライアントにサイトへのアクセスを認証するサーバー。アクセストークンを発行して行う。


アクセストークンが実質的なパスワードのようなものだが、resource serverのパスワードを直接渡していない点が重要な違い。パスワードを直接渡さないことで、機能別に権限を細かく利用可否を制御できる。
        """


処理の流れ。
        results = self.db.execute(sql, (user_id,))


# client->resource owner: Authorization Request。ここでユーザーが手操作でアクセスを承認する。
       
# client<-resource owner: Authorization Grant。
 
# client->authorization server: Authorization Grant。承認された情報でアクセストークンを要求。
        user = User(results[0]['user_id'], results[0]['user_name'])
# client<-authorization server: Access Token
 
# client->resource server: Access Token。アクセストークンでアクセス。
        orders = [Order(row['order_id'], row['product_name'], user) for row in results]
# client<-resource server: Access Token


Consumer Key/Secret: アプリ識別用のID/PW。
        user.orders = orders


Access Token: サイトにアクセスするためのパスワード。
        return user


=== API ===
```


==== 複数レコードの登録 ====
この方法では、1つのSQLクエリで必要なデータをすべて取得し、エンティティのプロパティにそれぞれのデータを設定します。
[https://buddypia.com/2021/11/14/%E8%A4%87%E6%95%B0%E3%83%AC%E3%82%B3%E3%83%BC%E3%83%89api%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E8%AA%BF%E3%81%B9%E3%81%A6%E3%81%BF%E3%81%9F%E8%A9%B1/ 複数レコードの登録・更新・削除のREST APIについて調べてみた話(+@ Graph API) - junode | 個人開発ブログ]


既存のAPIは単一リソースの処理しかないことが多い。JavaScriptなどで単一リソースを何回も呼べばいいというのはそうだけど、JavaScriptなしでは動作しない。一括処理用のAPIを作るしかなくないか?
### 2. リポジトリでの集約


[https://www.yamarkz.com/blog/rest-web-api-practice REST WebAPIのプラクティス | yamarkz.com]
`JOIN`を使わず、各エンティティを個別に取得した後、リポジトリが集約の役割を担う方法もあります。リポジトリが各エンティティの`Mapper`を呼び出し、必要なエンティティ同士を関連付けることで`JOIN`を再現します。例えば、まず`UserMapper`でユーザー情報を取得し、次に`OrderMapper`で該当ユーザーの注文を取得してエンティティ間で関連付けます。


delete_bulkなどのような一括処理用のAPIを作るしかない。内部的には単一処理のAPIを作る感じだったとしても。
```python


==== パラメーター ====
class UserRepository:
[https://stackoverflow.com/questions/25385559/rest-api-best-practices-args-in-query-string-vs-in-request-body json - REST API Best practices: args in query string vs in request body - Stack Overflow]


パラメーターの指定に3種類ある。
    def __init__(self, user_mapper, order_mapper):


# リクエストボディー
        self.user_mapper = user_mapper
# クエリー
# パス


パスはIDなどを指定する場合だけわかりやすい。それ以外のオプションはクエリーのほうがいい。
        self.order_mapper = order_mapper


ボディーは、通常サーバーのアップロード・ダウンロードデータとして使われる。クエリーはデータの指定に使う。
    def get_user_with_orders(self, user_id):


この原則に従うとシンプルだろう。
        user = self.user_mapper.find(user_id)


* URIには長さの制限がある。
        orders = self.order_mapper.find_by_user_id(user_id)
* ボディー
 
** 引数が非常に多い場合。
        user.orders = orders
** 画像などバイナリーデータ。
 
** キー・値構造を持たない場合。
        return user
* クエリー文字列
** 引数を簡単に確認できる。
** 共通の引数の場合。


==== 検索機能のGET/POST ====
```</blockquote>UserテーブルとOrderテーブルがあって、あるユーザーの注文一覧を取得したい場合を考える。


* [https://stackoverflow.com/questions/20550514/post-or-get-in-a-search-form .net - POST or GET in a search form? - Stack Overflow]
結局、user.ordersみたいな感じで、エンティティーに外部テーブルのレコードを配列で持たせるつくりになる。


検索機能にGETとPOSTのどちらを使うか?という議論がある。
クロス集計する場合は、users[0].orderみたいな感じ。メインのエンティティーのプロパティーに持たせる。フラットじゃないのでちょっと気持ち悪い。が、まあ構造としてこうなるのは順当。


データ登録するわけなじゃないのだから、GETがいいんじゃない?
方法として、1回のSQLで取得するか、それぞれのエンティティーを取得してマージするか。1回のSQLでやったほうが当然いい。


POSTだと、JSONをそのまま送れるので、複雑なケースに対応できる。特に、配列の送信が重要。
==== Other ====


GETのほうが検索条件をブックマークにできたり、URLを共有できるので、基本は便利。
===== 1対1-多対多 =====
プログラミング言語でデータの関連付けをすることがある。


==== レート制限対策 ====
1対1の場合、配列、連想配列のキーバリュー形式のデータがぴったり。


* [https://pikodon.com/note/php/api-cache/ APIの利用制限対策 | Web開発ノート]
多対多の場合。これも配列。二次元配列で基本は0要素目など。
* [https://keirinomikata.zendesk.com/hc/ja/articles/4404549985945-%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E6%95%B0%E3%81%AB%E3%82%88%E3%82%8B%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E5%88%B6%E9%99%90%E3%81%AE%E5%AF%BE%E7%AD%96%E6%96%B9%E6%B3%95 リクエスト数によるアクセス制限の対策方法 – 請求管理ロボ ヘルプ]
$array[][]


いろいろ方法がある。
== AI ==


* cronなどでデータをサーバー上 (DBなど) に定期保存して、保存データを表示させる。
=== 対話AI ===
* 配列を利用して、1回のリクエストでまとめて取得する。
* インターバルを設ける。
* HTTP 429/413を検知して、リトライする。


==== 指数関数的バックオフ ====
==== List ====
[https://notepm.jp/blog/24168 【2024年版】対話型AIサービスおすすめ11選を徹底比較!チャットボットとの違い・メリット・課題・選び方なども紹介 - NotePM]


* [https://docs.link.getmoneytree.com/docs/faq-rate-limiting APIレート制限は何か、どのように対処するのか?]
いろいろある。
* [[wikipedia:Exponential_backoff|Exponential backoff - Wikipedia]]
{| class="wikitable"
* [https://cloud.google.com/memorystore/docs/redis/exponential-backoff?hl=ja 指数バックオフ  |  Memorystore for Redis  |  Google Cloud]
|+
* [https://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/cloud-design-patterns/retry-backoff.html バックオフパターンで再試行 - AWS 規範ガイダンス]リトライ時は以下のアルゴリズムがいいらしい。
!Name
wait_interval = base * 2^n +/- jitter
!
!
!
|-
|Bing
|
|
|
|-
|Perplexity AI
|
|
|
|-
|ChatGPT
|
|
|
|-
|Google Gemini
|
|
|
|}
 
==== ChatGPT ====


* <code>wait_interval</code> は、API が HTTP 429 で応答した場合に、システムがリクエストを再試行するまでの時間となります。
===== Plan =====
* <code>base</code> は最初の間隔、つまり最初の再試行までの待ち時間です。この値には3000msを使用することをお勧めします。
[https://openai.com/chatgpt/ ChatGPT | OpenAI]
* <code>n</code> は、現在の呼び出しの前にリクエストが通らなかった数です。複数のスレッドやプロセスを使用して並行してAPIを呼び出している場合、<code>n</code>の値は現在のスレッド/プロセスにスコープされます。この値は、現在のスレッド/プロセスが、最後に成功した応答から何回 429 "Too Many Requests" エラーに遭遇したかを表します。
* <code>jitter</code> は 0 から <code>base</code> の間の乱数です。これは、複数のスレッド/プロセスが全く同時にAPIを呼び出さないように、リクエストを少しずつ分散させるために使用されます。システムが待機するたびに、この乱数値を再計算し <code>wait_interval</code> の合計に加算するか減算するか、ランダムで選択してください。


=== curl ===
Free/Plusの2のプランがある。
HTTPの通信のコマンドラインでの確認でよく使う。
{| class="wikitable"
|+
!
!Free
!Plus
|-
|金額 [USD/月]
|0
|20
|-
|機能
|基本
|アーリーアクセス
|-
|エンジン
|GPT-4o mini
|GPT-4/GPT-4o/GPT-4o mini
|-
|制限
| -
|GPT-4oの5倍以上のメッセージ送信
|-
|その他
| -
|データ分析、ファイルアップロード、ビジョン、Webブラウジング
|-
|画像生成
| -
|DALL-E
|}
送信可能なメッセージ数、エンジン、画像生成などが大きな違いだろう。


==== Basic ====
===== Account =====
[https://curl.se/docs/tutorial.html curl - Tutorial]
公式サイトにアカウントの意味の説明がない。しかたないので、ChatGPTに質問。<blockquote>ChatGPTに会員登録する意味は何ですか?
* -X: メソッド指定
* -d/--data-urlencode: リクエストボディー (key=value)を指定。-X POSTも自動指定になる。
curl -H "Content-Type: application/json" -d '{"name":"佐藤", "mail":"sato@example.com"}' localhost:5000/api/v1/users
JSONで送信する場合、ヘッダー指定が必須。


<nowiki>*</nowiki>-F: multipart/formのform指定。
curl -F "coolfiles=@fil1.gif;type=image/gif,fil2.txt,fil3.html"
  <nowiki>http://www.example.com/postit.cgi</nowiki>
@でfilename相当の指定。;でmime typeも指定できる。


@/</;type=自体を送信したい場合、-Fではなく、--form-stringを指定する。
ChatGPTに会員登録する主な利点はいくつかあります。


==== curl: (60) SSL certificate problem: self-signed certificate ====
1. **パーソナライズされた体験**: 登録すると、あなたの好みや過去のやり取りに基づいて、よりカスタマイズされた応答が得られます。
Ref: [https://linuxfan.info/curl-insecure curlで「自己署名証明書」を受け入れるには【curl: (60) SSL certificate problem: self signed certificate】 | LFI].


--insecureオプションを指定すると、localhostなどでの自己署名証明書を許可する。
2. **履歴の管理**: 過去のチャット履歴を保存し、いつでも見返すことができるため、情報の確認が簡単になります。


==== curl: Failed writing body ====
3. **新機能へのアクセス**: 登録ユーザーは新しい機能やアップデートを優先的に利用できる場合があります。
[https://askubuntu.com/questions/1449492/right-after-piping-to-head-tail-curl-23-failure-writing-output-to-desti pipe - Right After piping to "head"/"tail": "curl: (23) Failure writing output to destination" - Ask Ubuntu]


以下のようにhead -n 1を指定するとcurlがエラーを出力する。
4. **プレミアム機能**: 一部のサービスでは、会員登録をすることで、より高度な機能やサポートが提供されることがあります。
curl -H "Content-Type: application/json; charset=utf-8" -H "X-HD-apitoken:$TOKEN"        -d "{\"dbSchemaId\":$dbSchemaId, \"limit\":1, \"offset\":$offset}"        <nowiki>https://$DOMAIN/$ACCOUNT/api/csvexport/version/1.0</nowiki> | head -n 1


curl: Failed writing body
5. **セキュリティとプライバシー**: アカウントを持つことで、データの管理やプライバシーの設定をより細かく調整できます。
curlは標準出力に全部書き込めたかチェックしているようで、head -n 1で切り捨てたらcurlはエラーになる。


対策は、curl -sで出力を抑制するとのこと。これで解決。
興味があれば、ぜひ登録を検討してみてください!他に質問があればお知らせください。</blockquote>自分の過去の質問の履歴を見れるだけでも便利かも。


=== Wireshark ===
===== 方法 =====


==== TLS ====
====== 質問の分割 ======
Ref: [https://www.toyo.co.jp/onetech_blog/articles/detail/id=36994 SSL/TLSの復号#1 ~Wiresharkの設定~ | 東陽テクニカ | “はかる”技術で未来を創る | ワン・テクノロジーズ・カンパニー].
https://chatgpt.com/c/673bdc0d-e0e0-800b-a22b-4fa19e64476c


Wiresharkで通信パケットを確認する場合、デフォルトでTLSで暗号化されているので、内容がわからない。WiresharkでTLSに対応しておく必要がある。
Q. chatgptで質問するとき、連続して質問すると、同じURLで複数の質問が表示される。リロードして質問を分けたほうがいいのか?


[Preferences]-[Protocols]-[TCP] を選ぶ。
A. どちらでも問題ない。が、質問が関連しているなら同じチャットで継続したほうがいい。直前の質問も文脈を考慮できる。完全に話が異なるなら分けたほうが後で整理したり、URLを共有したときにわかりやすい。


* ☑Allow subdissector to reassemble TCP stream
===== 感想 =====
* ☑Reassemble out-of-order semgemnts


上記をチェックしておく。デフォルトでチェックされていた。
====== 2024-11-14 Thu ======
https://gnusocial.jp/notice/7806505<blockquote>[[/gnusocial.jp/group/32/id|!it]] [[/gnusocial.jp/group/28/id|!ai]] 業務でPHPの開発作業をしていて、ChatGPTを使いだして便利に感じています。検索エンジンの代わりに使っています。


続いて、セッションごとのPre-Master Secretを登録する。
例えば、「laravel eloquentでリレーション先のテーブルの主キー名の取得方法は?」と質問します。


Chrome/Firefoxだと、環境変数SSLKEYLOGFILEを設定すれば、このファイルにTLSセッションキーを出力するので、これをWiresharkで読み込むことで、復号対応する。
[[/chatgpt.com/c/67354314-fbdc-800b-a4e4-65f96d1a8fb2|https://chatgpt.com/c/67354314-fbdc-800b-a4e4-65f96d1a8fb2]]


以下のコマンド相当で、任意のファイル・場所にログファイルを指定する。
getRelatedというややマニアックなメソッドを教えてくれます[eloquent getrelated] で検索してもなかなかたどり着けないです。
export SSLKEYLOGFILE=/tmp/sslkey.log
Macだとlaunchctlで設定しておくといい。これでWebブラウザー経由の場合は見えるようになる。


=== Security ===
こういう検索エンジンで検索しにくい質問で便利だなと思います。


==== DoS攻撃 ====
検索エンジンで検索すると、的外れな情報も大量にヒットします。対話AIはそのごみの混ざった検索結果を分析した結果をコンパクトに返してくれます。対話AI使わなくても、検索エンジンで時間かければわかりますが、大幅に時間短縮できます。
いくつか対策方法がある。


* [https://lite.ip2location.com/ip-address-ranges-by-country?lang=ja 国別のIPアドレス範囲]
大量の凡人健常者が取り組んだ方法論として決まりきったものは、記憶の問題、ただの神経衰弱です。こういうのを検索エンジンの改良版としてAIに任せるのはいい使い方だと思います。
* [https://rakko.tools/tools/11/ IPアドレスから住所検索:国、地域の特定 | ラッコツールズ🔧]


サーバーログにIPアドレスが残るから、それで攻撃元の国を特定して、該当国を一括アクセス拒否。これが効果あるかもしれない。
個人的に、ただの知識、事実は重要度高くないと思いますが、一般社会では評価する側の頭が悪いので、これが重宝されます。


攻撃元の国は途上国とかが多いだろうから。IPアドレスは簡単に変更できるが、国を変えるのはたいへんだろう。
同僚や先輩に聞くより対話AIのほうがよほど頭いいです。話すことないです。聞くほうが時間の無駄なので。凡人はどんどん要らなくなります。


==== バリデーションの実装 ====
一方、私みたいなキチガイのデータは少ないので、検索エンジンやAIに聞いても出てこないです。世界で自分だけのオリジナルに専念するのがたぶんいいです。</blockquote>


* [https://teratail.com/questions/81861 フロント側で入力チェックをしていればサーバー側では入力チェックは必要ない?]
====== 2024-11-19 Tue ======
* [https://qiita.com/mi2__user/items/f2f415ccbb0a625c8647 フロントエンドの"バリデーション"は最低限の方がいいらしい。 #TypeScript - Qiita]
https://gnusocial.jp/notice/7867350<blockquote>[[/gnusocial.jp/group/28/id|!ai]] ChatGPTが検索エンジンの改良版としてやっぱり便利。さっきこういう質問しました。


基本的に、バックエンドで主にチェックして、フロントエンドはUXの向上目的で実装する。データの重複チェックはDBアクセスが必要だったりするから。また、API経由などフロントがそもそもないケースもある。
phpのメソッド名で、英単語の修飾語は前と後ろどちらがいい?例えば、namePrefixed()とprefixedName()のどちらがいい? [[/chatgpt.com/c/673bd358-3dc8-800b-8ec9-d745cc0eba85|https://chatgpt.com/c/673bd358-3dc8-800b-8ec9-d745cc0eba85]]


ただ、社内システムのような、画面経由でしか使わない。悪者がほぼいないと思われるケースは、フロントエンドでの検証だけでも十分に感じる。
私はこのレベルの細かい疑問がすぐ浮かぶのです。これを人間にきくと、頓珍漢な回答だったり、そもそも回答してもらえないし、何ならこういう質問した私がなぜかキチガイ扱いされて、微妙な雰囲気になって、質問できなくなって、ストレスが溜まって、居づらくなって早期退職になるんです。意味不明です。ただの質問にお気持ちの配慮とか面倒なので。


=== Browser ===
この間、 [[/misskey-square.net/users/9g2o6eycu3|@yuriha]] に突っ込まれた件も、たぶん対話AIとお互い会話したほうが有意義だったんじゃないかとすら思います。相手も私に突っ込む前に対話AIと会話したほうが自分の主張の自己矛盾、頓珍漢さに気づけたんじゃないかとすら思えます。私が突っ込んでまーた私がキチガイ扱いされるのも回避されます。対話AIからの客観的な指摘なら、同じ内容であっても、キチガイの私が言うより納得しやすいでしょう?同じ内容なら対話AIのほうが凡人健常者にとっては、信じ込みやすいでしょ?


==== Chromium ====
対話AIだとお気持ちの配慮いらないし、当たり前ですけど、キチガイ扱いされることもないので、快適です。元々対話AIには懐疑的でしたが、どちらかというと私のようなキチガイが凡人健常者の知識を拝借するためにあるような印象を持ちます。


===== Extension =====
検索エンジンでも調べることはできますが、めちゃくちゃ時間かかるんです。自分で複数の意見をみつけて、頭の中で比較検討して整理するので。これを一瞬でやってくれるのが楽。途中のデータ整理、目視は単純作業に近いのです。他のことに頭使えます。
Chromme系で愛用拡張機能を列挙する。


* [https://chromewebstore.google.com/detail/create-link/gcmghdmnkfdbncmnmlkkglmnnhagajbm Create Link]:
もはや技術とか、ただの暗記の神経衰弱は別にいらないです。一般企業の上長とか、士業のように、単純知識でマウント取るタイプの仕事はこれで確かに駆逐されます。どうせ対話AIのほうが賢いのだから。知識量で勝てるわけないです。全世界の情報の集積結果なんだから。


==== 開発者ツール ====
凡人健常者の知識を拝借して、世界でだれにも真似できないキチガイ部分に専念できます。GNU socialの開発もこれでいけると思います。</blockquote>


===== イベントリスナー =====
== VCS ==
[https://yuzu441.hateblo.jp/entry/2016/12/12/120000 要素に設定されているイベントを調べよう - ゆずめも]


[Elements]-[Event Listeners]-[handler]-右クリック-[Show function definition] でイベントリスナー関数の定義を確認できる。
=== List ===
Comparison of issue-tracking systems - Wikipedia <nowiki>https://en.wikipedia.org/wiki/Comparison_of_issue-tracking_systems</nowiki>


==== Other ====
BTS。GitHubみたいな。PHP製の以下がよさそう。


===== Windows Safari =====
* Tuleap
* Phabricator/Phorge
* MantisBT
* FusionForge
* GLPI
* Faveo Helpdesk
* [https://sourcehut.org/ sourcehut - the hacker's forge]: Python製。FSF推奨。


* [https://web.archive.org/web/20220220134447/https://jp.techcrunch.com/2012/07/27/20120725apple-safari-for-windows-ends/ Appleは静かにWindows版Safariの開発から手を引いてしまったのだろうか? | TechCrunch Japan]
VCSとの統合状況がまちまち。
* [http://web.archive.org/web/20120728130701/https://support.apple.com/kb/DL1531 Safari 5.1.7 for Windows]


一応ある。2012-05-09のSafari 5.1.7までWindows版が提供されていた。DL1531。
=== Git ===


=== Other ===
==== Commit ====


==== Tool ====
===== マージコミット後のコミット追加 =====
マージコミット後に次の開発作業を始めることが多い。が、直後の初回のコミットを追加したい場合困る。


* [https://web-toolbox.dev/ Web ToolBox | 開発者向けのオンラインツール]
git rebase -iにすると、コミットが残るから。編集はできるが、その直前にコミットの追加ができない。マージコミットは扱いが特殊で直接rebaseで編集できない。
* [https://tm-webtools.com/ TM - WebTools]


いくつかWeb関係の開発で役立つツール集を公開しているサイトがある。
しかたないので、該当コミットでブランチを作成して、コミット。その後、既存の修正ブランチをrebaseでそのコミットの後にくっつける。これでいける。


==== localhost ====
===== コミットオプション =====
[https://git-scm.com/docs/git-commit Git - git-commit Documentation]


* [[wikipedia:Special-use_domain_name|Special-use domain name - Wikipedia]]
コミットメッセージ指定のためのオプションがある。
* [https://ja.wikipedia.org/wiki/.localhost .localhost - Wikipedia]


RFC 6761 で規定。RFC 2606<nowiki/>で予約。DNSに登録されることはないため、テスト目的で使用可能。ループバック (送信元にそのまま返す) インターフェイス。
* -m|--message <message>: コミットを文字列で指定。複数指定可能で、その場合段落で区切ってくれる。2行目以後を書きたい場合などで使う。
* -C|--reuse-message <commit>: 指定したコミットのコミット情報を再使用する。
* -c|--reedit-message <commit>: -Cの同じだが、編集画面を表示してコミットメッセージを編集して再使用する。
* -F|--file=<file>: 指定したファイルをコミットメッセージに使う。-を指定すると標準入力を使う。


IPv4=127.0.0.1/IPv6=::1とされている。
基本は-m。-mの複数指定。


== Shared Host ==
===== 過去コミットのメールアドレスの変更 =====


=== Free ===
* [https://www.git-tower.com/learn/git/faq/change-author-name-email How can I change the author (name / email) of a commit? | Learn Version Control with Git]
無料で使用可能な共用ホスティングサービスがある。
* [https://zenn.dev/flyingbarbarian/articles/241627cae5988a Gitのcommitの名前やメールアドレスを過去からまとめて変更する]


==== スタードメイン無料サーバー ====
単一コミットのメールアドレスを指定する場合、commitに--authorを指定する。
ドメインをセットで利用する必要があるものの、スタードメインのスタードメイン無料サーバーがけっこういい。
git commit --author="John Doe <john@doe.org>"
--amendと併用することで、過去コミットも変更できる。


[https://www.star-domain.jp/service/free_server.php 無料レンタルサーバー | スタードメイン - ドメイン取得 100円(税込)~]
数が少ないなら、rebase -iで1個ずつamendする。数が多いならfilter-branch。


jpドメインの金額が相場の中では安い方で、それに無料サーバーがついていくる点。
===== 第一コミットの変更 =====


* ディスク容量 20GB
* [https://dev.classmethod.jp/articles/git-rebase-from-root/ [Git] 最初のコミットを含めてrebase -iする方法 | DevelopersIO]
* DB 1GB
* [https://git-scm.com/docs/git-rebase Git - git-rebase Documentation]


ただし、SSHやコマンドは使えないので、FTPでWordPressを展開して設置するとか、そういう簡単な使い方だけ。ただ、それでもWordPressでWebサイトを構築するくらいなら十分だと思う。
通常、第一コミットはammend以外では変更できない。


=== CORESERVER ===
rebase --root [branch] でブランチの第一コミットも参照して改変可能。


==== メール ====
===== マージコミットの打ち消し =====
マージコミットは扱いがやや特殊。
git revert -m 1 マージコミット
git reset --hard HEAD~1 # マージコミット前
どちらか。


* [https://www2.bwt.jp/wiki/?Custom_Filter_of_Coreserver Custom_Filter_of_Coreserver - PukiWiki]
==== stash ====
* [https://help.coreserver.jp/manual/v2/spam-filter/ スパムフィルターの設定 | マニュアル | サポート | レンタルサーバー CORESERVER(コアサーバー)]
* [https://help.coreserver.jp/manual/v1/customfilter/ カスタムフィルターの設定 | マニュアル | サポート | レンタルサーバー CORESERVER(コアサーバー)]


情報
===== 復元 =====
[https://qiita.com/generosity-naman/items/237338f8fe5b7e3b9a76 Git Stashの復元: 誤って削除されたスタッシュの復元方法 #Git-Stash - Qiita]


* [https://www2.bwt.jp/wiki/?CoreServer_Mail_Custom CoreServer_Mail_Custom - PukiWiki]
git stash drop実行時に、削除したコミットのSHA1が表示される。
* [https://bwt.blog.ss-blog.jp/2021-03-28 coreserverのメール設定:BWT Lab.:SSブログ]
* [https://qwerty.work/blog/2017/01/valueserver-spammail-filter-rule.php バリューサーバーのフィルター設定でスパムメール(迷惑メール)対策する方法 - QWERTY.WORK]
* [https://awmt.jp/dekirukana/archives/2253 コアサーバー V1にてカスタムフィルターで「ごみ箱」を指定したときの確認方法 – AWMTの、できるかな?]


ルールが特殊なので注意する。
そのSHA1をapplyで指定すれば、取り込める。
git stash apply [stash_hash]


ゴミ箱に振り分ける場合。
===== リモート =====
[https://qiita.com/mather314/items/a1536c52a2eb0426b2b5 gitの不要なブランチを消すコマンド #Git - Qiita]
git fetch -p/--prune
リモートの削除済みブランチをローカルに同期する。


順1 で[<code>./.Trash</code>] を指定
===== リモートの最新タグ =====
https:/stackoverflow.com/questions/20734181/how-to-get-list-of-latest-tags-in-remote-git


順2
git ls-remote --tag --sort=taggerdate


* 条件:  [<code>.*</code>]
date関係のsortはオブジェクトへのアクセスが必要なので、ローカルにないとダメとか。
* 処理:  <code>./</code>、に振り分ける


条件部分には正規表現が使えるように見える。
https:/git-scm.com/docs/git-ls-remote.html


破棄にしないといけない。転送する場合、カスタムフィルターの中に転送を入れる。条件を.*にする。
https:/stackoverflow.com/questions/10649814/get-last-git-tag-from-a-remote-repo-without-cloning


カスタムフィルターにくせがある。
git rev-listでいけそう。


* エスケープ(\を前置する)が必要な文字は「'」「"」「|」「`」「~」「?」「!」
https:/gist.github.com/rponte/fdc0724dd984088606b0


==== Value Domain ネットde診断 byGMO ====
===== 差分ファイル抽出 =====
情報源: [https://qiita.com/kaminaly/items/28f9cb4e680deb700833 gitで差分ファイルを抽出する #Git - Qiita]。


* [https://www.value-domain.com/information/detail/?no=20240606-1 弊社レンタルサーバー上で運用中のドメインにおける自動セキュリティ診断開始のお知らせ | お知らせ - バリュードメイン]
git archiveとgit diffを組み合わせる。
* [https://www.value-domain.com/security/net-de-shindan/ Value Domain ネットde診断 byGMO - バリュードメイン]
git archive --format=zip --prefix=root/ HEAD `git diff --diff-filter=d --name-only HEAD^ HEAD` -o archive.zip
ただし、この方法はファイル数がARG_MAX以下の場合だけ。ファイル数が多い場合だめ。


2024-06-07 Friからバリュードメイン系の利用者に無料で提供しているセキュリティー診断ツール。
git diff --name-onlyで一覧を出力させて、1個ずつcp -pで階層を維持してコピーするしかないかも?


== Analytics ==
例:
mkdir -p archive
git diff --name-only new_base 44765_upgrade-base-version | xargs -i cp -p --parent "{}" archive/


=== Tool ===
===== core.autocrlf =====
サイト分析用のツールがいくつかある ([https://hidesunblog.com/blog-ranking-sites/ 2023年ブログランキング!おすすめブログランキングサイト比較【一般人向け】])。
<blockquote>warning: in the working copy of 'docker/README.md', LF will be replaced by CRLF the next time Git touches it</blockquote>Windowsでは改行にCR+LFを使うが、mac/LinuxはLFのみ。これの違いの処理のための設定がcore.autoclrlf


* SimilarWeb
* true=コミット時にCRLFをLFに自動変換。チェックアウト時に逆。Windows向けの設定。
* Ubersuggest
* false=変換しない。
* ahrefs
* input=コミット時にCRLFをLFに自動変換のみ。mac/Linux向け。Windowsではチェックアウト時にCRLFになるが、mac/LinuxはLFになる。
* Googleキーワードプランナー


=== 閲覧数取得 ===
わかりにくい。基本はfalseで良いと思われる。
出典: [https://affiliate-jpn.com/archives/5595 GoogleAnalyticsで自サイトの人気記事ランキングを表示する方法 | アフィリエイトJAPAN]。


* [行動]-[サイトコンテンツ]-[全てのページ]
===== gitkの文字化け対策 =====
* [表示する行数]=5000
[https://www.pistolfly.com/weblog/2010/02/gitk.html gitkのエンコーディングを設定する - Pistolfly]
* [エクスポート]=TSV


=== 流入元特定 ===
gitkはシステムのデフォルトエンコーディングで表示しようとするので、文字エンコーディングを指定しておく。
「[https://support.google.com/analytics/thread/252885536/%E4%BC%9A%E5%93%A1%E7%99%BB%E9%8C%B2%E7%94%BB%E9%9D%A2%E3%81%AE%E6%B5%81%E5%85%A5%E5%85%83%E6%8E%A2%E7%B4%A2%E6%96%B9%E6%B3%95%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6?hl=ja 会員登録画面の流入元探索方法について - Google アナリティクス コミュニティ]」どのページから会員登録があったか、会員登録に結びつく記事は非常に重要。<blockquote>こんにちは。
git config --global gui.encoding utf-8


探索レポートでユーザーセグメントを作成する集計方法はいかがでしょうか。
===== ファイル名などの文字化け対策 =====
[https://qiita.com/kumazo/items/2169e1ee7be278f82b94 Git for Windows で日本語を使いたい #Vim - Qiita]
git config --global core.quotepath false
git config --global gui.encoding utf-8


・自由形式レポートを作成
===== 改名と修正 =====


・セグメント作成 > ユーザーセグメント
* [https://qiita.com/yukimura1227/items/fbb076db61a2e43a32e3 gitでrename&modifyしたファイルのログを追跡できるようにしたい場合 #Git - Qiita]
* [https://zenn.dev/yoichi/articles/how-git-handles-renaming Gitはファイルのリネームをどう扱うか]


・条件は page_view > パラメータ page_location > 含む:会員登録画面のURL を指定
改名と修正を同時にすると、改名を検知できない。


・「会員登録画面閲覧ユーザー」などセグメント名をセットして保存
-Mオプションを指定すると、類似度で同時も検知できる。が、基本はリネーム・改名と修正は別コミットにしたほうがよさそう。


・探索レポートにセグメントを適用
===== 差分無視 =====
[https://qiita.com/odekekepeanuts/items/8a056b87c9e481e07e57 git diffの--ignoreオプションにおけるスペース、タブ、改行の扱いを理解する #Git - Qiita]


・ディメンション:セッションの参照元 / メディア、ランディング ページ + クエリ文字列
-wでインデント違いを無視してくれる。


・指標:セッション
===== squash =====
squashすると、squash対象コミットが、対象の直前のコミットに含められる。


ご確認よろしくお願いいたします。
===== gitignore =====
[https://git-scm.com/docs/gitignore/en Git - gitignore Documentation]


※ページ閲覧の発生しなかったセッションはランディングページが (not set)になります。
====== Format ======
記述方法を整理する。


 開きっぱなしのタブから再訪問するセッションなどが該当します。ご参考までに。</blockquote>PMProでも似たような回答。<blockquote>Google Analytics 4 can track ecommerce conversions and then assign page value to posts that were a part of their conversion path for that engaged session. </blockquote>
* 空行は無視。
* #始まりの行はコメント扱い。
* 終端スペースは無視。
* !接頭辞はパターン否定。つまり、除外ではなく含める。以前除外された一致を再び含める。ただし、親ディレクトリーが除外されている場合、以下のファイルは含められない。パフォーマンス上の理由。順番に注意する。
* /はディレクトリー区切りとして使用。先頭、中間、末尾で登場する。
** 先頭と中間の/は相対パスを意味する。
** それ以外、末尾の/と/なしの場合、現在以下のディレクトリーにもマッチする。
** 末尾が/で終わる場合、ディレクトリーのみに一致。/がない場合、ディレクトリーとファイルの両方に一致。
* *は/以外にマッチ。?は/以外の任意の1文字にマッチ。[a-zA-Z] の範囲記法も使用可能。fnmatch(3) FNM_PATHNAMEフラグのパス名展開に準じる。
* **は特殊な意味がある。
** **/=全ディレクトリー。**/fooは配下の全fooにマッチ。**/foo/barはfoo以下の全barにマッチ。
** /**=配下のすべてにマッチ。
** a/**/b=a/b a/x/b a/x/y/bのすべてにマッチ。


== Server ==
後は特に明記がないが、上から順番に評価されて、最後のマッチが優先されるので、記述の順番に注意する。


=== httpd ===
反転の!と/の扱いに特に注意が必要。
Apache HTTP Server


==== Access Control ====
先頭スラッシュをつけないと、再帰的になる。
出典: [https://httpd.apache.org/docs/2.4/en/howto/access.html Access Control - Apache HTTP Server Version 2.4]。
    $ cat .gitignore
    # ディレクトリ foo/bar 以外のすべてを除外
    /*
    !/foo
    /foo/*
    !/foo/bar


DoS攻撃対策などで重要な設定。
====== 空ディレクトリーの維持 ======
[https://stackoverflow.com/questions/115983/how-do-i-add-an-empty-directory-to-a-git-repository How do I add an empty directory to a Git repository? - Stack Overflow]


mod_authz_core/mod_authz_hostがコアモジュール。mod_rewriteも関係ある。
gitは空ディレクトリーを履歴管理できない。何かファイルが必要。


基本構文は以下。
logなど維持したい空ディレクトリーに、以下の内容の.gitignoreを置く。
  Require host <address>
  !.gitignore
Require ip <ip address>
.gitignore以外を無視する。これで.gitignoreのみがあるので管理できる。
1番目の形式はドメイン名。2番目はIPアドレス。部分マッチする。マッチしたもののアクセスを許可する。


Requireの直後にnotを指定してアクセス禁止にできる。こちらが重要。
====== 指定ファイルのみ除外 ======
*
!.gitignore
ディレクトリーを残す以外 (.gitignore1ファイル以外) に、サンプルファイルなど複数ファイルを残したい場合は、上記のように*で最初に全部除外して指定ファイルのみ含める。/は必要に応じてつける。


=== E-mail ===
===== gitattributes =====
[[https://www.itti.jp/web-direction/spam-blacklist-release/ サーバーIPがブラックリストに載ってメール送信エラーになるのを解除する方法]]
[https://git-scm.com/docs/gitattributes Git - gitattributes Documentation]


MailHog: Go言語製のメールサーバーソフト。
gitignoreに似ていて、パターンにマッチしたパスに対する設定を行える。


=== Debian ===
* text
* eol
* working-tree-encoding
* ident
* filter
* diff
* merge
* conflict-marker-size
* whitespace
* export-ignore: git archiveなどに含めないことをマーク。
* export-subst
* delta
* encoding


==== PHP8 ====
===== ファイルのインデックスのみ削除 =====
[How To Install PHP 8.0 on Debian 11/10/9 | ComputingForGeeks](<nowiki>https://computingforgeeks.com/how-to-install-php-on-debian-linux/</nowiki>)
git rmは単独だと、gitの履歴とローカルファイルからも削除する。追跡対象から削除のみで、ローカルファイルとして残したい場合、--cachedを指定する。
git rm --cached


Debian 11の場合、PHP 8には外部リポジトリーが必要なので追加する。
==== gitk ====


sudo apt update
===== problem =====
ブランチ名が長いと、右クリックしにくい


sudo apt install -y lsb-release ca-certificates apt-transport-https software-properties-common gnupg2
==== Other ====


PHPパッケージを追加する。
===== 他のブランチとの同一化 =====
git diff HEAD master | patch -p 1
patchの他にgit applyでもいい。


echo "deb <nowiki>https://packages.sury.org/php/</nowiki> $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/sury-php.list
===== .netrc =====
https://social.senooken.jp/conversation/1573147#notice-2217499


wget -qO - <nowiki>https://packages.sury.org/php/apt.gpg</nowiki> | sudo apt-key add -
Gitのパスワード入力の省略方法に~/.netrcがある。


sudo apt update
しかし、man netrcするとわかるけど、これはもともとFTPのためのもの。なぜGitで使えるんだ?Gitの文書で言及がない。


これでPHP8を参照できるので、インストールする。
In conversation Thursday, 21-Feb-2019 10:58:47 JST from web permalink


sudo apt install php8.2
せのお (妹尾 賢)せのお (妹尾 賢) in reply to


[How to Switch between Multiple PHP Version on Debian 12/11/10 – TecAdmin](<nowiki>https://tecadmin.net/switch-between-multiple-php-version-on-debian/</nowiki>)
理由が分かった。


インストールしたら、PHPのバージョンを切り替える。
1. Gitはhttpとhttpsの通信にcURLを使っている。


a2dismod php7.4
<nowiki>https://github.com/git/git/blob/master/INSTALL#L141</nowiki>


a2enmod php8.2
2. cURLが.netrcにも対応しているから。


sudo systemctl restart apache2
<nowiki>https://ec.haxx.se/usingcurl-netrc.html</nowiki>


php 8.2にするとこういうエラー。
=== GitHub ===


[Sat Sep 02 11:31:02.558029 2023] [php:error] [pid 25644] [client 133.106.38.37:57181] PHP Fatal error:  Uncaught Error: Undefined constant "DB_DATAOBJECT_ERROR_NODATA" in /var/www/gnusocial/public/index.php:104\nStack trace:\n#0 [internal function]: handleError()\n#1 {main}\n  thrown in /var/www/gnusocial/public/index.php on line 104
==== Account ====
Username may only contain alphanumeric characters or single hyphens, and cannot begin or end with a hyphen.
ユーザー名は、英数字と-のみが使用可能。


念のためdockerで起動を試みましたが、同じくトップ画面を開くと同じエラーになります。
組織別にアカウントを分けるなら、かぶらないように末尾に-組織名のようなサフィックスがあるとよいだろう。


<<nowiki>https://notabug.org/gnusocialjp/gnusocial/src/main/docker/development</nowiki>> にDockerでの起動方法があります。`docker compose up -d` を実行するだけでlocalhostでアクセスできます。
=== Fossil ===
* [https://gigazine.net/news/20231231-why-sqlite-does-not-use-git/ SQLiteがバージョン管理システムとしてGitを採用しない理由 - GIGAZINE]
* [https://gigazine.net/news/20201229-fossil/ GitとGitHubの機能をひとつのバイナリに詰め込んだ「Fossil」レビュー - GIGAZINE]
 
外部依存を排除しており、CGIでも動作するという点が非常に良い。気になる。Phorgeの検討が不要になる。


私とあなたとの環境の違いを排除したいので、dockerのインストールだけ頑張って、それでdockerでも簡単に動作確認してくれませんか?
=== Phorge ===
[https://we.phorge.it/ Home]


==== alternative ====
PhorgeはPhabricatorのフォーク。
Ref: [https://wiki.debian.org/DebianAlternatives DebianAlternatives - Debian Wiki].


OS内でバージョン違いのプログラムを管理するための仕組みがある。それがupdate-alternativesコマンド。<syntaxhighlight lang="sh">
==== About ====
sudo update-alternatives --display vi
sudo update-alternatives --config vi
</syntaxhighlight>オプションとコマンド名を指定することで、現在の実体と更新ができる。


=== XAMPP ===
===== Introduction =====
[https://we.phorge.it/book/phorge/article/introduction/ ◉ Introduction]


==== ポート番号変更 ====
以下が主な機能。
[https://qiita.com/neneta0921/items/3c2f9ac8ea9b5bcfc6e6 Xamppでポート競合を防ぐ方法 #PHP - Qiita]


XAMPP Control PanelのConfigから変更可能。
* コードレビューツール=Differential
* リポジトリーブラウザー=Diffusion
* バグトラッカー=Maniphest
* ウィキ=Phiriction


phpmyadminはConfigのphpmyadminで、Servers.portを追加する。
GitHubの自己ホスト。


=== cron ===
===== Phabricator =====
[[wikipedia:Phabricator|Phabricator - Wikipedia]]


==== About ====
PhabricatorはもともとFacebook社内のBTSシステム。PHP製。2021-06-01に開発終了。
[https://ja.wikipedia.org/wiki/Cron cron - Wikipedia]


UNIX系OSのジョブ管理ツール。タスクの定期実行を可能にする。
主なユーザー。


cronの名前は時間を意味するギリシア語chronosに由来する。
* AngularJS
* Discord
* Facebook


指定した時間に1回だけ実行するなら、atがある。電子メールの送信などで役立つ。
==== Install ====
[https://we.phorge.it/book/phorge/article/installation_guide/ ◉ Installation Guide]


==== Format ====
[https://ipv6.rs/tutorial/Ubuntu_Server_Latest/Phorge/ Self Host with IPv6rs - IPv6 Provider - How to Install Phorge on Ubuntu Server Latest]
cronの動作はcrontab (cron table) ファイルで指定する。


以下の形式になっている。
===== Requirement =====
# ┌───────────── 分(0〜59)
LAMP環境で動作する。
# │ ┌───────────── 時(0〜23)
# │ │ ┌───────────── 日(1〜31)
# │ │ │ ┌───────────── 月(1〜12)JAN-DEC
# │ │ │ │ ┌───────────── 曜日(0〜6〈日〜土〉、一部のシステムでは7も日曜日) SUN-SAT
# │ │ │ │ │
# │ │ │ │ │
# * * * * * [予約するコマンド]
日時部分はいくつか指定方法がある。


* *: すべて。
共用ホストでも動作するが、一部機能しない。通常コンピューターを推奨している。
* */n: nごとに実行 (*/5)。
* ,: 複数の時間間隔を指定 (1,2,3)
* -: 範囲。
* %: コマンド内の%はエスケープされていないと改行文字に変換され、標準入力としてコマンドに渡される。


ユーザーはcrontab -eで自分の設定ファイルを編集できる。crontabファイルの直接編集は非推奨で、crontabコマンドでの修正が推奨されている。
* MySQL: 5.5以上。
* PHP 7.2以上
* git: 2.5.0以上。
* PHP extension: mbstring, iconv, mysql (or mysqli), curl, pcntl


==== Command ====
ドメインはサブディレクトリーはだめで、サブドメインじゃないとダメ。


* 編集: crontab -e
===== Download =====
* 表示: crontab -l
以下のコマンドで取得する。
* 削除: crontab -r
$ cd somewhere/ # pick some install directory
somewhere/ $ git clone <nowiki>https://we.phorge.it/source/arcanist.git</nowiki>
somewhere/ $ git clone <nowiki>https://we.phorge.it/source/phorge.git</nowiki>
gitの設定。
$ sudo git config --system --add safe.directory somewhere/arcanist
$ sudo git config --system --add safe.directory somewhere/phorge
phorge用のDBを作っておく。
cp /var/www/html/phorge/phabricator/conf/local/local.json.example /var/www/html/phorge/phabricator/conf/local/local.json


-u: 実行ユーザー指定。
"mysql.host": "localhost", "mysql.user": "phorge", "mysql.pass": "password", "mysql.port": 3306, "mysql.charset": "utf8", "mysql.database": "phorgedb"
後は開くだけ。


==== Log ====
===== Config =====
/var/log/cron
[https://we.phorge.it/book/phorge/article/configuration_guide/ ◉ Configuration Guide]


[https://askubuntu.com/questions/85558/verify-if-crontab-works cron - Verify if crontab works - Ask Ubuntu]
以下のコマンドでユーザーを認識させる。
phorge/ $ ./bin/storage upgrade --user <user> --password <password>


デーモン自体の確認は以下。
==== Diffusion ====
systemctl status cron
systemctl restart cron


== Visual Studio Code ==
===== Hosting =====
[https://we.phorge.it/book/phorge/article/diffusion_hosting/ ◉ Diffusion User Guide: Repository Hosting]


=== Keybind ===
== Shell ==


==== 矩形選択 ====
=== Shell Command Language ===
Ref: [https://mitomito.hatenablog.jp/entry/2021/01/27/073000#:~:text=VS%20Code%E3%81%AE%E7%9F%A9%E5%BD%A2%E9%81%B8%E6%8A%9E%E3%81%A8%E7%9F%A9%E5%BD%A2%E8%B2%BC%E4%BB%98%E3%81%AE%E6%93%8D%E4%BD%9C%E6%96%B9%E6%B3%95%201%20%E3%83%9E%E3%82%A6%E3%82%B9%E3%81%A7%E6%93%8D%E4%BD%9C%E3%81%99%E3%82%8B%E5%A0%B4%E5%90%88%20shift%20%2B%20alt%20%2B,shift%20%2B%20alt%20%2B%20%E7%9F%A2%E5%8D%B0%E3%81%A7%E4%BB%BB%E6%84%8F%E3%81%AE%E7%AF%84%E5%9B%B2%E3%82%92%E9%81%B8%E6%8A%9E%E3%81%97%E3%80%81%20%28or%20%E5%88%87%E3%82%8A%E5%8F%96%E3%82%8A%29%E3%81%99%E3%82%8B%20 VS Codeの矩形選択と矩形貼付の操作方法 - mito’s blog].


* s-alt-クリック
==== Compound Commands ====
* c-s-alt-矢印
[https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/utilities/V3_chap02.html#tag_18_09_04 Shell Command Language]
ジャンプ


* 括弧ジャンプ: C-S-\
===== Case Conditional Construct =====
case word in
    [(]pattern1) compound-list;;
    [[(]pattern[ | pattern] ... ) compound-list;;] ...
    [[(]pattern[ | pattern] ... ) compound-list]
esac


=== Config ===
* 未マッチで終了ステータス0。
* pattern部分: シェル展開が有効。他はglob。
* |でOR検索相当。
* 最後のパターンの;;は省略可能。if文のようにも使える。
* 全パターンの捕捉は最後に*。空でもマッチする。?は最低1文字必要。


==== Default terminal ====
BREでは未対応な|のORマッチに対応しているのが最大の特徴。文法なのでコマンドを実行せず早い。grepを使わずにできるだけこちらを使ったほうがいい。
Ref: [https://stackoverflow.com/questions/44435697/change-the-default-terminal-in-visual-studio-code bash - Change the default terminal in Visual Studio Code - Stack Overflow].


[F1]-[Terminal: Select Default Profile]
=== ワイルドカード ===
ワイルドカードで.始まりのファイルをマッチさせたい。


=== cscope ===
以下ならマッチするが、ブレース展開 (brace expansion) はPOSIX shでは使えなかった気がする。
cscope用のプラグインが何個かある。
echo {.*,*}


* [https://marketplace.visualstudio.com/items?itemName=xulion.codescope scope4code - Visual Studio Marketplace]
=== BOM ===
* [https://marketplace.visualstudio.com/items?itemName=SeungukShin.cscope-code cscope-code - Visual Studio Marketplace]
[https://stackoverflow.com/questions/3127436/adding-bom-to-utf-8-files unicode - Adding BOM to UTF-8 files - Stack Overflow]


scope4codeのほうがいろいろできそうだが、うまく動作しなかった。使い方がよくわからない。
ExcelでUTF-8ファイルを開けるように、UTF-8のBOMをファイルにつけたい。
printf '\xEF\xBB\xBF' > with_bom.txt
上記コードでBOMを最初に書き込んで、後は追記する。


cscope-codeはシンプルだが動作した。こちらを当分使うことにする。
=== awk ===
[https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/ The Open Group Base Specifications Issue 7]


Macの場合、control-. sのように、control-.の後に、controlを話してsを押すと発動する。カーソル下のシンボルしか使えない感じなのがネック。まあいい。
==== 変数 ====


=== Vim ===
===== 特別 =====
* NF: 列数。列の全表示などで使う基本的で重要な変数。
* NR: 行番号。


* [https://marketplace.visualstudio.com/items?itemName=vscodevim.vim Vim - Visual Studio Marketplace]
===== スコープ =====
[http://www.fukano.jp/study_of_awk/basic/basic08.htm 変数のスコープ]


VSCodedでVimのキー操作を使うためのプラグイン。これが一番人気。いや、Vimのエミューレーターは中途半端な感じだから使わないほうがいいかな。
関数の仮引数のみ、ローカル変数扱いで、それ以外はグローバル変数。


=== Extension ===
==== 文/statement ====
CSS


Tailwind CSS IntelliSense
* actions
** if/else
** while/do...while/for
** break/continue
** delete
** next
** exit
* output
** print
** printf


==== PHP ====
==== 関数 ====
Laravel Blade Snippets


===== PHP Intelephense =====
===== 組込関数 =====
Ref: [https://marketplace.visualstudio.com/items?itemName=bmewburn.vscode-intelephense-client PHP Intelephense - Visual Studio Marketplace].


VSCodeのPHPの補完拡張として人気が高い。
* Arithmetic
 
** atan2
====== Quick Start ======
** cos
設置後、しておくべき設定がある。
** sin
 
** exp
* Go to <code>Extensions</code>.
** log
* Search for <code>@builtin php</code>
** sqrt
* Disable <code>PHP Language Features</code>. Leave <code>PHP Language Basics</code> enabled for syntax highlighting.
** int
 
** rand
VSCodeの [PHP Language Features] を無効にしておくとのこと。
** srand
 
* String
後は、.php以外の拡張子でPHPファイルがあれば、関連付けを追加するとか。
** gsub
** index
** length
** match
** split
** sprintf
** sub
** substr
** tolower
** toupper
* I/O
** close
** getline
** system


====== Module ======
print/printfは関数ではなく、statement/文扱い。
peclなどPHPの標準モジュールで一部認識できないものがある。


「[https://stackoverflow.com/questions/62258598/undefined-type-imagick-in-vscodes-intelephense php - Undefined type 'Imagick' in VSCode's intelephense - Stack Overflow]」にあるように、そういう場合は [Settings]-[Stubs] で追加するとよい。
==== ヘッダー出力、列別最大長さ出力。 ====
<nowiki>awk -F, '{if(NR==1) print $0} {for(i=1; i<=NF; ++i){if (line[i] < length($i)) line[i] = length($i)}} END {for (i=1; i<=NF; ++i) {printf line[i]","}}' data/101542.csv</nowiki>


====== Coding ======
==== CSV ====
Ref: [https://beyondjapan.com/blog/2020/02/intelephense-vscode-php/ VSCode で PHP 開発するならインテリセンス最強の intelephense を使おう | 株式会社ビヨンド].
[https://qiita.com/ko1nksm/items/19407c1c53cbbc50569a シェルスクリプトの実験のために作った POSIX 準拠 awk 実装の CSVパーサー (RFC4180対応) #ShellScript - Qiita]<syntaxhighlight lang="awk" line="1">
# csvparser.awk


intelephenseでコード補完を認識しやすい書き方というのがある。
## Usage
# awk -f csvparser.awk data.csv


まず、型をつけられるものはつける。<syntaxhighlight lang="php">
# CSV の論理的な一行毎に呼び出されるコールバック関数(サンプル)
function superMethod()
# row: 行番号(最初の行は1) len: フィールド数 fields: フィールドデータ
{
function callback(row, len, fields,  col, field) {
    /** @var AwesomeService $awesomeService */
    for ( col = 1; col <= len; col++ ) {
    $awesomeService = $this->app->make(AwesomeService::class);
        field = fields[col]
     $awesomeService->awesomeMethod();
        gsub(/\\/, "&&", field)  # \ は \\ にエスケープする
        gsub(/\n/, "\\n", field) # 改行は \n にエスケープする
        print row ":" col " " field
     }
}
}
</syntaxhighlight>ローカル変数も型名を指定する。これをしないと、インスタンスでコード補完が効かない。


== Project ==
BEGIN { row = max_idx = 0 }
 
{
* [https://gigazine.net/news/20240217-open-source-non-code-contribution/ オープンソースの開発プロジェクトではコーディング以外のドキュメント化やサポートなどの貢献が特に重要 - GIGAZINE]
    idx = 0
* [https://gigazine.net/news/20240229-open-source-project-business/ オープンソースプロジェクトを有料化して月収100万円の事業家に転身したソフトウェア開発者 - GIGAZINE]
    sub(/\r$/, "")
 
    while ($0 != "") {
== DB ==
        if (match($0, /^(["]([^"]|["]["])*["]|[^,"]*)(,|$)/)) {
 
            fields[++idx] = ""
=== Other ===
        } else if (match($0, /^["]/)) {
 
            fields[++idx] = substr($0, 2)
===== 画像データのパス/BLOBでの格納 =====
            for (;;) {
 
                if (getline == 0) exit 1
* [https://stackoverflow.com/questions/1347461/saving-images-files-or-blobs database - Saving images: files or blobs? - Stack Overflow]
                sub(/\r$/, "")
* [https://stackoverflow.com/questions/3748/storing-images-in-db-yea-or-nay database - Storing Images in DB - Yea or Nay? - Stack Overflow]
                if (match($0, /^([^"]|["]["])*["](,|$)/)) break
* [https://www.microsoft.com/en-us/research/publication/to-blob-or-not-to-blob-large-object-storage-in-a-database-or-a-filesystem/ To BLOB or Not To BLOB: Large Object Storage in a Database or a Filesystem - Microsoft Research]
                gsub(/["]["]/, "\"")
* [https://teratail.com/questions/296506 データベースに画像を保存するメリット・デメリットと必要性について]
                fields[idx] = fields[idx] "\n" $0
* [https://teratail.com/questions/81233 データベースに画像を保存するのはありでしょうか?]
            }
 
            fields[idx] = fields[idx] "\n"
画像のファイルサイズが1MB以下の場合は問題ない。が、それ以外だと問題があるので、ファイルパスで扱うのがいいらしい。
        } else {
 
            exit 1
==== カラム順序 ====
        }
テーブルのカラム・列の順序。これに意味があるのか?カラムを追加する場合などに影響がある。
        field = substr($0, RSTART, RLENGTH)
 
        $0 = substr($0, RSTART + RLENGTH)
* [https://teratail.com/questions/26532 MySQLでカラムの順番は重要ですか?]
        lastcomma = sub(/,$/, "", field) > 0
* [https://teratail.com/questions/97539 定義するカラムの順番]
        gsub(/^["]|["]$/, "", field) && gsub(/["]["]/, "\"", field)
* [https://qiita.com/Tachy_Pochy/items/7d8d16611adcb5a08cbe テーブルのカラムを増やす際に末尾に追加するのではなく、カラムの並び順を変更したい #考え方 - Qiita]
        fields[idx] = fields[idx] field
* [https://qiita.com/pea1205/items/9caf3f37fc4ce9f401b1 PostgreSQLのカラム順序がテーブルサイズに与える影響 #PostgreSQL - Qiita]
    }
* [https://stackoverflow.com/questions/2111958/does-column-order-matter-in-your-mysql-tables database - Does column order matter in your MySQL tables? - Stack Overflow]
    if (lastcomma) fields[++idx] = ""
* [https://stackoverflow.com/questions/894522/is-there-any-reason-to-worry-about-the-column-order-in-a-table mysql - Is there any reason to worry about the column order in a table? - Stack Overflow]
    while (idx < max_idx) delete fields[max_idx--]
 
    callback(++row, idx, fields)
パフォーマンスに影響がある。特に下2個の情報が参考になる。
    max_idx = idx
 
}
基本的に、頻繁に使用する列 (主キー、外部キー、頻出検索、頻出更新の順) を先頭に配置する。ただし、null許容は全体的に後ろ。null許容の中でも頻度順にする。
 
ディスクスペースの利用率、使用するデータの効率などに影響がある模様。
 
==== NULL ====
Ref: [https://qiita.com/daichi_yamazaki/items/ea3516080948e95bbf26 NOT NULL 制約をつけるべきカラムとは #PostgreSQL - Qiita].
 
絶対に必要な項目にNOT NULL制約をつける。NULLを許容する列は、最後のほうに集めると、ストレージなどの効率がいい。
 
例えば、取得に失敗した場合に、値をどうするのか?などを考えるとよい。


==== int/string ====
</syntaxhighlight>awkのCSVパーサー。先頭のBOMはあると認識できないので、tail -c +4でBOMを除外して使う。
tail -c +4 data/101543.csv | awk -f csvparser.awk


* [https://stackoverflow.com/questions/747802/integer-vs-string-in-database language agnostic - Integer vs String in database - Stack Overflow]
=== Other ===
* [https://teratail.com/questions/259465 データベースの値の持ち方は文字列にするか数字にするか迷っています]


データベースのカラムでIDやコード類を定義する場合、型をintなどの数値系、charなどの文字列系にするかの議論がある。
==== binary ====
[https://qiita.com/ko1nksm/items/dc8f247cdc5b7b58b736 POSIX準拠のシェルスクリプトでバイナリデータを扱う #Bash - Qiita]


* WHEREの範囲、算術計算など数値計算が伴うなら数値。データを何に使うかの意味論が重要。
バイナリーデータの読込はodコマンド。なければhexdump。
* 数値のほうが高速。
* 郵便番号のように先頭が0つく場合、文字列。
* 数値だと、auto incrementで登録時の重複除去を保証できる。
* 値を変更する可能性がないなら数値。
* 文字列型だと文字数の検討が必要。


==== INT/BIGINT ====
書込はprintf。


* [https://qiita.com/tk20211228/items/fbed24e7c97bf10112a0 MySQLにおけるint型IDの限界とクラッシュ回避のための対策 #MySQL - Qiita]
head/tailの-cはPOSIXで使えたか?
* [https://gihyo.jp/article/2022/08/mysql-rcn0178 第178回 MySQLのAUTO_INCREMENTなINTEGERってどのくらいで使い切るの? | gihyo.jp]


int型は4バイトでsignedなら2,147,483,647 (21億) が最大値。1日1万件増加するとして588年。10万件で58年。増加追加量次第だが、中小規模なら通常はint型で問題ない。
== cmd.exe ==


BIGINTなら、1日100万件で25269512429年。BIGINTならほぼ問題ない。
=== Control block ===


ただ、BIGINTはINTの2倍のサイズになるのでストレージも消費する。よく考えておく。
==== for ====
あくまでコマンド。


BIGINTでも足りない場合、プライマリーキーを文字列にして、UUIDやhash値を使う。
===== nest =====


==== マスター ====
* [https://chicagopile1-75.hatenablog.com/entry/2018/05/23/143502 バッチファイルで2重ループ - ハムスターに飼われる院生のブログ]
[https://jsol-datamanagement.com/solution/solution-575/ マスタデータって何?マスタデータについて詳しく解説! - J-MDM/Snowflake]


ユーザー、顧客や拠点の情報など、ベースとなるデータのこと。
* [https://web.archive.org/web/20230602041631/https://jj-blues.com/cms/wantto-useloop/ web.archive.org/web/20230602041631/https://jj-blues.com/cms/wantto-useloop/]


マスターの他に、トランザクションというのもある。これは、売買などシステムや業務の稼働に伴って生じるデータ。
ネストはできない。二重ループしたければ、関数にしてそれを呼び出す。


==== DB ID ====
=== bitsadmin ===
DBのIDの採番規則。非常に重要。全体のパフォーマンスにも影響する。
Windowsでのファイルダウンロードコマンド


[https://zenn.dev/praha/articles/3c84e3818891c3 idをautoincrementして何が悪いの?]
Windows 7以降ではbitsadminコマンドがあり、これがwget相当となる。


[https://instagram-engineering.com/sharding-ids-at-instagram-1cf5a71e5a5c Sharding & IDs at Instagram. With more than 25 photos and 90 likes… | by Instagram Engineering | Instagram Engineering]
書式:
 
bitsadmin /transfer <job name> <URL> <output path>
# <mark>生成されたIDは時間順に並べ替え可能である必要がある</mark>(例えば、写真 ID のリストは、写真に関する詳細情報を取得せずに並べ替えることができます)
<job name><output path>は必須なので注意する。
# ID は理想的には 64 ビットである必要があります (インデックスが小さくなり、Redis などのシステムでより優れたストレージを実現するため)
# システムには、新しい「可動部分」をできるだけ少なく導入する必要があります。私たちが非常に少数のエンジニアで Instagram を拡張できたのは、信頼できるシンプルでわかりやすいソリューションを選択したことが大きな理由です。


Instagramは独自の計算式でIDを算出している。
=== certutil ===
Windowsでのハッシュの確認に使える。
certutil -hashfile file


日時、ユーザーID、自動増分値。
SHA1 ハッシュ (対象 C:\moconavi\windows\Moconavi\ext\chromium\moconavium.exe):
e0da85b04b6970ac1f0c33db7a9ad607fdbd44eb
CertUtil: -hashfile コマンドは正常に完了しました。


この3要素で構成して算出している。これでバッティングせずに時間ソートで64ビットで収まる。よく考えられている。
=== rlogin.cmd ===
コマンドキーの送信を自動化できる?
rem rlogin.cmd
@Echo off
Set SERVER=192.168.0.0
Set USERNAME=
Set PASSWORD=
Cmdkey /generic:TERMSRV/%SERVER% /user:%USERNAME% /pass:%PASSWORD%
Start mstsc /v:%SERVER%
Timeout 5
Cmdkey /delete:TERMSRV/%SERVER%


==== Sharding ====
=== 実行中プロセスのパスの確認 ===
[https://e-words.jp/w/%E3%82%B7%E3%83%A3%E3%83%BC%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0.html シャーディングとは - 意味をわかりやすく - IT用語辞典 e-Words]
出典: [https://superuser.com/questions/768984/show-exe-file-path-of-running-processes-on-the-command-line-in-windows Show EXE file path of running processes on the command-line in Windows - Super User]
wmic process get ProcessID,ExecutablePath
wmic process where "name='mysqld.exe'" get ProcessID, ExecutablePath
wmic process where "name='mysqld.exe'" get ProcessID, ExecutablePath /FORMAT:LIST


シャーディング。DBの負荷分散の手法。
=== 簡易編集モード/挿入モード ===


データをレコード・行単位で水平分割して、複数のデータベースサーバーに分散して記録する。
* [https://softantenna.com/blog/windows-10-command-prompt-no-stop/ 【Tips】Windows 10のコマンドプロンプトが意図せず止まってしまう問題を回避する方法 | ソフトアンテナ]
* [https://superuser.com/questions/419717/windows-command-prompt-freezing-randomly Windows command prompt freezing randomly - Super User]


分散したDBの単位をシャードと呼んでいる。データが増大しても台数を増やせば問題ない。
Windows 10のcmd.exeは [簡易編集モード] が有効になっており、コマンドプロンプトを左クリックすると、テキストの選択が始まる。テキスト選択中はコマンドの実行が止まる。長時間かかるコマンドの実行中に誤操作で止まると困るので、これは無効にしたほうがよい。


ただし、どのデータがどのサーバーで記録しているかを把握する必要がある。ハッシュ値などから計算する。
cmd.exeを起動-左上のアイコンをクリック-[規定値]/[プロパティ]-[オプション]-[□簡易編集モード] を選ぶ。


==== 親子関係 ====
そのほか、 <code>git log</code> のような制御が移るコマンドを実行してしばらくすると、操作できなくなる。
親子関係、ツリー構造、階層構造を表現したいことがある。


[https://teratail.com/questions/281348 1つのテーブルで親子関係を管理する方法]
[□挿入モード] にすると回避できる模様。


基本的に、親コードのカラムをどこかのテーブルに持たせて対応させる。
== Web ==


* 隣接リスト (Adjacency List): 親子関係が再帰的になっている場合、途中データの削除はやっかいになる。親子の取得が少々複雑で何回もSQLが必要になり厄介。階層構造が2-3階程度なら問題ない。
=== URL ===
* 経路列挙:


==== Standard ====
==== クエリー配列 ====
[[wikipedia:ISO/IEC_9075|ISO/IEC 9075 - Wikipedia]]


ISO/IEC 9075がSQLの標準。標準外のSQL/関数は独自実装なので扱いには注意が必要。標準のみの使用が望ましい。
* [https://shinkufencer.hateblo.jp/entry/2019/05/18/163912 クエリストリングで配列を表現をするケースをざっと調べる - コード日進月歩]
* [https://qiita.com/s4kd0R/items/8a11d88099008bb1e9dc PHPでクエリパラメータから配列を受け取る物語 #JavaScript - Qiita]
* [https://www.php.net/http_build_query PHP: http_build_query - Manual]


ANSI SQLと呼んだりするらしい。
やり方がいくつかある。


[[wikipedia:List_of_SQL_reserved_words|List of SQL reserved words - Wikipedia]]
# CSV文字列で受取後分割: <nowiki>https://www.sakdor.net/test/?var=1,2,3</nowiki> explode(",",$_GET[var]);
# 配列添字
## http://www.sakdor.net/test/?var&#x5B;&#x5D;=1&var&#x5B;&#x5D;=2&var&#x5B;&#x5D;=3
## http://www.sakdor.net/test/?var&#x5B;a&#x5D;=1&var&#x5B;b&#x5D;=2&var&#x5B;c&#x5D;=3
## http:www.sakdor.net?var[0]=1&var[1]=2&var[2]=3


ここに標準SQLの予約語一覧がある。
データが決まっているならcsvがシンプル。


=== Naming ===
=== HTTP ===
[https://www.rfc-editor.org/rfc/rfc9110.html RFC 9110: HTTP Semantics]


==== IDとコード ====
==== Content-Disposition ====
[https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Content-Disposition Content-Disposition - HTTP | MDN]


* [https://atmarkit.itmedia.co.jp/bbs/phpBB/viewtopic.php?topic=30818&forum=26 「列名の付け方(~CD or ~ID ?)」(1) Database Expert - @IT]
[https://datatracker.ietf.org/doc/html/rfc6266 RFC 6266 - Use of the Content-Disposition Header Field in the Hypertext Transfer Protocol (HTTP)]
* [https://irof.hateblo.jp/entry/2021/10/26/181920 コード、区分、フラグ、IDと名前。 - 日々常々]
Content-Disposition: inline
Content-Disposition: attachment
Content-Disposition: attachment; filename="filename.jpg"
filenameでファイル名を指定する。ここの値は二重引用符で囲む。スペースを含む場合に必須になる。


コードは広い概念。
==== multipart/form-data ====
rfc7578


IDはコードの内、一意なもの。
* [https://datatracker.ietf.org/doc/html/rfc7578 RFC 7578 - Returning Values from Forms: multipart/form-data]
* [https://qiita.com/sivertigo/items/14957200af5ad953d63b Multipart/form-dataの仕様メモ #HTTP - Qiita]


==== 命名規則 ====
ファイルアップロード用のMIME type。
* [https://webapp.perlzemi.com/blog/20191113074356.html データベースのテーブル名とフィールド名の命名規約 - Perl Webアプリ開発入門]
* [https://www.yiiframework.com/wiki/227/guidelines-for-good-schema-design Guidelines for good schema design | Wiki | Yii PHP Framework]


DBスキーマの命名規則はあまりない。Yiiの規約がけっこうしっかりしている。
リクエストヘッダー
 
Content-Type: multipart/form-data; boundary=--hogehoge
* 複数形ではなく単数形でデータベースのテーブルに名前を付ける
リクエストボディー
* フィールド名の前にDBテーブル名を追加しない
--hogehoge
* モデルクラス名にテーブルプレフィックスを含めない
Content-Disposition: form-data; name="user_name"
* テーブルのID列に「id」という名前を付けます
Content-Type: text/plain
* 意味のある主キー名を避ける
* データベーススキーマで外部キーの関係を定義する
test
* 「id」で終わる外部キーフィールドに名前を付ける
--hogehoge
* 単数形/複数形の性質を反映する名前関係を行う
Content-Disposition: form-data; name="email"
 
==== Convention ====
sample@mail.com
Ref: [https://style.potepan.com/articles/26931.html SQLで大文字・小文字のルールはある?区別・変換方法も一緒に教えます! | ポテパンスタイル].
--hogehoge
Content-Disposition: form-data; name="gender"
male
--hogehoge
Content-Disposition: form-data; name="user_profile" filename="image.jpeg"
Content-Type: image/jpeg
\xff\xd8\....
--hogehoge--
ヘッダーでmultipart/form-dataを明記して、ボディーでデータを指定する。


予約語以外、基本的に全部小文字で、複数単語はハイフン区切りにしたほうがいいらしい。
[https://weblabo.oscasierra.net/curl-post/ curlコマンドでPOSTする, 様々な形式別メモ |]


==== enum/string ====
curlでの送信理由。


* [https://zenn.dev/tonbi_attack/articles/fb796ac3cf9720 DBで区分値などのCODEは数値ではなく文字列を利用するべき]
-Fで送信データをname=data形式で指定する。ファイルの内容を指定する場合、@filenameで指定する。これを指定すると、リクエストボディーのfilename扱いにしてくれる模様。-Fを指定すると、-H 'Content-Type: multipart/form-data'が自動付与される。たぶん、-dと同様に-X POSTもつく。
* [https://teratail.com/questions/154006 区分値は数値にすべきか意味のある文字列にすべきか]
curl -X POST -F file1=@/var/tmp/sample.jpg <nowiki>https://xxxxx.net/xxxxxx</nowiki>
 
データとテキストを同時送信したい場合、-Fで複数指定する。
区分系データを数字で持つか、文字列で持つか。
curl -X POST -F 'age=30' -F file1=@/var/tmp/sample.jpg <nowiki>https://xxxxx.net/xxxxxx</nowiki>
curlだと上記のboundaryなどをうまくやってくれるのだと思う。


文字列だとわかりやすい。数字で持つと、意味の把握にカラム定義など、別の資料を確認する必要がある。アプリ側で表示に毎回そのマップや変換が必要になる。
リクエストボディー全体をファイルデータにする場合。
curl -X POST -H 'Content-Type: image/jpeg' --data-binary @/var/tmp/sample.jpg <nowiki>https://xxxxx.net/xxxxxx</nowiki>


数値で必要ならマスターの主キーにする。基本は文字列でいいと思う。
=== IP address ===
出典: [https://glocalnet.jp/vpn/topix/archives/67#:~:text=%EF%BC%94%EF%BC%8E%E5%9B%BA%E5%AE%9AIP%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E3%81%AE%E5%8F%96%E5%BE%97%E6%96%B9%E6%B3%95%20%E5%8F%96%E5%BE%97%E6%96%B9%E6%B3%95%E3%81%AF%E4%B8%BB%E3%81%AB3%E3%81%A4%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82,%E3%83%BB%E5%A5%91%E7%B4%84%E3%81%97%E3%81%A6%E3%81%84%E3%82%8B%E3%83%97%E3%83%AD%E3%83%90%E3%82%A4%E3%83%80%E3%81%A7%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%A8%E3%81%97%E3%81%A6%E7%94%B3%E3%81%97%E8%BE%BC%E3%82%80%E6%96%B9%E6%B3%95%20%E3%83%BB%E5%9B%BA%E5%AE%9AIP%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E3%81%AB%E5%AF%BE%E5%BF%9C%E3%81%97%E3%81%A6%E3%81%84%E3%82%8BSIM%E3%82%92%E5%A5%91%E7%B4%84%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95%20%E3%83%BBVPN%E3%82%92%E5%88%A9%E7%94%A8%E3%81%97%E3%81%9F%E5%9B%BA%E5%AE%9AIP%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E3%81%AE%E6%8F%90%E4%BE%9B%E4%BC%9A%E7%A4%BE%E3%82%92%E5%88%A9%E7%94%A8%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95 固定IPアドレスの取得方法 ~実は簡単!フリーランスの方も必見です~|VPN活用日記|トピックス|グローカルネットの快適VPN【公式】| 株式会社グローカルネット]。


=== SQL ===
自宅サーバーを行う際、固定IPアドレスが必要になる。


==== JOIN ====
取得方法がいくつかある。
[https://products.sint.co.jp/topsic/blog/sql-bootcamp-07 SQLのテーブル結合(JOIN, UNION, NATURAL)を覚えよう!基本構文と使用例を解説]


外部テーブルと外部キーで結合の方法がいくつかある。
* 契約しているプロバイダでオプションとして申し込む方法
* 固定IPアドレスに対応しているSIMを契約する方法
* '''VPNを利用した固定IPアドレスの提供会社を利用する方法'''


* INNER JOIN: AND。両方のテーブルにある項目のみ。
VPNの固定IPアドレスが安いらしい。ryoかsuwakoが解説していた気がする。
** SELECT ... FROM ... INNER JOIN テーブル名 ON 項目A = 項目B
* OUTER JOIN: OR。片方がなくても。
* CROSS JOIN: 全組み合わせ。
* NATURAL: 同名項目を取得。
* UNION/UNION ALL: 2以上のSELECT結果の結合。
他にWHEREで結合する方法がある。


結合すると、同名カラムは上書きされる。必要なら、select column as column_nameで別名をつける。
=== Authentication ===
認証方式がいくつかある。HTTPで定義される認証方式 (HTTP認証) が有名。


結合する場合、同じ値だから通常は問題ない。
==== Basic認証 ====
出典: [https://ja.wikipedia.org/wiki/Basic%E8%AA%8D%E8%A8%BC Basic認証 - Wikipedia]。


[https://zenn.dev/kasamifutoshi/scraps/8c8cf445f50445 【Laravel】目的別クエリビルダの記述方法まとめ(記事を書く前の整理用)]
Authorization HTTPヘッダーにBasicのあとに [username:password] をBASE64でエンコードして送信する認証方式。
GET /private/index.html HTTP/1.1
Host: example.com
Authorization: Basic cm9vdDpwYXNzd29yZA{{=}}{{=}}
盗聴や改ざんが簡単だが、シンプルという利点がある。


addSelectで列名を地道に追加する。これが確実。
==== OAuth ====
Ref


[https://rimane.net/inner-join-1037/ 結合したテーブルに同じ名前のカラムがあっても正しく取り出す方法【MySQL+PHP】 - りまねどっとねっと]
* [https://ja.wikipedia.org/wiki/OAuth OAuth - Wikipedia]


GroupConcatで文字列で結合する。
OAuth (オーオース) 権限の認可のための標準。OAuth 2.0が最新の標準。


[https://stackoverflow.com/questions/329931/sql-select-join-is-it-possible-to-prefix-all-columns-as-prefix SQL select join: is it possible to prefix all columns as 'prefix.*'? - Stack Overflow]
以下が登場人物。


ダミーの空列を追加すれば、処理はしやすい。が、そもそも同じ列名を取得できるのか?
* resource owner: あるサイトのユーザー。
* resource server: あるサイトのユーザーのデータの保有サーバー。
* clent: クライアントアプリ。リソースサーバーのデータを使用したい。
* authorization server: クライアントにサイトへのアクセスを認証するサーバー。アクセストークンを発行して行う。


==== 一括更新 ====
アクセストークンが実質的なパスワードのようなものだが、resource serverのパスワードを直接渡していない点が重要な違い。パスワードを直接渡さないことで、機能別に権限を細かく利用可否を制御できる。
Ref: [https://zenn.dev/rescuenow/articles/5b16ab6c4d9cf9 MySQLで複数行を一括更新するクエリの実装方法].


ELT/FIELDを併用すれば一括更新可能とのこと。
処理の流れ。


==== UPSERT ====
# client->resource owner: Authorization Request。ここでユーザーが手操作でアクセスを承認する。
Ref: [https://resanaplaza.com/2023/01/22/%e3%80%90%e7%b7%8f%e3%81%be%e3%81%a8%e3%82%81%e3%80%91upsert%e3%81%a8%e3%81%af%ef%bc%9fdb%e3%81%94%e3%81%a8%e3%81%ae%e9%81%95%e3%81%84%e3%81%af%ef%bc%9f/ 【総まとめ】UPSERTとは?DBごとの違いは? | 初心者DIYプログラミング入門].
# client<-resource owner: Authorization Grant。
# client->authorization server: Authorization Grant。承認された情報でアクセストークンを要求。
# client<-authorization server: Access Token
# client->resource server: Access Token。アクセストークンでアクセス。
# client<-resource server: Access Token


INSERTするかUPDATEするか、一度SELECTで値の有無を確認してから本来しないといけない。SQLを2回実行必要で、処理が無駄になるので、これを1回で行う。これがUPSERTと呼ばれるもの。ただし、UPSERTというSQLがあるわけではなく、DBごとの独自拡張になる。
Consumer Key/Secret: アプリ識別用のID/PW。


MERGE文が一応あるが、MySQLにはない ([https://stackoverflow.com/questions/42663074/is-merge-statement-available-in-mysql sql - Is merge statement available in MySQL - Stack Overflow])。代わりにINSERT ... ON DUPULICATE KEY UPDATEという文を使う。
Access Token: サイトにアクセスするためのパスワード。


==== NULLを含むLIKE ====
=== API ===
[https://stackoverflow.com/questions/3924400/like-does-not-accept-null-value sql - like '%' does not accept NULL value - Stack Overflow]


[https://qiita.com/umekikazuya/items/61c16a36824c334e31e5 【SQL】NULL値を制御/SQLマスターへの道「COALESCE」 #初心者 - Qiita]
==== 複数レコードの登録 ====
[https://buddypia.com/2021/11/14/%E8%A4%87%E6%95%B0%E3%83%AC%E3%82%B3%E3%83%BC%E3%83%89api%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E8%AA%BF%E3%81%B9%E3%81%A6%E3%81%BF%E3%81%9F%E8%A9%B1/ 複数レコードの登録・更新・削除のREST APIについて調べてみた話(+@ Graph API) - junode | 個人開発ブログ]


LIKEで文字列検索する際、SELECT * FROM DB WHERE <column> LIKE '%%';であいまい検索してもNULLの場合ヒットしない。
既存のAPIは単一リソースの処理しかないことが多い。JavaScriptなどで単一リソースを何回も呼べばいいというのはそうだけど、JavaScriptなしでは動作しない。一括処理用のAPIを作るしかなくないか?
where COALESCE([table].[column],<nowiki>''</nowiki>) like '<parameter>'
IFNULL([table].[column], <nowiki>''</nowiki>) like '%'
COALESCEかISNULLで引数に空文字を指定するとうまくいく模様。


COALESCEが標準なのでこれを使う。
[https://www.yamarkz.com/blog/rest-web-api-practice REST WebAPIのプラクティス | yamarkz.com]


COALESCE (コアリース) は引数のリストから、最初の非NULLを取得する。NULLを含むデータの処理に便利。
delete_bulkなどのような一括処理用のAPIを作るしかない。内部的には単一処理のAPIを作る感じだったとしても。


ISNULL(<value>, <orValue>) はCOALESCEの引数2個版。理由がないならシンプルなISNULLを使うとよい。
==== パラメーター ====
[https://stackoverflow.com/questions/25385559/rest-api-best-practices-args-in-query-string-vs-in-request-body json - REST API Best practices: args in query string vs in request body - Stack Overflow]


同じ名前の関数で、動きが違う。
パラメーターの指定に3種類ある。


「[https://mysql.sql55.com/sql/mysql-isnull-coalesce.php MySQL の ISNULL()・COALESCE() - MySQL の基礎 - MySQL 入門]」MySQLのISNULLは引数1個で、boolを返すだけ。
# リクエストボディー
 
# クエリー
COALESCE() や IFNULL() を使うしかない。
# パス


NULLIF/COALESCEは標準。
パスはIDなどを指定する場合だけわかりやすい。それ以外のオプションはクエリーのほうがいい。


MYSQLのNULLIFは引数1=引数2の場合、trueでNULLを、そうでなければ1個目の引数を返す。IFNULLと逆。
ボディーは、通常サーバーのアップロード・ダウンロードデータとして使われる。クエリーはデータの指定に使う。
<code>NULLIF(引数1, 引数2);</code>
以下の CASE 文と同等です。
<CASE
WHEN 引数1 = 引数2
THEN NULL
ELSE 引数1
END;


==== 日付範囲 ====
この原則に従うとシンプルだろう。


* [https://dbflute.seasar.org/ja/manual/function/genbafit/implfit/datefromto/ 日付範囲の条件指定を定型化(安全に) | DBFlute]
* URIには長さの制限がある。
* [https://zenn.dev/shuhei_takada/articles/d1444e409330ad SQLで日付の範囲指定をしたいときにありがちなミス]
* ボディー
** 引数が非常に多い場合。
** 画像などバイナリーデータ。
** キー・値構造を持たない場合。
* クエリー文字列
** 引数を簡単に確認できる。
** 共通の引数の場合。


注意点がある。
==== 検索機能のGET/POST ====


2024-01-01から2024-01-02としたい場合、いくつか記述方法がある。
* [https://stackoverflow.com/questions/20550514/post-or-get-in-a-search-form .net - POST or GET in a search form? - Stack Overflow]
where PURCHASE_DATETIME >= '2024-01-01' and PURCHASE_DATETIME <= '2024-01-02'


SELECT * FROM users WHERE id BETWEEN 2 AND 4;
検索機能にGETとPOSTのどちらを使うか?という議論がある。
SELECT * FROM users WHERE id >= 2 AND id <= 4;
ただし、上記はまずい。2024-01-02T00:00までしか判定されない。方法がいくつかある。


# DATE関数で日付部分のみ抽出: <code>SELECT * FROM users WHERE DATE(created_at) BETWEEN '2022-01-01' AND '2022-01-02'</code>
データ登録するわけなじゃないのだから、GETがいいんじゃない?
# 1日進めて小なりで抽出:  <code>where PURCHASE_DATETIME >= '2024-01-01' and PURCHASE_DATETIME < '2024-01-03'</code>
# ミリ秒まで指定: <code>DATETIME <= '2010-10-31 23:59:59.999'</code>


3はミリ秒の.999の部分がどこまでいるのか?という問題があるしスマートではない。
POSTだと、JSONをそのまま送れるので、複雑なケースに対応できる。特に、配列の送信が重要。


1-2で対応するのがよい。1がいいか。
GETのほうが検索条件をブックマークにできたり、URLを共有できるので、基本は便利。


==== Echo/SELECTだけでtable作成 ====
==== レート制限対策 ====


* [https://takuya-1st.hatenablog.jp/entry/2017/01/18/133015 SQLでecho/print するための代替方法 - それマグで!]
* [https://pikodon.com/note/php/api-cache/ APIの利用制限対策 | Web開発ノート]
* [https://keirinomikata.zendesk.com/hc/ja/articles/4404549985945-%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E6%95%B0%E3%81%AB%E3%82%88%E3%82%8B%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E5%88%B6%E9%99%90%E3%81%AE%E5%AF%BE%E7%AD%96%E6%96%B9%E6%B3%95 リクエスト数によるアクセス制限の対策方法 – 請求管理ロボ ヘルプ]


* [https://qiita.com/Hiraku/items/aafc3b58d2efa4e97511 SQL SELECT基礎(3) その場で表を作る #SQL - Qiita]
いろいろ方法がある。


SQLでechoのようにリテラル表示したいことがある。
* cronなどでデータをサーバー上 (DBなど) に定期保存して、保存データを表示させる。
select '##  A ' as <nowiki>''</nowiki>;
* 配列を利用して、1回のリクエストでまとめて取得する。
asでカラム名を空にすると、必要なものだけになる。
* インターバルを設ける。
 
* HTTP 429/413を検知して、リトライする。
UNION ALLで複数のselectを結合できる。
SELECT 1 AS a, 2 AS b, 3 AS c, 4 AS d
UNION ALL
SELECT 2,4,6,8
UNION ALL
SELECT 3,6,9,12
これで4x3の表を作れる。


==== 引用符 ====
==== 指数関数的バックオフ ====
[https://qiita.com/Ping/items/d5d8468dadd9c1287f5e DBごとのSQLのクォーテーションを整理したった #MySQL - Qiita]
{| class="wikitable"
!
!'シングル'
!"ダブル"
!<code>`バック`</code>
![大カッコ]
!備考
|-
|MySQL
|[[/dev.mysql.com/doc/refman/5.6/ja/string-literals.html|文字列定数]]
|[[/dev.mysql.com/doc/refman/5.6/ja/string-literals.html|文字列定数]]
|[[/dev.mysql.com/doc/refman/5.6/ja/identifiers.html|引用識別子]]
|(なし)
|引用識別子はUNIX系では大文字小文字を区別[[/qiita.com/Ping/items/d5d8468dadd9c1287f5e#fn1|1]]
|-
|MySQL
([[/dev.mysql.com/doc/refman/5.6/ja/sql-mode.html#sql-mode-full|ANSI_QUOTES モード]])
|文字列定数
|引用識別子
|引用識別子
|(なし)
|
|-
|PostgreSQL
|[[/www.postgresql.jp/document/11/html/sql-syntax-lexical.html#SQL-SYNTAX-STRINGS|文字列定数]]
|[[/www.postgresql.jp/document/11/html/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS|引用識別子]]
|(なし)
|(なし)
|引用識別子では大文字小文字を区別
|-
|Oracle
|[[/dev.mysql.com/doc/refman/5.6/ja/sql-mode.html#sql-mode-full|文字列定数]]
|[[/docs.oracle.com/cd/E96517 01/sqlrf/Database-Object-Names-and-Qualifiers.html#GUID-75337742-67FD-4EC0-985F-741C93D918DA|引用識別子]]
|(なし)
|(なし)
|引用識別子では大文字小文字を区別
|-
|[[/www.sqlite.org/lang keywords.html|SQLite]]
|文字列定数
|引用識別子
|引用識別子
|引用識別子
|
|-
|Microsoft SQL Server
(Transact-SQL)
|文字列定数
|引用識別子
|(なし)
|引用識別子
|QUOTED_IDENTIFIER が ON (既定値) の場合
|}
基本的に、以下と思っておけばいい。


* 一重引用符: 文字列定数
* [https://docs.link.getmoneytree.com/docs/faq-rate-limiting APIレート制限は何か、どのように対処するのか?]
* [[wikipedia:Exponential_backoff|Exponential backoff - Wikipedia]]
* [https://cloud.google.com/memorystore/docs/redis/exponential-backoff?hl=ja 指数バックオフ  |  Memorystore for Redis  |  Google Cloud]
* [https://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/cloud-design-patterns/retry-backoff.html バックオフパターンで再試行 - AWS 規範ガイダンス]リトライ時は以下のアルゴリズムがいいらしい。
wait_interval = base * 2^n +/- jitter


* 二重引用符: 引用識別子
* <code>wait_interval</code> は、API が HTTP 429 で応答した場合に、システムがリクエストを再試行するまでの時間となります。
* <code>base</code> は最初の間隔、つまり最初の再試行までの待ち時間です。この値には3000msを使用することをお勧めします。
* <code>n</code> は、現在の呼び出しの前にリクエストが通らなかった数です。複数のスレッドやプロセスを使用して並行してAPIを呼び出している場合、<code>n</code>の値は現在のスレッド/プロセスにスコープされます。この値は、現在のスレッド/プロセスが、最後に成功した応答から何回 429 "Too Many Requests" エラーに遭遇したかを表します。
* <code>jitter</code> は 0 から <code>base</code> の間の乱数です。これは、複数のスレッド/プロセスが全く同時にAPIを呼び出さないように、リクエストを少しずつ分散させるために使用されます。システムが待機するたびに、この乱数値を再計算し <code>wait_interval</code> の合計に加算するか減算するか、ランダムで選択してください。


引用識別子は、テーブル名、カラム名など、DB中のオブジェクト。
=== curl ===
HTTPの通信のコマンドラインでの確認でよく使う。


=== phpMyAdmin ===
==== Basic ====
[https://curl.se/docs/tutorial.html curl - Tutorial]
* -X: メソッド指定
* -d/--data-urlencode: リクエストボディー (key=value)を指定。-X POSTも自動指定になる。
curl -H "Content-Type: application/json" -d '{"name":"佐藤", "mail":"sato@example.com"}' localhost:5000/api/v1/users
JSONで送信する場合、ヘッダー指定が必須。


==== テーブル定義出力 ====
<nowiki>*</nowiki>-F: multipart/formのform指定。
[https://superuser.com/questions/168595/how-to-export-mysql-schema-from-phpmyadmin database - How to export mysql schema from phpmyadmin? - Super User]
curl -F "coolfiles=@fil1.gif;type=image/gif,fil2.txt,fil3.html"
  <nowiki>http://www.example.com/postit.cgi</nowiki>
@でfilename相当の指定。;でmime typeも指定できる。


[エクスポート]-[詳細]
@/</;type=自体を送信したい場合、-Fではなく、--form-stringを指定する。


* フォーマット=Texy! text
==== curl: (60) SSL certificate problem: self-signed certificate ====
* 出力:◎出力をテキストで表示する
Ref: [https://linuxfan.info/curl-insecure curlで「自己署名証明書」を受け入れるには【curl: (60) SSL certificate problem: self signed certificate】 | LFI].
* フォーマット特有のオプション:ダンプするテーブル=構造


これで出力・表示すると使いやすい。
--insecureオプションを指定すると、localhostなどでの自己署名証明書を許可する。


=== MySQL ===
==== curl: Failed writing body ====
[https://askubuntu.com/questions/1449492/right-after-piping-to-head-tail-curl-23-failure-writing-output-to-desti pipe - Right After piping to "head"/"tail": "curl: (23) Failure writing output to destination" - Ask Ubuntu]


==== SQL ====
以下のようにhead -n 1を指定するとcurlがエラーを出力する。
curl -H "Content-Type: application/json; charset=utf-8" -H "X-HD-apitoken:$TOKEN"        -d "{\"dbSchemaId\":$dbSchemaId, \"limit\":1, \"offset\":$offset}"        <nowiki>https://$DOMAIN/$ACCOUNT/api/csvexport/version/1.0</nowiki> | head -n 1


===== カラム名検索 =====
curl: Failed writing body
[https://qiita.com/dkwnm/items/3aa7be0bca95a2a75304 MySQLで指定されたカラム名を持つテーブルを検索する #MySQL - Qiita]
curlは標準出力に全部書き込めたかチェックしているようで、head -n 1で切り捨てたらcurlはエラーになる。
select table_name, column_name from information_schema.columns where column_name = '検索したいカラム名' and table_schema = '検索対象のデータベース名';


==== Type ====
対策は、curl -sで出力を抑制するとのこと。これで解決。
[https://dev.mysql.com/doc/refman/8.0/ja/data-types.html MySQL :: MySQL 8.0 リファレンスマニュアル :: 11 データ型]


データ型の書式がある。
=== Wireshark ===


* DECIMAL(M [, D]): M=全体の桁数。D=内小数部の桁数。
==== TLS ====
* CHAR(M)/VARCHAR(M): M=格納最大文字数。CHARのM=0-255までで末尾はスペース。VARCHARはM=0-65535までで、可変長文字列で256以上もOK。末尾のスペースは削除される。先頭にプレフィクスの1-2バイトのデータを付与している。255バイト以下の文字列なら1バイト、256バイト以上なら2バイト追加。
Ref: [https://www.toyo.co.jp/onetech_blog/articles/detail/id=36994 SSL/TLSの復号#1 ~Wiresharkの設定~ | 東陽テクニカ | “はかる”技術で未来を創る | ワン・テクノロジーズ・カンパニー].


===== Backup =====
Wiresharkで通信パケットを確認する場合、デフォルトでTLSで暗号化されているので、内容がわからない。WiresharkでTLSに対応しておく必要がある。
mysql -u username -p database_name <file.sql


==== Error ====
[Preferences]-[Protocols]-[TCP] を選ぶ。


===== Error: [PDOException] PDO::__construct(): The server requested authentication method unknown to the client [caching_sha2_password] =====
* ☑Allow subdissector to reassemble TCP stream
* [https://www.petitmonte.com/database/mysql_authentication_plugin.html MySQL8.0以降で接続できない場合は「認証プラグイン」を変更する]
* ☑Reassemble out-of-order semgemnts
* [https://symfoware.blog.fc2.com/blog-entry-2160.html phpからMySQL 8.0へPDOで接続時「SQLSTATE[HY000] [2054] The server requested authentication method unknown to the client」 - Symfoware]
* [https://yoku0825.blogspot.com/2018/01/mysql-804.html 日々の覚書: MySQL 8.0.4におけるデフォルト認証形式の変更]
* [https://qiita.com/ucan-lab/items/b094dbfc12ac1cbee8cb docker-compose MySQL8.0 のDBコンテナを作成する #Docker - Qiita]


MySQL 8.0になってから、認証方式が変わったらしく、そのままだと接続に失敗する。
上記をチェックしておく。デフォルトでチェックされていた。


PHP 7.1.16, 7.2.4 以降から対応しているらしい。それ以前だと設定が必要。
続いて、セッションごとのPre-Master Secretを登録する。


==== Config ====
Chrome/Firefoxだと、環境変数SSLKEYLOGFILEを設定すれば、このファイルにTLSセッションキーを出力するので、これをWiresharkで読み込むことで、復号対応する。


===== Character =====
以下のコマンド相当で、任意のファイル・場所にログファイルを指定する。
[https://qiita.com/tfunato/items/e48ad0a37b8244a788f6 MySQLの文字コードとCollation #MySQL - Qiita]
export SSLKEYLOGFILE=/tmp/sslkey.log
Macだとlaunchctlで設定しておくといい。これでWebブラウザー経由の場合は見えるようになる。


DBで使用する文字セットと、その照合順序を選択できる。
=== Security ===


文字コードはutf8mb4で問題ない。照合順序も基本はutf8mb4_binで問題ないと思う。
==== DoS攻撃 ====
いくつか対策方法がある。


A ≠ a 区別する
* [https://lite.ip2location.com/ip-address-ranges-by-country?lang=ja 国別のIPアドレス範囲]
* [https://rakko.tools/tools/11/ IPアドレスから住所検索:国、地域の特定 | ラッコツールズ🔧]


≠  区別する
サーバーログにIPアドレスが残るから、それで攻撃元の国を特定して、該当国を一括アクセス拒否。これが効果あるかもしれない。


は≠ぱ≠ば 区別する
攻撃元の国は途上国とかが多いだろうから。IPアドレスは簡単に変更できるが、国を変えるのはたいへんだろう。


utf8mb4_general_ciは上2個を区別しない。
==== バリデーションの実装 ====


区別しないとあいまい検索で都合がいいことがある。
* [https://teratail.com/questions/81861 フロント側で入力チェックをしていればサーバー側では入力チェックは必要ない?]
* [https://qiita.com/mi2__user/items/f2f415ccbb0a625c8647 フロントエンドの"バリデーション"は最低限の方がいいらしい。 #TypeScript - Qiita]


ただし、あいまい検索にすると、対象範囲が増えるので、少し遅くなる模様 ([https://yakst.com/ja/posts/5431 CharsetとCollationの設定がMySQLのパフォーマンスに与える影響 | Yakst])。
基本的に、バックエンドで主にチェックして、フロントエンドはUXの向上目的で実装する。データの重複チェックはDBアクセスが必要だったりするから。また、API経由などフロントがそもそもないケースもある。


===== SQL mode =====
ただ、社内システムのような、画面経由でしか使わない。悪者がほぼいないと思われるケースは、フロントエンドでの検証だけでも十分に感じる。
[https://dev.mysql.com/doc/refman/8.0/ja/sql-mode.html#sql-mode-combo MySQL :: MySQL 8.0 リファレンスマニュアル :: 5.1.11 サーバー SQL モード]


SQLの基本的な動きを制御する設定がある。以下で現在値を確認。
==== 二重送信 ====
SELECT @@GLOBAL.sql_mode;
SELECT @@SESSION.sql_mode;
以下で設定。
SET GLOBAL sql_mode = 'modes';
SET SESSION sql_mode = 'modes';
GLOBALは権限が必要。SESSIONは誰でも変更可能。


デフォルト=ONLY_FULL_GROUP_BY, STRICT_TRANS_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO および NO_ENGINE_SUBSTITUTION。
* [https://www.youfit.co.jp/archives/4545 フォームの二重送信を防止する方法 - 福岡・東京のシステム開発会社 (株)ユーフィット]
* [https://qiita.com/syobochim/items/120109315f671918f28d さいきょうの二重サブミット対策 #JavaScript - Qiita]


カンマで区切って複数指定できる。
submitボタンのダブルクリック、リロード、ブラウザーバック・フォワードなど、フォーム周りで注意が必要な保安要素がある。


モードの値としては、ANSIが重要。基本はこれでよい。
# ボタン連打
# ブラウザーバック
# リロード (PRG)


== Office ==
項目ごとにすべき対策が異なる。


=== Font ===
===== 連打 =====
いくつか愛用しているフォントがある。


* [https://moji.or.jp/ipafont/ IPAexフォントおよびIPAフォントについて | 一般社団法人 文字情報技術促進協議会]: 日本語の日本公式フォント。IPAexMincho/IPAexGothic。
* [https://www.youfit.co.jp/archives/4545 フォームの二重送信を防止する方法 - 福岡・東京のシステム開発会社 (株)ユーフィット]
* [https://itouhiro.github.io/mixfont-mplus-ipa/migu/ Miguフォント : M+とIPAの合成フォント]: Miguフォント。Migu 1C/Migu1M。IPAフォントとM+フォントの合成。半濁点の視認性が高かったり、コーディング用フォントとして手堅い。
* [https://qiita.com/syobochim/items/120109315f671918f28d さいきょうの二重サブミット対策 #JavaScript - Qiita]
* [https://codezine.jp/article/detail/769 JavaScriptを利用してフォームの二重送信を防止する|CodeZine(コードジン)]
* [https://blog.nisesagi.com/3150/ JavaScriptでformの2重送信を防止する | にせサギ ネットサギ体験ブログ]
* [https://yutaihara.com/archives/569 Javascriptで送信ボタン二度押しによる二重送信を防止する方法 | Yuta Ihara.com]


日本語と英語でフォントを分けられないソフトがあったりするので、必然的に日本語フォントが優先される。
基本は、ボタンのsubmitのイベント内でdisabled=trueでの無効化。


* 明朝体: IPAexMinch
似た考え方で、スプラッシュのモーダル表示もあり。これがわかりやすいかもしれない。
* ゴシック: Migu 1C
$("form").submit(function() {
* 等幅: Migu 1M
  var self = this;
* スライド: Migu 1C
  $(":submit", self).prop("disabled", true);
  setTimeout(function() {
    $(":submit", self).prop("disabled", false);
  }, 10000);
});
停止にしたら、二度通せなくなるので、タイムアウトで戻すとよい。


以前はスライド用にMigMix 1P/Migu 1Pを使っていた。視認性が高いから。その後、2011-04-18にMigu 1Cとさらに視認性を重視したフォントが生まれた ([https://itouhiro.github.io/mixfont-mplus-ipa/changelog.html 変更履歴 : M+とIPAの合成フォント])。Migu 1Cでいい。
=== Browser ===


=== Excel ===
==== Chromium ====


==== オートシェイプの全選択 ====
===== Extension =====
Ref: [https://aka-aca.com/tips014-shapes-select-01/ シート上の図形(オートシェイプ)を全て選択した状態にするショートカットキー【エクセルTips】]
Chromme系で愛用拡張機能を列挙する。


[C-g]-[セル選択]-[オブジェクト]
* [https://chromewebstore.google.com/detail/create-link/gcmghdmnkfdbncmnmlkkglmnnhagajbm Create Link]:


==== 日付の数値対策 ====
==== devtool/開発者ツール ====
[https://tokusengai.com/_ct/17544077 【Excel】入力した日付が5桁の数字になるのを防ぐ「書式設定」の確認方法 | 特選街web]


[https://pentan.info/else/excel_date_number.html Excelの日付が数字になるときの対処法 - [その他 + その他] ぺんたん info]
===== イベントリスナー =====
[https://yuzu441.hateblo.jp/entry/2016/12/12/120000 要素に設定されているイベントを調べよう - ゆずめも]


日付のデータが5桁の数字になって困ることがある。
[Elements]-[Event Listeners]-[handler]-右クリック-[Show function definition] でイベントリスナー関数の定義を確認できる。


これはセルの書式設定が、[標準] や [数値] になっているから。[日付] に変更すれば解決する。
===== イベント監視 =====
[https://stackoverflow.com/questions/3787555/how-to-find-out-which-javascript-events-fired How to find out which JavaScript events fired? - Stack Overflow]


セル参照、数式の場合は、TEXT関数で表示形式を指定する必要がある。"yyyy-mm-dd"を指定しておくとよいだろう。
monitorEvent関数で監視できるらしい。他に、FirefoxのFirebugのlog eventsでも監視できるらしい。


=== Word ===
==== Other ====


==== キーワード変数 ====
===== Windows Safari =====
[https://mylife8.net/cross-reference-word-bulk-replacement/ 【Word】文書中に何度も登場する文字列を1か所変更するだけで他の箇所も一括で変更する方法 | My Life 8]


例えば契約書などで、同じ氏名や住所が同一文書内に複数回登場することがある。一箇所変更すれば、全体も反映されるようにしたい。
* [https://web.archive.org/web/20220220134447/https://jp.techcrunch.com/2012/07/27/20120725apple-safari-for-windows-ends/ Appleは静かにWindows版Safariの開発から手を引いてしまったのだろうか? | TechCrunch Japan]
* [http://web.archive.org/web/20120728130701/https://support.apple.com/kb/DL1531 Safari 5.1.7 for Windows]


ブックマークと相互参照を利用する。
一応ある。2012-05-09のSafari 5.1.7までWindows版が提供されていた。DL1531。


# まずどこかで後で流用したい文字列を入力しておく (文書の先頭などわかりやすいだろう)。
=== Other ===
# 登録対象文字列を選択して [挿入]-ブックマーク] を選び、わかりやすい名前でブックマークに登録する。
# 以後の登録した文字列を使いたい場所で、[挿入]-[相互参照] で先に登録したブックマークの参照を配置する。
# 文字列を一括置換したい場合、最初に登録したブックマークの文字列を別のものに変更する。


=== LibreOffice Draw ===
==== Tool ====


==== テキストボックスの内部余白 ====
* [https://web-toolbox.dev/ Web ToolBox | 開発者向けのオンラインツール]
[https://ask.libreoffice.org/t/text-box-internal-margins-how-to-set-them/45583 text box internal margins - how to set them - English - Ask LibreOffice]
* [https://tm-webtools.com/ TM - WebTools]


テキストボックスに二重に余白がある。内部余白は、[Format]-[Text Attributes...] から変更可能。
いくつかWeb関係の開発で役立つツール集を公開しているサイトがある。


==== グリッド ====
==== localhost ====
[http://mcap-cr.com/calc/draw/draw03.html LibreOffice Drawの基本]


図形の配置でグリッドとスナップが重要。
* [[wikipedia:Special-use_domain_name|Special-use domain name - Wikipedia]]
* [https://ja.wikipedia.org/wiki/.localhost .localhost - Wikipedia]


グリッドの間隔類は、[Preferences]-[LibreOffice Draw]-[Grid] で設定する。
RFC 6761 で規定。RFC 2606<nowiki/>で予約。DNSに登録されることはないため、テスト目的で使用可能。ループバック (送信元にそのまま返す) インターフェイス。


[Resolution] がグリッド (点) の表示間隔。その横の [Subdivision] はグリッド同士の細分化個数。グリッドをあまり細かくしすぎると、目が疲れる。
IPv4=127.0.0.1/IPv6=::1とされている。


例えば、グリッドを1間隔にして、subdivisionを2にすると、0.5間隔でグリッドの間をスナップできる。
== Shared Host ==


=== LibreOffice Calc ===
=== Free ===
無料で使用可能な共用ホスティングサービスがある。


==== Formula ====
==== スタードメイン無料サーバー ====
ドメインをセットで利用する必要があるものの、スタードメインのスタードメイン無料サーバーがけっこういい。


===== evaluate =====
[https://www.star-domain.jp/service/free_server.php 無料レンタルサーバー | スタードメイン - ドメイン取得 100円(税込)~]


* [https://superuser.com/questions/939363/libreoffice-calc-equivalent-to-excel-evaluate-formula-feature worksheet function - LibreOffice Calc equivalent to Excel "Evaluate Formula" feature - Super User]
jpドメインの金額が相場の中では安い方で、それに無料サーバーがついていくる点。
* [https://ask.libreoffice.org/t/is-it-possible-to-convert-a-text-string-to-a-formula/31277 Is it possible to convert a text string to a formula? - English - Ask LibreOffice]
* [https://ask.libreoffice.org/t/evaluate-math-expressions/104248 Evaluate math expressions - English - Ask LibreOffice]
* [https://forum.openoffice.org/en/forum/viewtopic.php?t=3497 Apache OpenOffice Community Forum - [Solved] Evaluate a string - (View topic)]


セル内のテキストを数式として評価してほしい場面に遭遇した。
* ディスク容量 20GB
* DB 1GB


例えば、画素数 (720x720) の合計。Excelだとevaluateという関数があるが、Calcにはない。マクロなどで頑張る。あるいは、数式ではないがF9で数式に変換できるらしい。
ただし、SSHやコマンドは使えないので、FTPでWordPressを展開して設置するとか、そういう簡単な使い方だけ。ただ、それでもWordPressでWebサイトを構築するくらいなら十分だと思う。


==E-mail==
=== CORESERVER ===


===General===
==== メール ====


====Naming====
* [https://www2.bwt.jp/wiki/?Custom_Filter_of_Coreserver Custom_Filter_of_Coreserver - PukiWiki]
* [https://help.coreserver.jp/manual/v2/spam-filter/ スパムフィルターの設定 | マニュアル | サポート | レンタルサーバー CORESERVER(コアサーバー)]
* [https://help.coreserver.jp/manual/v1/customfilter/ カスタムフィルターの設定 | マニュアル | サポート | レンタルサーバー CORESERVER(コアサーバー)]


=====RFC=====
情報


*webmaster
* [https://www2.bwt.jp/wiki/?CoreServer_Mail_Custom CoreServer_Mail_Custom - PukiWiki]
*support
* [https://bwt.blog.ss-blog.jp/2021-03-28 coreserverのメール設定:BWT Lab.:SSブログ]
*info
* [https://qwerty.work/blog/2017/01/valueserver-spammail-filter-rule.php バリューサーバーのフィルター設定でスパムメール(迷惑メール)対策する方法 - QWERTY.WORK]
*service
* [https://awmt.jp/dekirukana/archives/2253 コアサーバー V1にてカスタムフィルターで「ごみ箱」を指定したときの確認方法 – AWMTの、できるかな?]
*pr
*billing
*氏名


[https://news.mynavi.jp/article/20120315-mailaddress/ 売上をアップするメールアドレス、商機を失うメールアドレス | マイナビニュース]
ルールが特殊なので注意する。


[https://webtan.impress.co.jp/e/2015/03/31/19657 infoやwebmasterなど企業サイトが備えるべきメールボックスのルール、ご存じですか? | 編集長ブログ―安田英久 | Web担当者Forum]
ゴミ箱に振り分ける場合。


[https://rfc-jp.nic.ad.jp/rfc-jp/RFC2142-JP.txt rfc-jp.nic.ad.jp/rfc-jp/RFC2142-JP.txt]
順1 で[<code>./.Trash</code>] を指定


[https://www.tains.tohoku.ac.jp/news/st-news-23/3437.html <nowiki>SuperTAINS News No.23 [Page.5]</nowiki>]
順2


[https://fumidzuki.com/knowledge/109/ 【Mail】メールアドレス作成のガイドライン(RFC2142) – fumidzuki]
* 条件:  [<code>.*</code>]
* 処理:  <code>./</code>、に振り分ける
 
条件部分には正規表現が使えるように見える。
 
破棄にしないといけない。転送する場合、カスタムフィルターの中に転送を入れる。条件を.*にする。
 
カスタムフィルターにくせがある。
 
* エスケープ(\を前置する)が必要な文字は「'」「"」「|」「`」「~」「?」「!」


公開用のメールアドレス。何にしようか考えていた。
==== Value Domain ネットde診断 byGMO ====


<nowiki>RFC 2142</nowiki>でいくつか推奨されている。
* [https://www.value-domain.com/information/detail/?no=20240606-1 弊社レンタルサーバー上で運用中のドメインにおける自動セキュリティ診断開始のお知らせ | お知らせ - バリュードメイン]
* [https://www.value-domain.com/security/net-de-shindan/ Value Domain ネットde診断 byGMO - バリュードメイン]


info@ support@ answer@ inquery@ contact@ pubic@
2024-06-07 Friからバリュードメイン系の利用者に無料で提供しているセキュリティー診断ツール。


contact@がやっぱり一番しっくりくる。info@ support@はRFC 2142にあるけど,これはビジネスより,サービスに紐付いたもの。個人でやる分にはサービス関係ないから,これは違う。publicも悪くはないのだけど,あまり一般的ではないか。
== Analytics ==


=====develop=====
==== Exam ====
<nowiki>##</nowiki> About


<html>
<nowiki>https://gnusocial.jp/notice/4506679</nowiki>
<blockquote style="position: relative; padding-left: 55px;">
                <section><a href="tag:gnusocial.jp,2022-10-08:noticeId=432699:objectType=note">GNU social JP管理人 (gnusocialjp@gnusocial.jp)'s status on Saturday, 08-Oct-2022 23:13:28 JST</a><a href="https://gnusocial.jp/gnusocialjp" title="gnusocialjp@gnusocial.jp"><img src="//gnusocial.jp/avatar/1-48-20220724135646.webp" alt="GNU social JP管理人" style="position: absolute; left: 0; top: 0;" width="48" height="48">GNU social JP管理人</a></section>
                <article>使用するメールアドレスに悩みます。GitのメールアドレスはGitのホスティングサービスに掲載され一般公開されます。<br>
                  <br>
                  メーリングリストのメールアドレスも、返信方法によって引用されアーカイブで一般公開されます。<br>
                  <br>
                  どう使い分けるのがよいでしょうか?案↓</article>
                <footer><a rel="bookmark" href="https://gnusocial.jp/conversation/243494#notice-432699">In conversation</a><time datetime="2022-10-08T23:13:28+09:00" title="Saturday, 08-Oct-2022 23:13:28 JST">about 11 minutes ago</time> <span>from <span>web</span></span><a href="https://gnusocial.jp/notice/432699">permalink</a></footer>
              </blockquote>
<blockquote style="position: relative; padding-left: 55px;">
                <section><a href="tag:gnusocial.jp,2022-10-08:noticeId=432737:objectType=note">GNU social JP管理人 (gnusocialjp@gnusocial.jp)'s status on Saturday, 08-Oct-2022 23:20:04 JST</a><a href="https://gnusocial.jp/gnusocialjp" title="gnusocialjp@gnusocial.jp"><img src="//gnusocial.jp/avatar/1-48-20220724135646.webp" alt="GNU social JP管理人" style="position: absolute; left: 0; top: 0;" width="48" height="48">GNU social JP管理人</a>
                  <div><a href="https://gnusocial.jp/notice/432699" rel="in-reply-to">in reply to</a></div>
                </section>
                <article>
                  <ol>
                    <li>develop@domainのようなアドレスで共有</li>
                    <li>develop@, ml@ で用途別</li>
                    <li>contact@ で一般公開用で共有</li>
                  </ol>
                  開発用のメールなので、1がいいですかね。仮に漏洩しても開発関係経由というのがわかるので。</article>
                <footer><a rel="bookmark" href="https://gnusocial.jp/conversation/243494#notice-432737">In conversation</a><time datetime="2022-10-08T23:20:04+09:00" title="Saturday, 08-Oct-2022 23:20:04 JST">about 5 minutes ago</time> <span>from <span>web</span></span><a href="https://gnusocial.jp/notice/432737">permalink</a></footer>
              </blockquote>
</html>


1がいいと思う。
<nowiki>###</nowiki> 全般


===== category =====
- マーケティング・ビジネス実務検定
目的に応じて使い分けたほうがよさそう。


[https://upa-pc.blogspot.com/2014/06/mail-security.html メールアドレスを何個ぐらい使い分けたら安全・快適に過ごせるのか - Dr.ウーパのコンピュータ備忘録]
- IMA検定


メールアドレス流出時の被害防止
- Web検定


不審なメールの検知
- ネットマーケティング検定


必要な数
<nowiki>###</nowiki> 解析系


* 銀行・証券会社
- ウェブ解析士
* 知り合い
* ショッピングサイト


その他
- GAIQ
 
- 統計検定


* Webサイトなどの公開用
- Webアナリスト検定
* 本名でのやり取り
* ニックネーム
* 金銭のやり取りのないサービス登録
* 金銭のやり取りのあるサービス登録
* 登録にメールアドレスが必要だけど,そんなに使っていないメール


メールアドレスの種類
GAIQが無料だしどうせ使うからいいかな。


* フリーメール
<nowiki>https://wacul-ai.com/blog/access-analysis/google-analytics-method/gaiq/</nowiki>
* プロバイダーメール
* 独自ドメイン


[https://afmasakun01.com/3373.html メールアドレスの種類とアフィリエイトにおける3つの使い分け方法 | アフィリエイト]
<nowiki>https://www.plan-b.co.jp/blog/seo/12792/</nowiki>


* サービス登録用
<nowiki>##</nowiki> URL
* メルマガ購読用(捨てアド)
* メインアドレス


[https://d.hatena.ne.jp/okmount/20080505/1209914528 メールアドレスの使い分けかた(前編) - 学習する機械、学習しない人間]
- <nowiki>https://ceres-inc.jp/business-tips/recommended-webmarketing-shikaku/</nowiki>


[https://d.hatena.ne.jp/okmount/20080506/1210002001 メールアドレスの使い分けかた(後編) - 学習する機械、学習しない人間]
- <nowiki>https://mynavi-creator.jp/blog/article/qualification-for-web-marketer</nowiki>


これらを考えてどういう名前で何個用意するかを考える。
- <nowiki>https://www.icloud.co.jp/article/exam/features-and-5-acquisition-benefits.html</nowiki>


とりあえずメインで使うmainというアドレスを一つ用意する。残りをどうするか。
- <nowiki>https://digitor.jp/textbook/web-analytical-qualification/</nowiki>


Webサイト公開用にcontact
=== Tool ===
サイト分析用のツールがいくつかある ([https://hidesunblog.com/blog-ranking-sites/ 2023年ブログランキング!おすすめブログランキングサイト比較【一般人向け】])。


* main: メインで使うメール。人に直接教えるときや,お金が絡む場合,ショッピングサイトなど実名が求められるような重要な内容にはこれ。こちらから送信するときもこれ。相手の顔が見えているとき。
* SimilarWeb
* contact:受信専用,公開用。問い合わせ用。なんかフォーラムやブログのコメント欄やcontact usなどにこちらから問い合わせる時なども。相手の顔が見えないときなど。
* Ubersuggest
* service: 基本的に受信専用,たまに返信。Webサービス登録用。
* ahrefs
* recruit:就職活動用。就職サイトとか転職エージェント,企業とやりとりするときはけっこうメール来るから。
* Googleキーワードプランナー
 
=== 閲覧数取得 ===
出典: [https://affiliate-jpn.com/archives/5595 GoogleAnalyticsで自サイトの人気記事ランキングを表示する方法 | アフィリエイトJAPAN]。
 
* [行動]-[サイトコンテンツ]-[全てのページ]
* [表示する行数]=5000
* [エクスポート]=TSV
 
=== 流入元特定 ===
「[https://support.google.com/analytics/thread/252885536/%E4%BC%9A%E5%93%A1%E7%99%BB%E9%8C%B2%E7%94%BB%E9%9D%A2%E3%81%AE%E6%B5%81%E5%85%A5%E5%85%83%E6%8E%A2%E7%B4%A2%E6%96%B9%E6%B3%95%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6?hl=ja 会員登録画面の流入元探索方法について - Google アナリティクス コミュニティ]」どのページから会員登録があったか、会員登録に結びつく記事は非常に重要。<blockquote>こんにちは。
 
探索レポートでユーザーセグメントを作成する集計方法はいかがでしょうか。
 
・自由形式レポートを作成
 
・セグメント作成 > ユーザーセグメント
 
・条件は page_view > パラメータ page_location > 含む:会員登録画面のURL を指定
 
・「会員登録画面閲覧ユーザー」などセグメント名をセットして保存
 
・探索レポートにセグメントを適用
 
・ディメンション:セッションの参照元 / メディア、ランディング ページ + クエリ文字列
 
・指標:セッション
 
ご確認よろしくお願いいたします。
 
※ページ閲覧の発生しなかったセッションはランディングページが (not set)になります。
 
 開きっぱなしのタブから再訪問するセッションなどが該当します。ご参考までに。</blockquote>PMProでも似たような回答。<blockquote>Google Analytics 4 can track ecommerce conversions and then assign page value to posts that were a part of their conversion path for that engaged session. </blockquote>
 
== Server ==
 
=== httpd ===
Apache HTTP Server
 
==== Access Control ====
出典: [https://httpd.apache.org/docs/2.4/en/howto/access.html Access Control - Apache HTTP Server Version 2.4]。
 
DoS攻撃対策などで重要な設定。
 
mod_authz_core/mod_authz_hostがコアモジュール。mod_rewriteも関係ある。
 
基本構文は以下。
Require host <address>
Require ip <ip address>
1番目の形式はドメイン名。2番目はIPアドレス。部分マッチする。マッチしたもののアクセスを許可する。
 
Requireの直後にnotを指定してアクセス禁止にできる。こちらが重要。
 
=== E-mail ===
[[https://www.itti.jp/web-direction/spam-blacklist-release/ サーバーIPがブラックリストに載ってメール送信エラーになるのを解除する方法]]
 
MailHog: Go言語製のメールサーバーソフト。
 
=== Debian ===
 
==== PHP8 ====
[How To Install PHP 8.0 on Debian 11/10/9 | ComputingForGeeks](<nowiki>https://computingforgeeks.com/how-to-install-php-on-debian-linux/</nowiki>)
 
Debian 11の場合、PHP 8には外部リポジトリーが必要なので追加する。
 
sudo apt update
 
sudo apt install -y lsb-release ca-certificates apt-transport-https software-properties-common gnupg2
 
PHPパッケージを追加する。
 
echo "deb <nowiki>https://packages.sury.org/php/</nowiki> $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/sury-php.list
 
wget -qO - <nowiki>https://packages.sury.org/php/apt.gpg</nowiki> | sudo apt-key add -
 
sudo apt update
 
これでPHP8を参照できるので、インストールする。
 
sudo apt install php8.2
 
[How to Switch between Multiple PHP Version on Debian 12/11/10 – TecAdmin](<nowiki>https://tecadmin.net/switch-between-multiple-php-version-on-debian/</nowiki>)
 
インストールしたら、PHPのバージョンを切り替える。
 
a2dismod php7.4
 
a2enmod php8.2
 
sudo systemctl restart apache2
 
php 8.2にするとこういうエラー。
 
[Sat Sep 02 11:31:02.558029 2023] [php:error] [pid 25644] [client 133.106.38.37:57181] PHP Fatal error:  Uncaught Error: Undefined constant "DB_DATAOBJECT_ERROR_NODATA" in /var/www/gnusocial/public/index.php:104\nStack trace:\n#0 [internal function]: handleError()\n#1 {main}\n  thrown in /var/www/gnusocial/public/index.php on line 104
 
念のためdockerで起動を試みましたが、同じくトップ画面を開くと同じエラーになります。
 
<<nowiki>https://notabug.org/gnusocialjp/gnusocial/src/main/docker/development</nowiki>> にDockerでの起動方法があります。`docker compose up -d` を実行するだけでlocalhostでアクセスできます。
 
私とあなたとの環境の違いを排除したいので、dockerのインストールだけ頑張って、それでdockerでも簡単に動作確認してくれませんか?
 
==== alternative ====
Ref: [https://wiki.debian.org/DebianAlternatives DebianAlternatives - Debian Wiki].
 
OS内でバージョン違いのプログラムを管理するための仕組みがある。それがupdate-alternativesコマンド。<syntaxhighlight lang="sh">
sudo update-alternatives --display vi
sudo update-alternatives --config vi
</syntaxhighlight>オプションとコマンド名を指定することで、現在の実体と更新ができる。
 
=== XAMPP ===
 
==== ポート番号変更 ====
[https://qiita.com/neneta0921/items/3c2f9ac8ea9b5bcfc6e6 Xamppでポート競合を防ぐ方法 #PHP - Qiita]
 
XAMPP Control PanelのConfigから変更可能。
 
phpmyadminはConfigのphpmyadminで、Servers.portを追加する。
 
== Vim ==
 
=== Other ===
 
==== Async ====
https:/github.com/skywind3000/asyncrun.vim
 
asyncrun.vimは1個のバックグラウンド処理しか対応していない。
 
<nowiki>https://github.com/skywind3000/asyncrun.vim/issues/12</nowiki>
 
vim-dispatchならいけるのか?
 
==== Binary ====
[https://vim-jp.org/vim-users-jp/2010/03/21/Hack-133.html vim-jp » Hack #133: バイナリファイルを編集する]
 
==== grep ====
非同期でgrepする方法。
 
<nowiki>https://superuser.com/questions/861783/how-to-run-a-grep-in-vim-asynchronously</nowiki>
 
<nowiki>https://www.reddit.com/r/vim/comments/5ses2e/async_grep_in_vim_8/</nowiki>
 
Vim 8の非同期APIはプラグイン用。
 
<nowiki>*</nowiki> <nowiki>https://github.com/mhinz/vim-grepper</nowiki>
 
<nowiki>*</nowiki> <nowiki>https://github.com/skywind3000/asyncrun.vim</nowiki>
 
<nowiki>*</nowiki> <nowiki>https://github.com/tpope/vim-dispatch</nowiki>
 
<nowiki>https://wonderwall.hatenablog.com/entry/2017/10/09/210000</nowiki>
 
asyncrun.vimでやるのがよさそう。
 
==== AnsiEsc ====
<nowiki>*</nowiki> https:/unix.stackexchange.com/questions/444226/how-to-make-vim-interpret-escaped-characters-as-colors
 
<nowiki>*</nowiki> https:/superuser.com/questions/358409/how-can-i-tell-vim-to-show-ansi-escape-codes-properly
 
本家は太字に対応していないのでこちらがいいかな。
 
- https:/github.com/powerman/vim-plugin-AnsiEsc
 
ただし、こちらはgvimでクリック時にカーソル位置がずれる。
 
=== program ===
 
==== C ====
[https://daisuzu.hatenablog.com/entry/2012/05/06/204019 ワシのVimプラグインは百八式まであるぞ - daisuzu's notes]
 
【C/C++】
 
     87. a.vim
 
        C/C++のヘッダとソースを切り替えます。
 
     88. c.vim
 
        C/C++のテンプレートやイディオムの入力をサポートしてくれます。
 
     89. CCTree
 
        cscopeを使って関数のコールグラフを表示してくれます。
 
     90. Source-Explorer-srcexpl.vim
 
        ソース解析ツール、Source InsightのVim版です。
 
     91. trinity.vim
 
        taglist, srcexpl, nerdtreeを同時に起動して
 
        VimがIDE画面のような画面になります。
 
     92. cscope-menu
 
        cscope用のメニューを表示してくれます。
 
     93. gtags.vim
 
        gtagsを使ってファイルを開けます。
 
     94. DoxygenToolkit.vim
 
        Doxygenコメントの入力をサポートしてくれます。
 
== Visual Studio Code ==
 
=== Keybind ===
 
==== 矩形選択 ====
Ref: [https://mitomito.hatenablog.jp/entry/2021/01/27/073000#:~:text=VS%20Code%E3%81%AE%E7%9F%A9%E5%BD%A2%E9%81%B8%E6%8A%9E%E3%81%A8%E7%9F%A9%E5%BD%A2%E8%B2%BC%E4%BB%98%E3%81%AE%E6%93%8D%E4%BD%9C%E6%96%B9%E6%B3%95%201%20%E3%83%9E%E3%82%A6%E3%82%B9%E3%81%A7%E6%93%8D%E4%BD%9C%E3%81%99%E3%82%8B%E5%A0%B4%E5%90%88%20shift%20%2B%20alt%20%2B,shift%20%2B%20alt%20%2B%20%E7%9F%A2%E5%8D%B0%E3%81%A7%E4%BB%BB%E6%84%8F%E3%81%AE%E7%AF%84%E5%9B%B2%E3%82%92%E9%81%B8%E6%8A%9E%E3%81%97%E3%80%81%20%28or%20%E5%88%87%E3%82%8A%E5%8F%96%E3%82%8A%29%E3%81%99%E3%82%8B%20 VS Codeの矩形選択と矩形貼付の操作方法 - mito’s blog].
 
* s-alt-クリック
* c-s-alt-矢印
ジャンプ
 
* 括弧ジャンプ: C-S-\
 
=== Config ===
 
==== Default terminal ====
Ref: [https://stackoverflow.com/questions/44435697/change-the-default-terminal-in-visual-studio-code bash - Change the default terminal in Visual Studio Code - Stack Overflow].
 
[F1]-[Terminal: Select Default Profile]
 
=== cscope ===
cscope用のプラグインが何個かある。
 
* [https://marketplace.visualstudio.com/items?itemName=xulion.codescope scope4code - Visual Studio Marketplace]
* [https://marketplace.visualstudio.com/items?itemName=SeungukShin.cscope-code cscope-code - Visual Studio Marketplace]
 
scope4codeのほうがいろいろできそうだが、うまく動作しなかった。使い方がよくわからない。
 
cscope-codeはシンプルだが動作した。こちらを当分使うことにする。
 
Macの場合、control-. sのように、control-.の後に、controlを話してsを押すと発動する。カーソル下のシンボルしか使えない感じなのがネック。まあいい。
 
=== Vim ===
 
* [https://marketplace.visualstudio.com/items?itemName=vscodevim.vim Vim - Visual Studio Marketplace]
 
VSCodedでVimのキー操作を使うためのプラグイン。これが一番人気。いや、Vimのエミューレーターは中途半端な感じだから使わないほうがいいかな。
 
=== Extension ===
CSS
 
Tailwind CSS IntelliSense
 
==== PHP ====
Laravel Blade Snippets
 
===== PHP Intelephense =====
Ref: [https://marketplace.visualstudio.com/items?itemName=bmewburn.vscode-intelephense-client PHP Intelephense - Visual Studio Marketplace].
 
VSCodeのPHPの補完拡張として人気が高い。
 
====== Quick Start ======
設置後、しておくべき設定がある。
 
* Go to <code>Extensions</code>.
* Search for <code>@builtin php</code>
* Disable <code>PHP Language Features</code>. Leave <code>PHP Language Basics</code> enabled for syntax highlighting.
 
VSCodeの [PHP Language Features] を無効にしておくとのこと。
 
後は、.php以外の拡張子でPHPファイルがあれば、関連付けを追加するとか。
 
====== Module ======
peclなどPHPの標準モジュールで一部認識できないものがある。
 
「[https://stackoverflow.com/questions/62258598/undefined-type-imagick-in-vscodes-intelephense php - Undefined type 'Imagick' in VSCode's intelephense - Stack Overflow]」にあるように、そういう場合は [Settings]-[Stubs] で追加するとよい。
 
====== Coding ======
Ref: [https://beyondjapan.com/blog/2020/02/intelephense-vscode-php/ VSCode で PHP 開発するならインテリセンス最強の intelephense を使おう | 株式会社ビヨンド].
 
intelephenseでコード補完を認識しやすい書き方というのがある。
 
まず、型をつけられるものはつける。<syntaxhighlight lang="php">
function superMethod()
{
    /** @var AwesomeService $awesomeService */
    $awesomeService = $this->app->make(AwesomeService::class);
    $awesomeService->awesomeMethod();
}
</syntaxhighlight>ローカル変数も型名を指定する。これをしないと、インスタンスでコード補完が効かない。
 
== PIM ==
[https://ja.wikipedia.org/wiki/Personal_Information_Manager Personal Information Manager - Wikipedia]
 
PIMという個人情報管理用アプリの分類がある。
 
* カレンダー
* アドレス帳
* 電子メール
* タスク管理
* メモ帳
* 音声メモ
* 電卓
* 時計
* 電子辞書
 
=== E-mail ===
 
==== General ====
 
===== Naming =====
 
====== RFC ======
*webmaster
*support
*info
*service
*pr
*billing
*氏名
 
[https://news.mynavi.jp/article/20120315-mailaddress/ 売上をアップするメールアドレス、商機を失うメールアドレス | マイナビニュース]
 
[https://webtan.impress.co.jp/e/2015/03/31/19657 infoやwebmasterなど企業サイトが備えるべきメールボックスのルール、ご存じですか? | 編集長ブログ―安田英久 | Web担当者Forum]
 
[https://rfc-jp.nic.ad.jp/rfc-jp/RFC2142-JP.txt rfc-jp.nic.ad.jp/rfc-jp/RFC2142-JP.txt]
 
[https://www.tains.tohoku.ac.jp/news/st-news-23/3437.html <nowiki>SuperTAINS News No.23 [Page.5]</nowiki>]
 
[https://fumidzuki.com/knowledge/109/ 【Mail】メールアドレス作成のガイドライン(RFC2142) – fumidzuki]
 
公開用のメールアドレス。何にしようか考えていた。
 
<nowiki>RFC 2142</nowiki>でいくつか推奨されている。
 
info@ support@ answer@ inquery@ contact@ pubic@
 
contact@がやっぱり一番しっくりくる。info@ support@はRFC 2142にあるけど,これはビジネスより,サービスに紐付いたもの。個人でやる分にはサービス関係ないから,これは違う。publicも悪くはないのだけど,あまり一般的ではないか。
 
====== develop ======
<html>
<blockquote style="position: relative; padding-left: 55px;">
                <section><a href="tag:gnusocial.jp,2022-10-08:noticeId=432699:objectType=note">GNU social JP管理人 (gnusocialjp@gnusocial.jp)'s status on Saturday, 08-Oct-2022 23:13:28 JST</a><a href="https://gnusocial.jp/gnusocialjp" title="gnusocialjp@gnusocial.jp"><img src="//gnusocial.jp/avatar/1-48-20220724135646.webp" alt="GNU social JP管理人" style="position: absolute; left: 0; top: 0;" width="48" height="48">GNU social JP管理人</a></section>
                <article>使用するメールアドレスに悩みます。GitのメールアドレスはGitのホスティングサービスに掲載され一般公開されます。<br>
                  <br>
                  メーリングリストのメールアドレスも、返信方法によって引用されアーカイブで一般公開されます。<br>
                  <br>
                  どう使い分けるのがよいでしょうか?案↓</article>
                <footer><a rel="bookmark" href="https://gnusocial.jp/conversation/243494#notice-432699">In conversation</a><time datetime="2022-10-08T23:13:28+09:00" title="Saturday, 08-Oct-2022 23:13:28 JST">about 11 minutes ago</time> <span>from <span>web</span></span><a href="https://gnusocial.jp/notice/432699">permalink</a></footer>
              </blockquote>
<blockquote style="position: relative; padding-left: 55px;">
                <section><a href="tag:gnusocial.jp,2022-10-08:noticeId=432737:objectType=note">GNU social JP管理人 (gnusocialjp@gnusocial.jp)'s status on Saturday, 08-Oct-2022 23:20:04 JST</a><a href="https://gnusocial.jp/gnusocialjp" title="gnusocialjp@gnusocial.jp"><img src="//gnusocial.jp/avatar/1-48-20220724135646.webp" alt="GNU social JP管理人" style="position: absolute; left: 0; top: 0;" width="48" height="48">GNU social JP管理人</a>
                  <div><a href="https://gnusocial.jp/notice/432699" rel="in-reply-to">in reply to</a></div>
                </section>
                <article>
                  <ol>
                    <li>develop@domainのようなアドレスで共有</li>
                    <li>develop@, ml@ で用途別</li>
                    <li>contact@ で一般公開用で共有</li>
                  </ol>
                  開発用のメールなので、1がいいですかね。仮に漏洩しても開発関係経由というのがわかるので。</article>
                <footer><a rel="bookmark" href="https://gnusocial.jp/conversation/243494#notice-432737">In conversation</a><time datetime="2022-10-08T23:20:04+09:00" title="Saturday, 08-Oct-2022 23:20:04 JST">about 5 minutes ago</time> <span>from <span>web</span></span><a href="https://gnusocial.jp/notice/432737">permalink</a></footer>
              </blockquote>
</html>
 
1がいいと思う。
 
====== category ======
目的に応じて使い分けたほうがよさそう。
 
[https://upa-pc.blogspot.com/2014/06/mail-security.html メールアドレスを何個ぐらい使い分けたら安全・快適に過ごせるのか - Dr.ウーパのコンピュータ備忘録]
 
メールアドレス流出時の被害防止
 
不審なメールの検知
 
必要な数
 
* 銀行・証券会社
* 知り合い
* ショッピングサイト
 
その他
 
* Webサイトなどの公開用
* 本名でのやり取り
* ニックネーム
* 金銭のやり取りのないサービス登録
* 金銭のやり取りのあるサービス登録
* 登録にメールアドレスが必要だけど,そんなに使っていないメール
 
メールアドレスの種類
 
* フリーメール
* プロバイダーメール
* 独自ドメイン
 
[https://afmasakun01.com/3373.html メールアドレスの種類とアフィリエイトにおける3つの使い分け方法 | アフィリエイト]
 
* サービス登録用
* メルマガ購読用(捨てアド)
* メインアドレス
 
[https://d.hatena.ne.jp/okmount/20080505/1209914528 メールアドレスの使い分けかた(前編) - 学習する機械、学習しない人間]
 
[https://d.hatena.ne.jp/okmount/20080506/1210002001 メールアドレスの使い分けかた(後編) - 学習する機械、学習しない人間]
 
これらを考えてどういう名前で何個用意するかを考える。
 
とりあえずメインで使うmainというアドレスを一つ用意する。残りをどうするか。
 
Webサイト公開用にcontact
 
* main: メインで使うメール。人に直接教えるときや,お金が絡む場合,ショッピングサイトなど実名が求められるような重要な内容にはこれ。こちらから送信するときもこれ。相手の顔が見えているとき。
* contact:受信専用,公開用。問い合わせ用。なんかフォーラムやブログのコメント欄やcontact usなどにこちらから問い合わせる時なども。相手の顔が見えないときなど。
* service: 基本的に受信専用,たまに返信。Webサービス登録用。
* recruit:就職活動用。就職サイトとか転職エージェント,企業とやりとりするときはけっこうメール来るから。
* job: 個人事業、仕事用、不動産は事業なのでこちら。
* job: 個人事業、仕事用、不動産は事業なのでこちら。
* money: 金融機関登録用。銀行、証券会社、クレジットカード会社、決済会社・サービス。
* money: 金融機関登録用。銀行、証券会社、クレジットカード会社、決済会社・サービス。
* shop/store: ショッピングサイト、個人間売買サイト。
* shop/store: ショッピングサイト、個人間売買サイト。
* ユーザー名: メールアドレスの@以前はユーザー名とみなされることがあるので、ユーザー名のアドレスも用意しておくとよさそうだ。
* ユーザー名: メールアドレスの@以前はユーザー名とみなされることがあるので、ユーザー名のアドレスも用意しておくとよさそうだ。
 
 
 
 
 
 
こちらから送信するときのメールアドレス。
こちらから送信するときのメールアドレス。
 
 
Webサービスに登録するときどうするか。不動産屋さんとか人に教えるときはどうするか。アフィリエイトとかドメインとか実名が求められるときはどうするか。
Webサービスに登録するときどうするか。不動産屋さんとか人に教えるときはどうするか。アフィリエイトとかドメインとか実名が求められるときはどうするか。
 
 
gmailの+を考える。gmailでは+や.をつけると無限にアドレスをつけられる。ただし,受信は+のないメール。
gmailの+を考える。gmailでは+や.をつけると無限にアドレスをつけられる。ただし,受信は+のないメール。
 
 
ただし,gmailの+は使えないときがある。@以前の部分をユーザー名とみなして,+を無効な文字とみなすサービスがある模様。
ただし,gmailの+は使えないときがある。@以前の部分をユーザー名とみなして,+を無効な文字とみなすサービスがある模様。
 
 
[https://www.postcom.co.jp/ ネットではがきが印刷~郵送できるポスコミ【1枚から注文OK】]
[https://www.postcom.co.jp/ ネットではがきが印刷~郵送できるポスコミ【1枚から注文OK】]
 
<nowiki>https://www.tomtop.com/もだめ。</nowiki>
 
今まで使ってきたメールとはどうやりくりするか。
 
Thunderbirdでやる場合,Archiveするときに既読とメールのコピーを行う。
 
他のアドレスのメールはmainに転送するようにしておいて,mainのメールアドレスで確認。
 
最終的にThunderbirdでArchiveを実行したら,宛先のメールのフォルダーに同じ内容が既読状態でコピーされることにする。
 
このようなフィルターを作っておく。受信時にコピーしてしまうと,未読状態でコピーされてしまうか,受信した瞬間に既読状態になってしまい,見逃す可能性が高い。
 
Manage Identitiesで返信時に受信したアドレスで返信できるように登録しておく。


<nowiki>https://www.tomtop.com/もだめ。</nowiki>
==== Mozilla Thunderbird ====


今まで使ってきたメールとはどうやりくりするか。
===== プロファイルの統合 =====


Thunderbirdでやる場合,Archiveするときに既読とメールのコピーを行う。
* [https://forums.mozillazine.jp/viewtopic.php?f=3&t=17478 MozillaZine.jp フォーラム • トピック - プロファイルの統合]
 
* [https://okwave.jp/qa/q5924014.html#goog_rewarded thunderbirdで2つのプロファイルを統合する方法| OKWAVE]
他のアドレスのメールはmainに転送するようにしておいて,mainのメールアドレスで確認。
 
最終的にThunderbirdでArchiveを実行したら,宛先のメールのフォルダーに同じ内容が既読状態でコピーされることにする。
 
このようなフィルターを作っておく。受信時にコピーしてしまうと,未読状態でコピーされてしまうか,受信した瞬間に既読状態になってしまい,見逃す可能性が高い。
 
Manage Identitiesで返信時に受信したアドレスで返信できるように登録しておく。


ImportExportToolsでデータ移行するというのが手堅い。一括操作を念頭に置いた機能になっている。数が少ないならば、emlファイルをドラッグドロップで取り込むこともできる。
[[Category:IT]]
[[Category:IT]]

2024年11月20日 (水) 17:29時点における最新版

ソフトウェア開発作業全般

Other

ASCIIFlow: 画面構成図などの作成でテキストなので便利かもしれない。

Project

名簿付きの寄付

  • Vim: https://vim-jp.org/vimdoc-ja/sponsor.html
  • Vim (list): https://www.vim.org/sponsor/hall_of_honour.php
  • KDE: https://relate.kde.org/
  • KDE (list): https://relate.kde.org/civicrm/profile?gid=18&search=0
  • Conservancy (list): https://sfconservancy.org/sponsors/
  • Conservancy: https://sfconservancy.org/donate/

Kanboard

クローズ時に自動移動

[Configure project]-[Automatic actions]

  • action=[Move the task to another project]
  • Event name=Closing a task
  • Column=Done
  • Project=

これでDoneをclose時にアーカイブ用のプロジェクトに移動できる。

Communication

Skype

すべてのエモーティコンのリストはありますか? - Microsoft サポート

Skyepで使用可能な絵文字の一覧。

Tool

General

Call tree

kcachegrindだったかな。

kscopeもこれか。

Doxygen+GraphVizで関数コールグラフ

kscope

https:/github.com/ivan0124/Linux-programming/wiki/How-to-use-KScope-to-trace-code

https:/sourceforge.net/projects/kscope/

http:/www.lemis.com/grog/software/kscope.php

cscope

cbrowser/kbrowserというGUIもある。

cscopeの大文字小文字無視検索

http://vim.1045645.n5.nabble.com/how-to-search-with-cscope-ignoring-case-td5715043.html

DBを別にする必要がありそう。

expect

端末の手動操作を自動化するソフト。

* ^と$は使えない。代わりに、\nを使う。

* 文字列の囲みに一重引用符 (') は使えない。二重引用符 (") のみ有効。

* expect文はawkみたいな感じ。

* ただし、expectは注意が必要。最初のexpectにマッチしないと先に進めない。タイムアウトとかするしかない。

expect -c "set timeout 5; spawn cat cat.txt; expect \nFAIL {send pwd/n; expect :; exit}"

https:/linuxjm.osdn.jp/html/expect/man1/expect.1.html

```

sh -eux <<-"EOT"

expect -c "set timeout 5; spawn ssh senooken@senooken-linux; expect :; send ieneko/n; expect aho {send echo aho} +x {send pwd/n}; expect /$; exit"

expect -c "set timeout 5; spawn ssh senooken@senooken-linux; expect :; send ieneko/n; expect + {send pwd/n}; expect /$; exit"

expect -c "set timeout 5; spawn cat cat.txt; expect \nFAIL {send pwd/n; expect :; exit}"

expect -c 'set timeout 10; spawn cat cat.txt; expect "aa F" {set AAA "abc"}; expect FAIL {send "$AAA/n"; expect " "; exit}'

EOT

```

Coding

タイムゾーン

タイムゾーン呪いの書 #timezone - Qiita

3文字形式は避けたほうが無難。

タイムゾーン名で判定する実装があるので、UTC-9なども避けたほうがいい。

tz databaseのAsia/Tokyoなどの確実性が高い。

Regular Expression

正規表現。重要。覚えにくいが重要なものをメモしておく。

後ろからマッチ。cが置換対象。

Case

/[^c]*$/: cより右端

マッチの前後の挿入

https:/vim.fandom.com/wiki/Power_of_g

:g/GST_.*("/s/^/LOG(INFO) << "DEBUG";/r/

行頭・行末で引っ掛ける。

関数にログ
:%s/([^")]*)/) /([a-z]* /)*{/&/rLOG(INFO) << "/1";/r/g

考慮するケース

double currentTime() const override { return m_element->currentTime(); }

glob

重要。正規表現とは似ているが異なる、パターンマッチング記法 (Pattern Matching Notation)。主に、globで採用されており、ディレクトリー・ファイルのマッチングで使われる。

使用可能な記号は以下3個。以下の3文字は\でエスケープできる。

  • ?: 任意の1文字にマッチ。
  • *: 任意の0以上の文字にマッチ。
  • [: []内の1文字にマッチ。正規表現の各括弧と同じ。ただし、先頭の否定が^ではなく、!。

ファイル名マッチ時には、追加で特殊なルールがある。

.から始まるファイル名へのマッチには、.が必要。つまり、*?は先頭の.にはマッチしない。[!a] のような否定形の各括弧記法も.にはマッチしない。加えて、先頭の[.]もマッチするかは不定(unspecified)。

globで.ファイルを含めたい場合、工夫が必要 (PHP: glob - Manual)。

.[!.]* *

上記のように.ファイルのマッチとそれ以外を指定する必要がある。

.[!.]* は、...以外の..始まりのファイルにマッチする。

.*を指定すると、./..がマッチするので注意する。最近のシェルは、シェル側で気を利かせているようで、.*だと. /..はマッチしない。

引用符のネスト

シェルやプログラミング言語で、文字列リテラルの表現などで、一重引用符'と二重引用符"を使う。

JSON作成や変数展開などで、これらをネストさせたいことがある。その基本的な考え方を整理する。

交互にしていい場合は簡単二重。引用符内に一重引用符を配置、一重引用符内に二重引用符を配置すればいい。

問題はこれがNGな場合。特にありがちなのが、JSONの生成。JSONの引用符は二重引用符のみ。一重引用符の中だと、二重引用符の変数展開が使用不能。外側を二重引用符にする必要がある。

二重引用符は、内部で変数展開が可能。この都合で、バックスラッシュ\によるエスケープが有効。

基本的な方法。

  1. 既存の一重/二重引用符などをバックスラッシュでエスケープ。
  2. 全体を一重/二重引用符で囲む。

何かAwkの本か何かで、基本的な考え方の説明の記載があった気がする。

[{"ke\y":"valu\e"}] を例として考える。

  1. {"ke\y":"valu\e"}
  2. エスケープ: {\"ke\\y\":\"valu\\e\"}
  3. 全体囲み: "{\"ke\\y\":\"valu\\e\"}"

これでOK。また何か考慮不足があればそのときに考える。

ただ、元データに修正が必要なので、そのまま行きたい。ヒアドキュメント的なものが使えるならそれを使うのがいい。

例えば、シェルなら、catコマンドとコマンド置換で生テキストを使える。

echo $(cat <<-'EOT'
{"ke\y":"valu\e"}
EOT
)

.envなどで使える技?いや使えない。.envではシンプルなコマンドしか使えず、ヒアドキュメントは使えない模様。

JSONのvalue部分に適用したい場合。データの二重引用符をバックスラッシュでエスケープする。これはこうするしかない。JSONが二重引用符しか認めないから。

基本的な考え方がある。

  1. JSON value用に二重引用符"を\"で置換。
  2. \"がPHP/JavaScriptで二重引用符に扱いにならないように、\を\\に置換。
  3. JSON項目の二重引用符"を\"で置換。
  4. 全体を二重引用符"で囲む。

こういう感じ。JSONはawkでも任意の最終データで考える。途中にプログラミング言語でのパースがあるので、それを考慮する必要がある。

ケース変換

javascript - camelCase to kebab-case - Stack Overflow

キャメルケースをチェインケースにしたり、逆にしたりなどケース変換したいことがある。正規表現を駆使して実現する。

encode

【PHP入門】URLエンコードする方法(urlencode) | 侍エンジニアブログ

日本語や記号を他のコードに変換 (エンコード) する方式が何通りかある。把握しておくと役立つ。

  • パーセントエンコーディング/URLエンコード: URLで使用不能な文字を%16進数で連結。
  • UTF-8
  • base64: 全データを「A-Z」「a-z」「0-9」「+」「/」の64文字で表現。文末に=を使うので実質は65文字。
  • HTMLエンコード: HTMLで特殊な意味を持つ文字を&lt;などに変換する。

Percent-encoding

unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"

上記文字はエンコードの対象外。

英数変換

string - PHP How to encode all characters with rawurlencode - Stack Overflow

変数名への変換などで、日本語や記号を英数字 [0-9a-zA-Z] に変換したいことがある。

こういう目的だと%エンコーディングが適している。

ただし、一部の記号を許可しているので、自前で変換する。

function encode_all($str) {
    $hex = unpack('H*', $str);
    return preg_replace('~..~', '%$0', strtoupper($hex[1]));
}

$str = 'big ƒüßchen';
print_r(encode_all($str));

Term

紛らわしい用語がある。

フレームワークの中にライブラリーも含めていいと思う。

Category

ソフトウェア開発工程 - Wikipedia

ソフトウェアの分類、ページ分類時に役立つ。

  • 言語
  • ツール: 静的解析、テスト、文書など。
  • フレームワーク

MediaWikiのページ名は全体で固有が条件なので、言語名+分類名でページを作るといい。

  • PHP language
  • PHP tool
  • PHP framework

成功時連続継続処理

一度の取得件数の上限が決まっていて、終了・失敗するまで取得を継続したいという処理がそれなりに発生する。

  1. 処理実行。
  2. 成功ならA、失敗なら終了。
  3. 処理実行。
  4. 成功ならA、失敗なら終了。

こういうパターン。いくつか実装方法があるが、while (true) のパターンが重複がなくてベストだと思う。

        /*
        // 無限ループで終了条件でブレイク
        while (true) {
            // 処理実行
            if (失敗) {
                break;
            }
            成功時処理
        }
        
        // do while
        do {
            処理実行
            if (成功時) {}            
        } while ();

        // for (初期化; 継続判定・終了判定; 成功時式) {
            処理実行
        }
        */

do-whileは成功・終了判定を2回書く必要がある。

forだと成功処理を式でしか書けない。成功処理を関数や即時実行関数式などで書くなら悪くはないし、ベストになりえる。

いや、成功時処理内の処理の結果次第で反復の終了条件などが追加で入るならNGになる。なので、やっぱりwhile(true)が無難。コード行数もそんなに変わらない。

これにさらに初回だけ、ヘッダーの取得、書き込み処理などが発生する場合、初回だけループの外でやるのがきれいだろうか?初回処理が2回登場することになるけれど。

offsetなどで初回の判定が反復内でできるから、それで分けるのがいいか?

        $offset = 0;
        while (true) {
            $currentReturnCode = $service->sendRequest(Raku2Config::API_TYPE_CSV_EXPORT, Raku2Config::CONFIG_API_URL_MULTI_API, [
                json_encode([
                    'dbSchemaId' => $table_info['dbSchemaId'],
                    'offset' => $offset,
                    'limit' => $limit,
                ])
            ]);

            $response = $service->getApiResultJson();
            // 終了条件: 戻り値が成功以外、か応答本体が1行 (ヘッダーのみ) の時。
            if (($currentReturnCode !== Raku2Config::EXIT_SUCCESS) || (substr_count($response, "\n") <= 1)) break;

            // 2回目からはヘッダー除去して書き込み。
            $start = strpos($response, "\n") + 1;
            $flat = FILE_APPEND;
            if ($offset === 0) {
                $start = $flag = 0;
                $path = stream_get_meta_data($fp = tmpfile())['uri'];
            }
            file_put_contents($path, substr($response, $start), $flag);
            $offset += $limit;
            sleep(3);
        }
        for ($offset = 0;
            ($currentReturnCode === Raku2Config::EXIT_SUCCESS) && (substr_count($response, "\n") > 1);
            (function() use (&$offset, $limit, $response) {
                // 2回目からはヘッダー除去して書き込み。
                $start = strpos($response, "\n") + 1;
                $flag = FILE_APPEND;
                if ($offset === 0) {
                    $start = $flag = 0;
                    $path = stream_get_meta_data($fp = tmpfile())['uri'];
                }
                file_put_contents($path, substr($response, $start), $flag);
                $offset += $limit;
                sleep(3);
            })()
        ) {
            $currentReturnCode = $service->sendRequest(Raku2Config::API_TYPE_CSV_EXPORT, Raku2Config::CONFIG_API_URL_MULTI_API, [
                json_encode([
                    'dbSchemaId' => $table_info['dbSchemaId'],
                    'offset' => $offset,
                    'limit' => $limit,
                ])
            ]);
            $response = $service->getApiResultJson();
        }

character

BOM

UTF-8のBOM

\xef\xbb\xbf

この文字を先頭につけるとUTF-8のBOMになる。

Convert

IP/CIDR

// JavaScript
    /**
     * サブネットマスクをIPアドレス形式 (x.x.x.x/255.255.255.0) からCIDR形式 (x.x.x.x/24) に変換する。
     * @param {string} ipaddress - IPアドレス文字列 (x.x.x.x/x.x.x.x形式)。
     */
    toCIDR(ipaddress) {
      const [address, mask] = ipaddress.split('/')
      const segments = mask.split('.')
      const CIDR = segments
        .map((e) => Number(e).toString(2))
        .join('')
        .replace(/0*$/, '').length
      return address + '/' + CIDR
    },
    /**
     * サブネットマスクのCIDR形式 (24) をIPアドレス形式 (255.255.255.0)に変換する。
     * @param {number} cidr - ciderの数字。
     * @return {string} x.x.x.x形式のIPアドレス文字列。
     */
    cidrToIp(cidr) {
      const digit = 32
      const ip = ('1'.repeat(cidr) + '0'.repeat(digit)).substr(0, digit)
      return ip
        .match(/.{8}/g)
        .map((e) => parseInt(e, 2))
        .join('.')
    },

Algorithm

再帰処理

https://chatgpt.com/c/673d9bfe-2414-800b-9922-f94be6dbe950

再帰関数で実装するほかに、スタックで処理する方法がある。

再帰関数のほうが簡単に実装できるが、関数呼び出しのオーバーヘッドがある。ネスト10-100程度くらいなら問題ない。

パフォーマンスや再帰中の細かい制御が必要なら、スタックが有利。ただし、実装がやや複雑。

最初は再帰関数で実装して、後でボトルネックになったらスタックというのも手。

UML

Umbrello

Problem

altなどの重なり順番、アクティブの下になっちゃう

optの条件が表示されない。

Modelio

クラス図

  • 汎化 (generalization): 実線白矢印。継承。
  • 実現 (realization): 点線矢印。interfaceの継承。
  • 集約: 白ひし形。
  • コンポジション: 黒ひし形。子が単体で存在できない場合。親と生存期間が同一の場合。
  • 関連: 実線矢印。メソッド内インスタンスなど。
  • 依存: 点線矢印。引数やローカル変数、返却値。

Design

Atomic Design

最近のUIのコンポーネントの組み方。UIコンポーネントを粒度に分けて、ディレクトリー分けして流用するという考え方。

  • atoms: 原子。これ以上分割不能な最小単位。input/label/buttonなど。
  • molecules: 分子。atomsを組み合わせたり、atomsに多少修正したもの。入力フォーム、ナビゲーション、カードなど。
  • organisms: 有機体。分子+アルファ。入力フォーム+ヘッダーなど。複数の分子。
  • templates: テンプレート。複数の有機体。ヘッダー、メイン、フッターなど。
  • pages: ページ。テンプレートを使用したページ。

インターフェイスと抽象クラス

PHPでインターフェイスと抽象クラスを使う #PHP - Qiita

  • インターフェイスは、クラスに複数実装できるが、抽象クラスは1つしか継承できない。→不特定のクラスで、共通のメソッドを定義したい場合。
  • インターフェイスは、実装のあるメソッドを持つことができないが、抽象クラスは、実装のあるメソッドを持つことができる。→抽象クラスは、複数のクラスの、共通処理の中に、一部違う処理が入る場合、プロパティーが必要な場合などに使用する。

インターフェイス

  • メソッド宣言のみ。
  • static/constの場合に限定して、メソッド定義、定数もOK。

Config class

アプリケーションの設定を管理するクラスの設計方法。いくつか方法があり、議論がある。「Best way to provide configuration parameters for objects far away from the starting point - Software Engineering Stack Exchange」で特によく議論されている。

  1. シングルトン/グローバル変数: ただし、テストなどで並列アクセスが必要な場合に困ることがあるらしい。
  2. DI/設定クラス引数: これがよく支持されている。テストしやすいなど。グローバル変数への参照を渡すようなイメージ。ただし、依存性の伝播のように、上から下に設定を渡す際に、関係ない大量の設定を渡すことがあったりする。

2のDIが最近の主流。引数で値渡し相当にすれば、並列アクセス時も無影響。伝播の問題は設計の問題。

メソッドをmain関数で呼び出すことを想定して、必要なものだけ渡るようにして、余計なものは削除する。上位・下位の関係を明確にすれば、渡すだけのパラメーターを排除できる。

do-while/if

複雑なif文と相性がいい。

for whileの無限ループで最後にbreakでも同じか

do {
  if (true) break;
} while(false);

if文が複雑な場合、do-whileで囲んで、breakでスキップできる。gotoに近い。

GoF

基本的に、具象クラスを使わずに、インターフェイスや抽象クラスを使ってインスタンスを生成するというのが、共通する基本パターン。

これにより、いろんなケースに同じコードで対応できる。

Factory Methodパターン

なぜあんなに難しい?Factory Methodパターン - ecbeing labs(イーシービーイング・ラボ)

コンストラクターの代わりに、インスタンスを生成 (工場=factory) となるメソッドを使うから、FactoryMethodパターン。

引数の内容に応じて、異なるクラスを作成する。

ただ、Factory Methodパターンを採用すると、コード量が増えて複雑になる。

複雑でややこしいだけなので、基本的に使わなくてよいと思う。

Naming

camelCase

https://gnusocial.jp/notice/7694551

!it 命名規則のキャメルケース。これ英語前提です。関数名に英語以外を使うと破綻します。

getキーバリュー()みたいな関数の定義。日本語ですると境界がわからなくなるので、getキー_バリューみたいにアンダーバーで区切ったほうが分かりやすい。なるほど…

getMyVariable() vs myVariable()

getterとsetterの命名規則。

getVar()にするか、Var()にするか。C++だと後者のパターンがあったりする。getを省略できるので、省スペースになる。

ただ、コード補完で探しやすさがちょっと変わる。getを前置したほうがわかりやすいか。

namePrefixed() vs prefixedName()

https://chatgpt.com/c/673bd358-3dc8-800b-8ec9-d745cc0eba85

名詞+修飾語 (形容詞) の場合のメソッドの命名規則。name+修飾語が複数ある場合name+修飾語がいい。オブジェクト指向でnameをオブジェクトとして扱う形に近い。name.methodみたいな。

例えば、nameMax、nameMinのような場合は後ろのほうが都合がいい。ただ、こういう場合はそもそもnameをオブジェクトにしてname.max()、name.min()にしたほうがいいという説がある。

そうではないならば、getPrefixedName()などが自然。getQueryString()など。StringQueryではない。

PHPでは以下のような命名規則が好まれる。

  • 動詞+修飾対象=getPrefixedName/isPrefixed()
  • 修飾対象+状態/修飾語=prefixdName

getPrefixedNameがいいか。後置修飾にしたいならば、そもそもオブジェクト+メソッドにすることを検討する。

map

連想配列とかハッシュ、オブジェクトなどでキーバリュー形式のデータ構造を扱うことがある。そういう変数の命名規則。

map_[key]_[value] のような形式にすると、キーとバリューが何を意味するか分かってわかりやすい。

foreach

PHP - senooken JP Wiki

foreach系のfor文ではキーとバリューを変数に格納して反復する。ファイルや配列に対して行うことが多い。

foreach (table as $row => $line)

その際の変数名は、上記のように$row/$lineにすると、行番号と行の値がはっきりしてわかりやすい。

Function argument order

関数の引数は入力、変更、出力の順番にする。理由はこの順番で使うから。

https://social.senooken.jp/notice/67270

うーん。今晩は,CODE COMPLETEでC言語の関数の引数の順番を調べたりしていて,勉強時間がないな…

int func(入力,変更,出力)

この順番。理由は,この順番で使うから。

memcpyとかは例外が多い。

x = bの語順からきているからとの憶測がある。

https://okwave.jp/qa/q4202225.html

DB

PDOの真の力を開放する - PHPでデータベースを扱う(3): Architect Note

DBアクセスのモデル化。行をクラスとすると扱いやすい模様。

getterを作ったり、データの妥当性のチェックなどもできる。

select/insert/などはmapperでクラスとDB列名を対応付けて処理する。自前で実装する場合はこういうつくりがいいらしい。

データベース関係のデザインパターンがいくつかある。

  • Active Record
  • Data Mapper
Active Record pattern

テーブルレコードに対応するクラスを用意して、そのクラス自体にDB操作もさせる。

シンプルだが、複雑な操作が苦手。

エンティティーがテーブルと密接なため、例えばテーブル構造が変わった場合に大量に修正必要。

Ruby on Rails/Laravel+Eloquentなどで採用。

Data Mapper pattern

第14回 DataMapperの使い方 | gihyo.jp

テーブルのレコードをクラスにするのはARと共通。

ただし、DB操作用のクラスを用意してそちらでDB操作する。

その都合、1テーブルに2クラス必要。

User/UserMapperのような対応関係。

2クラス必要だが、テーブル構造が変わった場合でも基本はMapperで吸収できる。

JOIN

Active RecordもData MapperもJOIN時の扱いが一番重要。単一エンティティーしか扱わないならどちらも同じ。

基本はエンティティーのプロパティーに持たせる感じ。

datamapperパターンでjoinする場合、エンティティーの扱いはどうなるの?

`DataMapper`パターンで`JOIN`を行う場合、エンティティの扱いは設計次第ですが、いくつかの注意点があります。`DataMapper`パターンは、データベースのテーブルとエンティティの間にマッピングを行い、エンティティはドメインロジックを持ち、データベースアクセスの責務を持たないことが特徴です。そのため、`JOIN`の処理をどの層で行うかを慎重に設計する必要があります。

以下、`JOIN`を行う際のエンティティの扱いと実装方法について解説します。

      1. 1. マッパークラスでの`JOIN`実装

`JOIN`を伴う複雑なクエリが必要な場合、マッパーが直接`JOIN`を使って複数テーブルを組み合わせた結果を取得し、それを複数のエンティティとしてマッピングする方法があります。例えば、ユーザーと注文を持つシステムで、ユーザーとその注文を一緒に取得したい場合、`UserMapper`で`JOIN`を行い、結果セットを`User`と`Order`エンティティに分割してマッピングします。

```python

class UserMapper:

    def find_user_with_orders(self, user_id):

        sql = """

            SELECT * FROM users

            JOIN orders ON users.id = orders.user_id

            WHERE users.id = %s

        """

        results = self.db.execute(sql, (user_id,))

       

        user = User(results[0]['user_id'], results[0]['user_name'])

        orders = [Order(row['order_id'], row['product_name'], user) for row in results]

        user.orders = orders

        return user

```

この方法では、1つのSQLクエリで必要なデータをすべて取得し、エンティティのプロパティにそれぞれのデータを設定します。

      1. 2. リポジトリでの集約

`JOIN`を使わず、各エンティティを個別に取得した後、リポジトリが集約の役割を担う方法もあります。リポジトリが各エンティティの`Mapper`を呼び出し、必要なエンティティ同士を関連付けることで`JOIN`を再現します。例えば、まず`UserMapper`でユーザー情報を取得し、次に`OrderMapper`で該当ユーザーの注文を取得してエンティティ間で関連付けます。

```python

class UserRepository:

    def __init__(self, user_mapper, order_mapper):

        self.user_mapper = user_mapper

        self.order_mapper = order_mapper

    def get_user_with_orders(self, user_id):

        user = self.user_mapper.find(user_id)

        orders = self.order_mapper.find_by_user_id(user_id)

        user.orders = orders

        return user

```

UserテーブルとOrderテーブルがあって、あるユーザーの注文一覧を取得したい場合を考える。

結局、user.ordersみたいな感じで、エンティティーに外部テーブルのレコードを配列で持たせるつくりになる。

クロス集計する場合は、users[0].orderみたいな感じ。メインのエンティティーのプロパティーに持たせる。フラットじゃないのでちょっと気持ち悪い。が、まあ構造としてこうなるのは順当。

方法として、1回のSQLで取得するか、それぞれのエンティティーを取得してマージするか。1回のSQLでやったほうが当然いい。

Other

1対1-多対多

プログラミング言語でデータの関連付けをすることがある。

1対1の場合、配列、連想配列のキーバリュー形式のデータがぴったり。

多対多の場合。これも配列。二次元配列で基本は0要素目など。

$array[][]

AI

対話AI

List

【2024年版】対話型AIサービスおすすめ11選を徹底比較!チャットボットとの違い・メリット・課題・選び方なども紹介 - NotePM

いろいろある。

Name
Bing
Perplexity AI
ChatGPT
Google Gemini

ChatGPT

Plan

ChatGPT | OpenAI

Free/Plusの2のプランがある。

Free Plus
金額 [USD/月] 0 20
機能 基本 アーリーアクセス
エンジン GPT-4o mini GPT-4/GPT-4o/GPT-4o mini
制限 - GPT-4oの5倍以上のメッセージ送信
その他 - データ分析、ファイルアップロード、ビジョン、Webブラウジング
画像生成 - DALL-E

送信可能なメッセージ数、エンジン、画像生成などが大きな違いだろう。

Account

公式サイトにアカウントの意味の説明がない。しかたないので、ChatGPTに質問。

ChatGPTに会員登録する意味は何ですか?


ChatGPTに会員登録する主な利点はいくつかあります。

1. **パーソナライズされた体験**: 登録すると、あなたの好みや過去のやり取りに基づいて、よりカスタマイズされた応答が得られます。

2. **履歴の管理**: 過去のチャット履歴を保存し、いつでも見返すことができるため、情報の確認が簡単になります。

3. **新機能へのアクセス**: 登録ユーザーは新しい機能やアップデートを優先的に利用できる場合があります。

4. **プレミアム機能**: 一部のサービスでは、会員登録をすることで、より高度な機能やサポートが提供されることがあります。

5. **セキュリティとプライバシー**: アカウントを持つことで、データの管理やプライバシーの設定をより細かく調整できます。

興味があれば、ぜひ登録を検討してみてください!他に質問があればお知らせください。

自分の過去の質問の履歴を見れるだけでも便利かも。

方法
質問の分割

https://chatgpt.com/c/673bdc0d-e0e0-800b-a22b-4fa19e64476c

Q. chatgptで質問するとき、連続して質問すると、同じURLで複数の質問が表示される。リロードして質問を分けたほうがいいのか?

A. どちらでも問題ない。が、質問が関連しているなら同じチャットで継続したほうがいい。直前の質問も文脈を考慮できる。完全に話が異なるなら分けたほうが後で整理したり、URLを共有したときにわかりやすい。

感想
2024-11-14 Thu

https://gnusocial.jp/notice/7806505

!it !ai 業務でPHPの開発作業をしていて、ChatGPTを使いだして便利に感じています。検索エンジンの代わりに使っています。

例えば、「laravel eloquentでリレーション先のテーブルの主キー名の取得方法は?」と質問します。

https://chatgpt.com/c/67354314-fbdc-800b-a4e4-65f96d1a8fb2

getRelatedというややマニアックなメソッドを教えてくれます[eloquent getrelated] で検索してもなかなかたどり着けないです。

こういう検索エンジンで検索しにくい質問で便利だなと思います。

検索エンジンで検索すると、的外れな情報も大量にヒットします。対話AIはそのごみの混ざった検索結果を分析した結果をコンパクトに返してくれます。対話AI使わなくても、検索エンジンで時間かければわかりますが、大幅に時間短縮できます。

大量の凡人健常者が取り組んだ方法論として決まりきったものは、記憶の問題、ただの神経衰弱です。こういうのを検索エンジンの改良版としてAIに任せるのはいい使い方だと思います。

個人的に、ただの知識、事実は重要度高くないと思いますが、一般社会では評価する側の頭が悪いので、これが重宝されます。

同僚や先輩に聞くより対話AIのほうがよほど頭いいです。話すことないです。聞くほうが時間の無駄なので。凡人はどんどん要らなくなります。

一方、私みたいなキチガイのデータは少ないので、検索エンジンやAIに聞いても出てこないです。世界で自分だけのオリジナルに専念するのがたぶんいいです。

2024-11-19 Tue

https://gnusocial.jp/notice/7867350

!ai ChatGPTが検索エンジンの改良版としてやっぱり便利。さっきこういう質問しました。

phpのメソッド名で、英単語の修飾語は前と後ろどちらがいい?例えば、namePrefixed()とprefixedName()のどちらがいい? https://chatgpt.com/c/673bd358-3dc8-800b-8ec9-d745cc0eba85

私はこのレベルの細かい疑問がすぐ浮かぶのです。これを人間にきくと、頓珍漢な回答だったり、そもそも回答してもらえないし、何ならこういう質問した私がなぜかキチガイ扱いされて、微妙な雰囲気になって、質問できなくなって、ストレスが溜まって、居づらくなって早期退職になるんです。意味不明です。ただの質問にお気持ちの配慮とか面倒なので。

この間、 @yuriha に突っ込まれた件も、たぶん対話AIとお互い会話したほうが有意義だったんじゃないかとすら思います。相手も私に突っ込む前に対話AIと会話したほうが自分の主張の自己矛盾、頓珍漢さに気づけたんじゃないかとすら思えます。私が突っ込んでまーた私がキチガイ扱いされるのも回避されます。対話AIからの客観的な指摘なら、同じ内容であっても、キチガイの私が言うより納得しやすいでしょう?同じ内容なら対話AIのほうが凡人健常者にとっては、信じ込みやすいでしょ?

対話AIだとお気持ちの配慮いらないし、当たり前ですけど、キチガイ扱いされることもないので、快適です。元々対話AIには懐疑的でしたが、どちらかというと私のようなキチガイが凡人健常者の知識を拝借するためにあるような印象を持ちます。

検索エンジンでも調べることはできますが、めちゃくちゃ時間かかるんです。自分で複数の意見をみつけて、頭の中で比較検討して整理するので。これを一瞬でやってくれるのが楽。途中のデータ整理、目視は単純作業に近いのです。他のことに頭使えます。

もはや技術とか、ただの暗記の神経衰弱は別にいらないです。一般企業の上長とか、士業のように、単純知識でマウント取るタイプの仕事はこれで確かに駆逐されます。どうせ対話AIのほうが賢いのだから。知識量で勝てるわけないです。全世界の情報の集積結果なんだから。

凡人健常者の知識を拝借して、世界でだれにも真似できないキチガイ部分に専念できます。GNU socialの開発もこれでいけると思います。

VCS

List

Comparison of issue-tracking systems - Wikipedia https://en.wikipedia.org/wiki/Comparison_of_issue-tracking_systems

BTS。GitHubみたいな。PHP製の以下がよさそう。

VCSとの統合状況がまちまち。

Git

Commit

マージコミット後のコミット追加

マージコミット後に次の開発作業を始めることが多い。が、直後の初回のコミットを追加したい場合困る。

git rebase -iにすると、コミットが残るから。編集はできるが、その直前にコミットの追加ができない。マージコミットは扱いが特殊で直接rebaseで編集できない。

しかたないので、該当コミットでブランチを作成して、コミット。その後、既存の修正ブランチをrebaseでそのコミットの後にくっつける。これでいける。

コミットオプション

Git - git-commit Documentation

コミットメッセージ指定のためのオプションがある。

  • -m|--message <message>: コミットを文字列で指定。複数指定可能で、その場合段落で区切ってくれる。2行目以後を書きたい場合などで使う。
  • -C|--reuse-message <commit>: 指定したコミットのコミット情報を再使用する。
  • -c|--reedit-message <commit>: -Cの同じだが、編集画面を表示してコミットメッセージを編集して再使用する。
  • -F|--file=<file>: 指定したファイルをコミットメッセージに使う。-を指定すると標準入力を使う。

基本は-m。-mの複数指定。

過去コミットのメールアドレスの変更

単一コミットのメールアドレスを指定する場合、commitに--authorを指定する。

git commit --author="John Doe <john@doe.org>"

--amendと併用することで、過去コミットも変更できる。

数が少ないなら、rebase -iで1個ずつamendする。数が多いならfilter-branch。

第一コミットの変更

通常、第一コミットはammend以外では変更できない。

rebase --root [branch] でブランチの第一コミットも参照して改変可能。

マージコミットの打ち消し

マージコミットは扱いがやや特殊。

git revert -m 1 マージコミット
git reset --hard HEAD~1 # マージコミット前

どちらか。

stash

復元

Git Stashの復元: 誤って削除されたスタッシュの復元方法 #Git-Stash - Qiita

git stash drop実行時に、削除したコミットのSHA1が表示される。

そのSHA1をapplyで指定すれば、取り込める。

git stash apply [stash_hash]
リモート

gitの不要なブランチを消すコマンド #Git - Qiita

git fetch -p/--prune

リモートの削除済みブランチをローカルに同期する。

リモートの最新タグ

https:/stackoverflow.com/questions/20734181/how-to-get-list-of-latest-tags-in-remote-git

git ls-remote --tag --sort=taggerdate

date関係のsortはオブジェクトへのアクセスが必要なので、ローカルにないとダメとか。

https:/git-scm.com/docs/git-ls-remote.html

https:/stackoverflow.com/questions/10649814/get-last-git-tag-from-a-remote-repo-without-cloning

git rev-listでいけそう。

https:/gist.github.com/rponte/fdc0724dd984088606b0

差分ファイル抽出

情報源: gitで差分ファイルを抽出する #Git - Qiita

git archiveとgit diffを組み合わせる。

git archive --format=zip --prefix=root/ HEAD `git diff --diff-filter=d --name-only HEAD^ HEAD` -o archive.zip

ただし、この方法はファイル数がARG_MAX以下の場合だけ。ファイル数が多い場合だめ。

git diff --name-onlyで一覧を出力させて、1個ずつcp -pで階層を維持してコピーするしかないかも?

例:

mkdir -p archive
git diff --name-only new_base 44765_upgrade-base-version | xargs -i cp -p --parent "{}" archive/
core.autocrlf

warning: in the working copy of 'docker/README.md', LF will be replaced by CRLF the next time Git touches it

Windowsでは改行にCR+LFを使うが、mac/LinuxはLFのみ。これの違いの処理のための設定がcore.autoclrlf

  • true=コミット時にCRLFをLFに自動変換。チェックアウト時に逆。Windows向けの設定。
  • false=変換しない。
  • input=コミット時にCRLFをLFに自動変換のみ。mac/Linux向け。Windowsではチェックアウト時にCRLFになるが、mac/LinuxはLFになる。

わかりにくい。基本はfalseで良いと思われる。

gitkの文字化け対策

gitkのエンコーディングを設定する - Pistolfly

gitkはシステムのデフォルトエンコーディングで表示しようとするので、文字エンコーディングを指定しておく。

git config --global gui.encoding utf-8
ファイル名などの文字化け対策

Git for Windows で日本語を使いたい #Vim - Qiita

git config --global core.quotepath false
git config --global gui.encoding utf-8
改名と修正

改名と修正を同時にすると、改名を検知できない。

-Mオプションを指定すると、類似度で同時も検知できる。が、基本はリネーム・改名と修正は別コミットにしたほうがよさそう。

差分無視

git diffの--ignoreオプションにおけるスペース、タブ、改行の扱いを理解する #Git - Qiita

-wでインデント違いを無視してくれる。

squash

squashすると、squash対象コミットが、対象の直前のコミットに含められる。

gitignore

Git - gitignore Documentation

Format

記述方法を整理する。

  • 空行は無視。
  • #始まりの行はコメント扱い。
  • 終端スペースは無視。
  • !接頭辞はパターン否定。つまり、除外ではなく含める。以前除外された一致を再び含める。ただし、親ディレクトリーが除外されている場合、以下のファイルは含められない。パフォーマンス上の理由。順番に注意する。
  • /はディレクトリー区切りとして使用。先頭、中間、末尾で登場する。
    • 先頭と中間の/は相対パスを意味する。
    • それ以外、末尾の/と/なしの場合、現在以下のディレクトリーにもマッチする。
    • 末尾が/で終わる場合、ディレクトリーのみに一致。/がない場合、ディレクトリーとファイルの両方に一致。
  • *は/以外にマッチ。?は/以外の任意の1文字にマッチ。[a-zA-Z] の範囲記法も使用可能。fnmatch(3) FNM_PATHNAMEフラグのパス名展開に準じる。
  • **は特殊な意味がある。
    • **/=全ディレクトリー。**/fooは配下の全fooにマッチ。**/foo/barはfoo以下の全barにマッチ。
    • /**=配下のすべてにマッチ。
    • a/**/b=a/b a/x/b a/x/y/bのすべてにマッチ。

後は特に明記がないが、上から順番に評価されて、最後のマッチが優先されるので、記述の順番に注意する。

反転の!と/の扱いに特に注意が必要。

先頭スラッシュをつけないと、再帰的になる。

    $ cat .gitignore 
    # ディレクトリ foo/bar 以外のすべてを除外
    /* 
    !/foo 
    /foo/* 
    !/foo/bar
空ディレクトリーの維持

How do I add an empty directory to a Git repository? - Stack Overflow

gitは空ディレクトリーを履歴管理できない。何かファイルが必要。

logなど維持したい空ディレクトリーに、以下の内容の.gitignoreを置く。

!.gitignore

.gitignore以外を無視する。これで.gitignoreのみがあるので管理できる。

指定ファイルのみ除外
*
!.gitignore

ディレクトリーを残す以外 (.gitignore1ファイル以外) に、サンプルファイルなど複数ファイルを残したい場合は、上記のように*で最初に全部除外して指定ファイルのみ含める。/は必要に応じてつける。

gitattributes

Git - gitattributes Documentation

gitignoreに似ていて、パターンにマッチしたパスに対する設定を行える。

  • text
  • eol
  • working-tree-encoding
  • ident
  • filter
  • diff
  • merge
  • conflict-marker-size
  • whitespace
  • export-ignore: git archiveなどに含めないことをマーク。
  • export-subst
  • delta
  • encoding
ファイルのインデックスのみ削除

git rmは単独だと、gitの履歴とローカルファイルからも削除する。追跡対象から削除のみで、ローカルファイルとして残したい場合、--cachedを指定する。

git rm --cached

gitk

problem

ブランチ名が長いと、右クリックしにくい

Other

他のブランチとの同一化
git diff HEAD master | patch -p 1

patchの他にgit applyでもいい。

.netrc

https://social.senooken.jp/conversation/1573147#notice-2217499

Gitのパスワード入力の省略方法に~/.netrcがある。

しかし、man netrcするとわかるけど、これはもともとFTPのためのもの。なぜGitで使えるんだ?Gitの文書で言及がない。

In conversation Thursday, 21-Feb-2019 10:58:47 JST from web permalink

せのお (妹尾 賢)せのお (妹尾 賢) in reply to

理由が分かった。

1. Gitはhttpとhttpsの通信にcURLを使っている。

https://github.com/git/git/blob/master/INSTALL#L141

2. cURLが.netrcにも対応しているから。

https://ec.haxx.se/usingcurl-netrc.html

GitHub

Account

Username may only contain alphanumeric characters or single hyphens, and cannot begin or end with a hyphen.

ユーザー名は、英数字と-のみが使用可能。

組織別にアカウントを分けるなら、かぶらないように末尾に-組織名のようなサフィックスがあるとよいだろう。

Fossil

外部依存を排除しており、CGIでも動作するという点が非常に良い。気になる。Phorgeの検討が不要になる。

Phorge

Home

PhorgeはPhabricatorのフォーク。

About

Introduction

◉ Introduction

以下が主な機能。

  • コードレビューツール=Differential
  • リポジトリーブラウザー=Diffusion
  • バグトラッカー=Maniphest
  • ウィキ=Phiriction

GitHubの自己ホスト。

Phabricator

Phabricator - Wikipedia

PhabricatorはもともとFacebook社内のBTSシステム。PHP製。2021-06-01に開発終了。

主なユーザー。

  • AngularJS
  • Discord
  • Facebook

Install

◉ Installation Guide

Self Host with IPv6rs - IPv6 Provider - How to Install Phorge on Ubuntu Server Latest

Requirement

LAMP環境で動作する。

共用ホストでも動作するが、一部機能しない。通常コンピューターを推奨している。

  • MySQL: 5.5以上。
  • PHP 7.2以上
  • git: 2.5.0以上。
  • PHP extension: mbstring, iconv, mysql (or mysqli), curl, pcntl

ドメインはサブディレクトリーはだめで、サブドメインじゃないとダメ。

Download

以下のコマンドで取得する。

$ cd somewhere/ # pick some install directory
somewhere/ $ git clone https://we.phorge.it/source/arcanist.git
somewhere/ $ git clone https://we.phorge.it/source/phorge.git

gitの設定。

$ sudo git config --system --add safe.directory somewhere/arcanist
$ sudo git config --system --add safe.directory somewhere/phorge

phorge用のDBを作っておく。

cp /var/www/html/phorge/phabricator/conf/local/local.json.example /var/www/html/phorge/phabricator/conf/local/local.json
"mysql.host": "localhost", "mysql.user": "phorge", "mysql.pass": "password", "mysql.port": 3306, "mysql.charset": "utf8", "mysql.database": "phorgedb"

後は開くだけ。

Config

◉ Configuration Guide

以下のコマンドでユーザーを認識させる。

phorge/ $ ./bin/storage upgrade --user <user> --password <password>

Diffusion

Hosting

◉ Diffusion User Guide: Repository Hosting

Shell

Shell Command Language

Compound Commands

Shell Command Language

Case Conditional Construct
case word in
    [(]pattern1) compound-list;;
    [[(]pattern[ | pattern] ... ) compound-list;;] ...
    [[(]pattern[ | pattern] ... ) compound-list]
esac
  • 未マッチで終了ステータス0。
  • pattern部分: シェル展開が有効。他はglob。
  • |でOR検索相当。
  • 最後のパターンの;;は省略可能。if文のようにも使える。
  • 全パターンの捕捉は最後に*。空でもマッチする。?は最低1文字必要。

BREでは未対応な|のORマッチに対応しているのが最大の特徴。文法なのでコマンドを実行せず早い。grepを使わずにできるだけこちらを使ったほうがいい。

ワイルドカード

ワイルドカードで.始まりのファイルをマッチさせたい。

以下ならマッチするが、ブレース展開 (brace expansion) はPOSIX shでは使えなかった気がする。

echo {.*,*}

BOM

unicode - Adding BOM to UTF-8 files - Stack Overflow

ExcelでUTF-8ファイルを開けるように、UTF-8のBOMをファイルにつけたい。

printf '\xEF\xBB\xBF' > with_bom.txt

上記コードでBOMを最初に書き込んで、後は追記する。

awk

The Open Group Base Specifications Issue 7

変数

特別
  • NF: 列数。列の全表示などで使う基本的で重要な変数。
  • NR: 行番号。
スコープ

変数のスコープ

関数の仮引数のみ、ローカル変数扱いで、それ以外はグローバル変数。

文/statement

  • actions
    • if/else
    • while/do...while/for
    • break/continue
    • delete
    • next
    • exit
  • output
    • print
    • printf

関数

組込関数
  • Arithmetic
    • atan2
    • cos
    • sin
    • exp
    • log
    • sqrt
    • int
    • rand
    • srand
  • String
    • gsub
    • index
    • length
    • match
    • split
    • sprintf
    • sub
    • substr
    • tolower
    • toupper
  • I/O
    • close
    • getline
    • system

print/printfは関数ではなく、statement/文扱い。

ヘッダー出力、列別最大長さ出力。

awk -F, '{if(NR==1) print $0} {for(i=1; i<=NF; ++i){if (line[i] < length($i)) line[i] = length($i)}} END {for (i=1; i<=NF; ++i) {printf line[i]","}}' data/101542.csv

CSV

シェルスクリプトの実験のために作った POSIX 準拠 awk 実装の CSVパーサー (RFC4180対応) #ShellScript - Qiita

# csvparser.awk

## Usage
# awk -f csvparser.awk data.csv

# CSV の論理的な一行毎に呼び出されるコールバック関数(サンプル)
# row: 行番号(最初の行は1) len: フィールド数 fields: フィールドデータ
function callback(row, len, fields,  col, field) {
    for ( col = 1; col <= len; col++ ) {
        field = fields[col]
        gsub(/\\/, "&&", field)  # \ は \\ にエスケープする
        gsub(/\n/, "\\n", field) # 改行は \n にエスケープする
        print row ":" col " " field
    }
}

BEGIN { row = max_idx = 0 }
{
    idx = 0
    sub(/\r$/, "")
    while ($0 != "") {
        if (match($0, /^(["]([^"]|["]["])*["]|[^,"]*)(,|$)/)) {
            fields[++idx] = ""
        } else if (match($0, /^["]/)) {
            fields[++idx] = substr($0, 2)
            for (;;) {
                if (getline == 0) exit 1
                sub(/\r$/, "")
                if (match($0, /^([^"]|["]["])*["](,|$)/)) break
                gsub(/["]["]/, "\"")
                fields[idx] = fields[idx] "\n" $0
            }
            fields[idx] = fields[idx] "\n"
        } else {
            exit 1
        }
        field = substr($0, RSTART, RLENGTH)
        $0 = substr($0, RSTART + RLENGTH)
        lastcomma = sub(/,$/, "", field) > 0
        gsub(/^["]|["]$/, "", field) && gsub(/["]["]/, "\"", field)
        fields[idx] = fields[idx] field
    }
    if (lastcomma) fields[++idx] = ""
    while (idx < max_idx) delete fields[max_idx--]
    callback(++row, idx, fields)
    max_idx = idx
}

awkのCSVパーサー。先頭のBOMはあると認識できないので、tail -c +4でBOMを除外して使う。

tail -c +4 data/101543.csv | awk -f csvparser.awk 

Other

binary

POSIX準拠のシェルスクリプトでバイナリデータを扱う #Bash - Qiita

バイナリーデータの読込はodコマンド。なければhexdump。

書込はprintf。

head/tailの-cはPOSIXで使えたか?

cmd.exe

Control block

for

あくまでコマンド。

nest

ネストはできない。二重ループしたければ、関数にしてそれを呼び出す。

bitsadmin

Windowsでのファイルダウンロードコマンド

Windows 7以降ではbitsadminコマンドがあり、これがwget相当となる。

書式:

bitsadmin /transfer <job name> <URL> <output path>

<job name>と<output path>は必須なので注意する。

certutil

Windowsでのハッシュの確認に使える。

certutil -hashfile file
SHA1 ハッシュ (対象 C:\moconavi\windows\Moconavi\ext\chromium\moconavium.exe):
e0da85b04b6970ac1f0c33db7a9ad607fdbd44eb
CertUtil: -hashfile コマンドは正常に完了しました。

rlogin.cmd

コマンドキーの送信を自動化できる?

rem rlogin.cmd

@Echo off
Set SERVER=192.168.0.0
Set USERNAME=
Set PASSWORD=

Cmdkey /generic:TERMSRV/%SERVER% /user:%USERNAME% /pass:%PASSWORD%
Start mstsc /v:%SERVER%
Timeout 5
Cmdkey /delete:TERMSRV/%SERVER%

実行中プロセスのパスの確認

出典: Show EXE file path of running processes on the command-line in Windows - Super User

wmic process get ProcessID,ExecutablePath
wmic process where "name='mysqld.exe'" get ProcessID, ExecutablePath
wmic process where "name='mysqld.exe'" get ProcessID, ExecutablePath /FORMAT:LIST

簡易編集モード/挿入モード

Windows 10のcmd.exeは [簡易編集モード] が有効になっており、コマンドプロンプトを左クリックすると、テキストの選択が始まる。テキスト選択中はコマンドの実行が止まる。長時間かかるコマンドの実行中に誤操作で止まると困るので、これは無効にしたほうがよい。

cmd.exeを起動-左上のアイコンをクリック-[規定値]/[プロパティ]-[オプション]-[□簡易編集モード] を選ぶ。

そのほか、 git log のような制御が移るコマンドを実行してしばらくすると、操作できなくなる。

[□挿入モード] にすると回避できる模様。

Web

URL

クエリー配列

やり方がいくつかある。

  1. CSV文字列で受取後分割: https://www.sakdor.net/test/?var=1,2,3 explode(",",$_GET[var]);
  2. 配列添字
    1. http://www.sakdor.net/test/?var%5B%5D=1&var%5B%5D=2&var%5B%5D=3
    2. http://www.sakdor.net/test/?var%5Ba%5D=1&var%5Bb%5D=2&var%5Bc%5D=3
    3. http:www.sakdor.net?var[0]=1&var[1]=2&var[2]=3

データが決まっているならcsvがシンプル。

HTTP

RFC 9110: HTTP Semantics

Content-Disposition

Content-Disposition - HTTP | MDN

RFC 6266 - Use of the Content-Disposition Header Field in the Hypertext Transfer Protocol (HTTP)

Content-Disposition: inline
Content-Disposition: attachment
Content-Disposition: attachment; filename="filename.jpg"

filenameでファイル名を指定する。ここの値は二重引用符で囲む。スペースを含む場合に必須になる。

multipart/form-data

rfc7578

ファイルアップロード用のMIME type。

リクエストヘッダー

Content-Type: multipart/form-data; boundary=--hogehoge

リクエストボディー

--hogehoge
Content-Disposition: form-data; name="user_name"
Content-Type: text/plain

test
--hogehoge
Content-Disposition: form-data; name="email"

sample@mail.com
--hogehoge
Content-Disposition: form-data; name="gender"

male
--hogehoge
Content-Disposition: form-data; name="user_profile" filename="image.jpeg"
Content-Type: image/jpeg

\xff\xd8\....
--hogehoge--

ヘッダーでmultipart/form-dataを明記して、ボディーでデータを指定する。

curlコマンドでPOSTする, 様々な形式別メモ |

curlでの送信理由。

-Fで送信データをname=data形式で指定する。ファイルの内容を指定する場合、@filenameで指定する。これを指定すると、リクエストボディーのfilename扱いにしてくれる模様。-Fを指定すると、-H 'Content-Type: multipart/form-data'が自動付与される。たぶん、-dと同様に-X POSTもつく。

curl -X POST -F file1=@/var/tmp/sample.jpg https://xxxxx.net/xxxxxx

データとテキストを同時送信したい場合、-Fで複数指定する。

curl -X POST -F 'age=30' -F file1=@/var/tmp/sample.jpg https://xxxxx.net/xxxxxx

curlだと上記のboundaryなどをうまくやってくれるのだと思う。

リクエストボディー全体をファイルデータにする場合。

curl -X POST -H 'Content-Type: image/jpeg' --data-binary @/var/tmp/sample.jpg https://xxxxx.net/xxxxxx

IP address

出典: 固定IPアドレスの取得方法 ~実は簡単!フリーランスの方も必見です~|VPN活用日記|トピックス|グローカルネットの快適VPN【公式】| 株式会社グローカルネット

自宅サーバーを行う際、固定IPアドレスが必要になる。

取得方法がいくつかある。

  • 契約しているプロバイダでオプションとして申し込む方法
  • 固定IPアドレスに対応しているSIMを契約する方法
  • VPNを利用した固定IPアドレスの提供会社を利用する方法

VPNの固定IPアドレスが安いらしい。ryoかsuwakoが解説していた気がする。

Authentication

認証方式がいくつかある。HTTPで定義される認証方式 (HTTP認証) が有名。

Basic認証

出典: Basic認証 - Wikipedia

Authorization HTTPヘッダーにBasicのあとに [username:password] をBASE64でエンコードして送信する認証方式。

GET /private/index.html HTTP/1.1
Host: example.com
Authorization: Basic cm9vdDpwYXNzd29yZA==

盗聴や改ざんが簡単だが、シンプルという利点がある。

OAuth

Ref

OAuth (オーオース) 権限の認可のための標準。OAuth 2.0が最新の標準。

以下が登場人物。

  • resource owner: あるサイトのユーザー。
  • resource server: あるサイトのユーザーのデータの保有サーバー。
  • clent: クライアントアプリ。リソースサーバーのデータを使用したい。
  • authorization server: クライアントにサイトへのアクセスを認証するサーバー。アクセストークンを発行して行う。

アクセストークンが実質的なパスワードのようなものだが、resource serverのパスワードを直接渡していない点が重要な違い。パスワードを直接渡さないことで、機能別に権限を細かく利用可否を制御できる。

処理の流れ。

  1. client->resource owner: Authorization Request。ここでユーザーが手操作でアクセスを承認する。
  2. client<-resource owner: Authorization Grant。
  3. client->authorization server: Authorization Grant。承認された情報でアクセストークンを要求。
  4. client<-authorization server: Access Token
  5. client->resource server: Access Token。アクセストークンでアクセス。
  6. client<-resource server: Access Token

Consumer Key/Secret: アプリ識別用のID/PW。

Access Token: サイトにアクセスするためのパスワード。

API

複数レコードの登録

複数レコードの登録・更新・削除のREST APIについて調べてみた話(+@ Graph API) - junode | 個人開発ブログ

既存のAPIは単一リソースの処理しかないことが多い。JavaScriptなどで単一リソースを何回も呼べばいいというのはそうだけど、JavaScriptなしでは動作しない。一括処理用のAPIを作るしかなくないか?

REST WebAPIのプラクティス | yamarkz.com

delete_bulkなどのような一括処理用のAPIを作るしかない。内部的には単一処理のAPIを作る感じだったとしても。

パラメーター

json - REST API Best practices: args in query string vs in request body - Stack Overflow

パラメーターの指定に3種類ある。

  1. リクエストボディー
  2. クエリー
  3. パス

パスはIDなどを指定する場合だけわかりやすい。それ以外のオプションはクエリーのほうがいい。

ボディーは、通常サーバーのアップロード・ダウンロードデータとして使われる。クエリーはデータの指定に使う。

この原則に従うとシンプルだろう。

  • URIには長さの制限がある。
  • ボディー
    • 引数が非常に多い場合。
    • 画像などバイナリーデータ。
    • キー・値構造を持たない場合。
  • クエリー文字列
    • 引数を簡単に確認できる。
    • 共通の引数の場合。

検索機能のGET/POST

検索機能にGETとPOSTのどちらを使うか?という議論がある。

データ登録するわけなじゃないのだから、GETがいいんじゃない?

POSTだと、JSONをそのまま送れるので、複雑なケースに対応できる。特に、配列の送信が重要。

GETのほうが検索条件をブックマークにできたり、URLを共有できるので、基本は便利。

レート制限対策

いろいろ方法がある。

  • cronなどでデータをサーバー上 (DBなど) に定期保存して、保存データを表示させる。
  • 配列を利用して、1回のリクエストでまとめて取得する。
  • インターバルを設ける。
  • HTTP 429/413を検知して、リトライする。

指数関数的バックオフ

wait_interval = base * 2^n +/- jitter
  • wait_interval は、API が HTTP 429 で応答した場合に、システムがリクエストを再試行するまでの時間となります。
  • base は最初の間隔、つまり最初の再試行までの待ち時間です。この値には3000msを使用することをお勧めします。
  • n は、現在の呼び出しの前にリクエストが通らなかった数です。複数のスレッドやプロセスを使用して並行してAPIを呼び出している場合、nの値は現在のスレッド/プロセスにスコープされます。この値は、現在のスレッド/プロセスが、最後に成功した応答から何回 429 "Too Many Requests" エラーに遭遇したかを表します。
  • jitter は 0 から base の間の乱数です。これは、複数のスレッド/プロセスが全く同時にAPIを呼び出さないように、リクエストを少しずつ分散させるために使用されます。システムが待機するたびに、この乱数値を再計算し wait_interval の合計に加算するか減算するか、ランダムで選択してください。

curl

HTTPの通信のコマンドラインでの確認でよく使う。

Basic

curl - Tutorial

  • -X: メソッド指定
  • -d/--data-urlencode: リクエストボディー (key=value)を指定。-X POSTも自動指定になる。
curl -H "Content-Type: application/json" -d '{"name":"佐藤", "mail":"sato@example.com"}' localhost:5000/api/v1/users

JSONで送信する場合、ヘッダー指定が必須。

*-F: multipart/formのform指定。

curl -F "coolfiles=@fil1.gif;type=image/gif,fil2.txt,fil3.html"
  http://www.example.com/postit.cgi

@でfilename相当の指定。;でmime typeも指定できる。

@/</;type=自体を送信したい場合、-Fではなく、--form-stringを指定する。

curl: (60) SSL certificate problem: self-signed certificate

Ref: curlで「自己署名証明書」を受け入れるには【curl: (60) SSL certificate problem: self signed certificate】 | LFI.

--insecureオプションを指定すると、localhostなどでの自己署名証明書を許可する。

curl: Failed writing body

pipe - Right After piping to "head"/"tail": "curl: (23) Failure writing output to destination" - Ask Ubuntu

以下のようにhead -n 1を指定するとcurlがエラーを出力する。

curl -H "Content-Type: application/json; charset=utf-8" -H "X-HD-apitoken:$TOKEN"         -d "{\"dbSchemaId\":$dbSchemaId, \"limit\":1, \"offset\":$offset}"         https://$DOMAIN/$ACCOUNT/api/csvexport/version/1.0 | head -n 1
curl: Failed writing body

curlは標準出力に全部書き込めたかチェックしているようで、head -n 1で切り捨てたらcurlはエラーになる。

対策は、curl -sで出力を抑制するとのこと。これで解決。

Wireshark

TLS

Ref: SSL/TLSの復号#1 ~Wiresharkの設定~ | 東陽テクニカ | “はかる”技術で未来を創る | ワン・テクノロジーズ・カンパニー.

Wiresharkで通信パケットを確認する場合、デフォルトでTLSで暗号化されているので、内容がわからない。WiresharkでTLSに対応しておく必要がある。

[Preferences]-[Protocols]-[TCP] を選ぶ。

  • ☑Allow subdissector to reassemble TCP stream
  • ☑Reassemble out-of-order semgemnts

上記をチェックしておく。デフォルトでチェックされていた。

続いて、セッションごとのPre-Master Secretを登録する。

Chrome/Firefoxだと、環境変数SSLKEYLOGFILEを設定すれば、このファイルにTLSセッションキーを出力するので、これをWiresharkで読み込むことで、復号対応する。

以下のコマンド相当で、任意のファイル・場所にログファイルを指定する。

export SSLKEYLOGFILE=/tmp/sslkey.log

Macだとlaunchctlで設定しておくといい。これでWebブラウザー経由の場合は見えるようになる。

Security

DoS攻撃

いくつか対策方法がある。

サーバーログにIPアドレスが残るから、それで攻撃元の国を特定して、該当国を一括アクセス拒否。これが効果あるかもしれない。

攻撃元の国は途上国とかが多いだろうから。IPアドレスは簡単に変更できるが、国を変えるのはたいへんだろう。

バリデーションの実装

基本的に、バックエンドで主にチェックして、フロントエンドはUXの向上目的で実装する。データの重複チェックはDBアクセスが必要だったりするから。また、API経由などフロントがそもそもないケースもある。

ただ、社内システムのような、画面経由でしか使わない。悪者がほぼいないと思われるケースは、フロントエンドでの検証だけでも十分に感じる。

二重送信

submitボタンのダブルクリック、リロード、ブラウザーバック・フォワードなど、フォーム周りで注意が必要な保安要素がある。

  1. ボタン連打
  2. ブラウザーバック
  3. リロード (PRG)

項目ごとにすべき対策が異なる。

連打

基本は、ボタンのsubmitのイベント内でdisabled=trueでの無効化。

似た考え方で、スプラッシュのモーダル表示もあり。これがわかりやすいかもしれない。

$("form").submit(function() {
  var self = this;
  $(":submit", self).prop("disabled", true);
  setTimeout(function() {
    $(":submit", self).prop("disabled", false);
  }, 10000);
});

停止にしたら、二度通せなくなるので、タイムアウトで戻すとよい。

Browser

Chromium

Extension

Chromme系で愛用拡張機能を列挙する。

devtool/開発者ツール

イベントリスナー

要素に設定されているイベントを調べよう - ゆずめも

[Elements]-[Event Listeners]-[handler]-右クリック-[Show function definition] でイベントリスナー関数の定義を確認できる。

イベント監視

How to find out which JavaScript events fired? - Stack Overflow

monitorEvent関数で監視できるらしい。他に、FirefoxのFirebugのlog eventsでも監視できるらしい。

Other

Windows Safari

一応ある。2012-05-09のSafari 5.1.7までWindows版が提供されていた。DL1531。

Other

Tool

いくつかWeb関係の開発で役立つツール集を公開しているサイトがある。

localhost

RFC 6761 で規定。RFC 2606で予約。DNSに登録されることはないため、テスト目的で使用可能。ループバック (送信元にそのまま返す) インターフェイス。

IPv4=127.0.0.1/IPv6=::1とされている。

Shared Host

Free

無料で使用可能な共用ホスティングサービスがある。

スタードメイン無料サーバー

ドメインをセットで利用する必要があるものの、スタードメインのスタードメイン無料サーバーがけっこういい。

無料レンタルサーバー | スタードメイン - ドメイン取得 100円(税込)~

jpドメインの金額が相場の中では安い方で、それに無料サーバーがついていくる点。

  • ディスク容量 20GB
  • DB 1GB

ただし、SSHやコマンドは使えないので、FTPでWordPressを展開して設置するとか、そういう簡単な使い方だけ。ただ、それでもWordPressでWebサイトを構築するくらいなら十分だと思う。

CORESERVER

メール

情報

ルールが特殊なので注意する。

ゴミ箱に振り分ける場合。

順1 で[./.Trash] を指定

順2

  • 条件:  [.*]
  • 処理:  ./、に振り分ける

条件部分には正規表現が使えるように見える。

破棄にしないといけない。転送する場合、カスタムフィルターの中に転送を入れる。条件を.*にする。

カスタムフィルターにくせがある。

  • エスケープ(\を前置する)が必要な文字は「'」「"」「|」「`」「~」「?」「!」

Value Domain ネットde診断 byGMO

2024-06-07 Friからバリュードメイン系の利用者に無料で提供しているセキュリティー診断ツール。

Analytics

Exam

## About

https://gnusocial.jp/notice/4506679

### 全般

- マーケティング・ビジネス実務検定

- IMA検定

- Web検定

- ネットマーケティング検定

### 解析系

- ウェブ解析士

- GAIQ

- 統計検定

- Webアナリスト検定

GAIQが無料だしどうせ使うからいいかな。

https://wacul-ai.com/blog/access-analysis/google-analytics-method/gaiq/

https://www.plan-b.co.jp/blog/seo/12792/

## URL

- https://ceres-inc.jp/business-tips/recommended-webmarketing-shikaku/

- https://mynavi-creator.jp/blog/article/qualification-for-web-marketer

- https://www.icloud.co.jp/article/exam/features-and-5-acquisition-benefits.html

- https://digitor.jp/textbook/web-analytical-qualification/

Tool

サイト分析用のツールがいくつかある (2023年ブログランキング!おすすめブログランキングサイト比較【一般人向け】)。

  • SimilarWeb
  • Ubersuggest
  • ahrefs
  • Googleキーワードプランナー

閲覧数取得

出典: GoogleAnalyticsで自サイトの人気記事ランキングを表示する方法 | アフィリエイトJAPAN

  • [行動]-[サイトコンテンツ]-[全てのページ]
  • [表示する行数]=5000
  • [エクスポート]=TSV

流入元特定

会員登録画面の流入元探索方法について - Google アナリティクス コミュニティ」どのページから会員登録があったか、会員登録に結びつく記事は非常に重要。

こんにちは。

探索レポートでユーザーセグメントを作成する集計方法はいかがでしょうか。

・自由形式レポートを作成

・セグメント作成 > ユーザーセグメント

・条件は page_view > パラメータ page_location > 含む:会員登録画面のURL を指定

・「会員登録画面閲覧ユーザー」などセグメント名をセットして保存

・探索レポートにセグメントを適用

・ディメンション:セッションの参照元 / メディア、ランディング ページ + クエリ文字列

・指標:セッション

ご確認よろしくお願いいたします。

※ページ閲覧の発生しなかったセッションはランディングページが (not set)になります。

 開きっぱなしのタブから再訪問するセッションなどが該当します。ご参考までに。

PMProでも似たような回答。

Google Analytics 4 can track ecommerce conversions and then assign page value to posts that were a part of their conversion path for that engaged session.

Server

httpd

Apache HTTP Server

Access Control

出典: Access Control - Apache HTTP Server Version 2.4

DoS攻撃対策などで重要な設定。

mod_authz_core/mod_authz_hostがコアモジュール。mod_rewriteも関係ある。

基本構文は以下。

Require host <address>
Require ip <ip address>

1番目の形式はドメイン名。2番目はIPアドレス。部分マッチする。マッチしたもののアクセスを許可する。

Requireの直後にnotを指定してアクセス禁止にできる。こちらが重要。

E-mail

[サーバーIPがブラックリストに載ってメール送信エラーになるのを解除する方法]

MailHog: Go言語製のメールサーバーソフト。

Debian

PHP8

[How To Install PHP 8.0 on Debian 11/10/9 | ComputingForGeeks](https://computingforgeeks.com/how-to-install-php-on-debian-linux/)

Debian 11の場合、PHP 8には外部リポジトリーが必要なので追加する。

sudo apt update

sudo apt install -y lsb-release ca-certificates apt-transport-https software-properties-common gnupg2

PHPパッケージを追加する。

echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/sury-php.list

wget -qO - https://packages.sury.org/php/apt.gpg | sudo apt-key add -

sudo apt update

これでPHP8を参照できるので、インストールする。

sudo apt install php8.2

[How to Switch between Multiple PHP Version on Debian 12/11/10 – TecAdmin](https://tecadmin.net/switch-between-multiple-php-version-on-debian/)

インストールしたら、PHPのバージョンを切り替える。

a2dismod php7.4

a2enmod php8.2

sudo systemctl restart apache2

php 8.2にするとこういうエラー。

[Sat Sep 02 11:31:02.558029 2023] [php:error] [pid 25644] [client 133.106.38.37:57181] PHP Fatal error:  Uncaught Error: Undefined constant "DB_DATAOBJECT_ERROR_NODATA" in /var/www/gnusocial/public/index.php:104\nStack trace:\n#0 [internal function]: handleError()\n#1 {main}\n  thrown in /var/www/gnusocial/public/index.php on line 104

念のためdockerで起動を試みましたが、同じくトップ画面を開くと同じエラーになります。

<https://notabug.org/gnusocialjp/gnusocial/src/main/docker/development> にDockerでの起動方法があります。`docker compose up -d` を実行するだけでlocalhostでアクセスできます。

私とあなたとの環境の違いを排除したいので、dockerのインストールだけ頑張って、それでdockerでも簡単に動作確認してくれませんか?

alternative

Ref: DebianAlternatives - Debian Wiki.

OS内でバージョン違いのプログラムを管理するための仕組みがある。それがupdate-alternativesコマンド。

sudo update-alternatives --display vi
sudo update-alternatives --config vi

オプションとコマンド名を指定することで、現在の実体と更新ができる。

XAMPP

ポート番号変更

Xamppでポート競合を防ぐ方法 #PHP - Qiita

XAMPP Control PanelのConfigから変更可能。

phpmyadminはConfigのphpmyadminで、Servers.portを追加する。

Vim

Other

Async

https:/github.com/skywind3000/asyncrun.vim

asyncrun.vimは1個のバックグラウンド処理しか対応していない。

https://github.com/skywind3000/asyncrun.vim/issues/12

vim-dispatchならいけるのか?

Binary

vim-jp » Hack #133: バイナリファイルを編集する

grep

非同期でgrepする方法。

https://superuser.com/questions/861783/how-to-run-a-grep-in-vim-asynchronously

https://www.reddit.com/r/vim/comments/5ses2e/async_grep_in_vim_8/

Vim 8の非同期APIはプラグイン用。

* https://github.com/mhinz/vim-grepper

* https://github.com/skywind3000/asyncrun.vim

* https://github.com/tpope/vim-dispatch

https://wonderwall.hatenablog.com/entry/2017/10/09/210000

asyncrun.vimでやるのがよさそう。

AnsiEsc

* https:/unix.stackexchange.com/questions/444226/how-to-make-vim-interpret-escaped-characters-as-colors

* https:/superuser.com/questions/358409/how-can-i-tell-vim-to-show-ansi-escape-codes-properly

本家は太字に対応していないのでこちらがいいかな。

- https:/github.com/powerman/vim-plugin-AnsiEsc

ただし、こちらはgvimでクリック時にカーソル位置がずれる。

program

C

ワシのVimプラグインは百八式まであるぞ - daisuzu's notes

【C/C++】

     87. a.vim

        C/C++のヘッダとソースを切り替えます。

     88. c.vim

        C/C++のテンプレートやイディオムの入力をサポートしてくれます。

     89. CCTree

        cscopeを使って関数のコールグラフを表示してくれます。

     90. Source-Explorer-srcexpl.vim

        ソース解析ツール、Source InsightのVim版です。

     91. trinity.vim

        taglist, srcexpl, nerdtreeを同時に起動して

        VimがIDE画面のような画面になります。

     92. cscope-menu

        cscope用のメニューを表示してくれます。

     93. gtags.vim

        gtagsを使ってファイルを開けます。

     94. DoxygenToolkit.vim

        Doxygenコメントの入力をサポートしてくれます。

Visual Studio Code

Keybind

矩形選択

Ref: VS Codeの矩形選択と矩形貼付の操作方法 - mito’s blog.

  • s-alt-クリック
  • c-s-alt-矢印

ジャンプ

  • 括弧ジャンプ: C-S-\

Config

Default terminal

Ref: bash - Change the default terminal in Visual Studio Code - Stack Overflow.

[F1]-[Terminal: Select Default Profile]

cscope

cscope用のプラグインが何個かある。

scope4codeのほうがいろいろできそうだが、うまく動作しなかった。使い方がよくわからない。

cscope-codeはシンプルだが動作した。こちらを当分使うことにする。

Macの場合、control-. sのように、control-.の後に、controlを話してsを押すと発動する。カーソル下のシンボルしか使えない感じなのがネック。まあいい。

Vim

VSCodedでVimのキー操作を使うためのプラグイン。これが一番人気。いや、Vimのエミューレーターは中途半端な感じだから使わないほうがいいかな。

Extension

CSS

Tailwind CSS IntelliSense

PHP

Laravel Blade Snippets

PHP Intelephense

Ref: PHP Intelephense - Visual Studio Marketplace.

VSCodeのPHPの補完拡張として人気が高い。

Quick Start

設置後、しておくべき設定がある。

  • Go to Extensions.
  • Search for @builtin php
  • Disable PHP Language Features. Leave PHP Language Basics enabled for syntax highlighting.

VSCodeの [PHP Language Features] を無効にしておくとのこと。

後は、.php以外の拡張子でPHPファイルがあれば、関連付けを追加するとか。

Module

peclなどPHPの標準モジュールで一部認識できないものがある。

php - Undefined type 'Imagick' in VSCode's intelephense - Stack Overflow」にあるように、そういう場合は [Settings]-[Stubs] で追加するとよい。

Coding

Ref: VSCode で PHP 開発するならインテリセンス最強の intelephense を使おう | 株式会社ビヨンド.

intelephenseでコード補完を認識しやすい書き方というのがある。

まず、型をつけられるものはつける。

function superMethod()
{
    /** @var AwesomeService $awesomeService */
    $awesomeService = $this->app->make(AwesomeService::class);
    $awesomeService->awesomeMethod();
}

ローカル変数も型名を指定する。これをしないと、インスタンスでコード補完が効かない。

PIM

Personal Information Manager - Wikipedia

PIMという個人情報管理用アプリの分類がある。

  • カレンダー
  • アドレス帳
  • 電子メール
  • タスク管理
  • メモ帳
  • 音声メモ
  • 電卓
  • 時計
  • 電子辞書

E-mail

General

Naming
RFC
  • webmaster
  • support
  • info
  • service
  • pr
  • billing
  • 氏名

売上をアップするメールアドレス、商機を失うメールアドレス | マイナビニュース

infoやwebmasterなど企業サイトが備えるべきメールボックスのルール、ご存じですか? | 編集長ブログ―安田英久 | Web担当者Forum

rfc-jp.nic.ad.jp/rfc-jp/RFC2142-JP.txt

SuperTAINS News No.23 [Page.5]

【Mail】メールアドレス作成のガイドライン(RFC2142) – fumidzuki

公開用のメールアドレス。何にしようか考えていた。

RFC 2142でいくつか推奨されている。

info@ support@ answer@ inquery@ contact@ pubic@

contact@がやっぱり一番しっくりくる。info@ support@はRFC 2142にあるけど,これはビジネスより,サービスに紐付いたもの。個人でやる分にはサービス関係ないから,これは違う。publicも悪くはないのだけど,あまり一般的ではないか。

develop

GNU social JP管理人 (gnusocialjp@gnusocial.jp)'s status on Saturday, 08-Oct-2022 23:13:28 JSTGNU social JP管理人GNU social JP管理人
使用するメールアドレスに悩みます。GitのメールアドレスはGitのホスティングサービスに掲載され一般公開されます。

メーリングリストのメールアドレスも、返信方法によって引用されアーカイブで一般公開されます。

どう使い分けるのがよいでしょうか?案↓
GNU social JP管理人 (gnusocialjp@gnusocial.jp)'s status on Saturday, 08-Oct-2022 23:20:04 JSTGNU social JP管理人GNU social JP管理人
  1. develop@domainのようなアドレスで共有
  2. develop@, ml@ で用途別
  3. contact@ で一般公開用で共有
開発用のメールなので、1がいいですかね。仮に漏洩しても開発関係経由というのがわかるので。

1がいいと思う。

category

目的に応じて使い分けたほうがよさそう。

メールアドレスを何個ぐらい使い分けたら安全・快適に過ごせるのか - Dr.ウーパのコンピュータ備忘録

メールアドレス流出時の被害防止

不審なメールの検知

必要な数

  • 銀行・証券会社
  • 知り合い
  • ショッピングサイト

その他

  • Webサイトなどの公開用
  • 本名でのやり取り
  • ニックネーム
  • 金銭のやり取りのないサービス登録
  • 金銭のやり取りのあるサービス登録
  • 登録にメールアドレスが必要だけど,そんなに使っていないメール

メールアドレスの種類

  • フリーメール
  • プロバイダーメール
  • 独自ドメイン

メールアドレスの種類とアフィリエイトにおける3つの使い分け方法 | アフィリエイト

  • サービス登録用
  • メルマガ購読用(捨てアド)
  • メインアドレス

メールアドレスの使い分けかた(前編) - 学習する機械、学習しない人間

メールアドレスの使い分けかた(後編) - 学習する機械、学習しない人間

これらを考えてどういう名前で何個用意するかを考える。

とりあえずメインで使うmainというアドレスを一つ用意する。残りをどうするか。

Webサイト公開用にcontact

  • main: メインで使うメール。人に直接教えるときや,お金が絡む場合,ショッピングサイトなど実名が求められるような重要な内容にはこれ。こちらから送信するときもこれ。相手の顔が見えているとき。
  • contact:受信専用,公開用。問い合わせ用。なんかフォーラムやブログのコメント欄やcontact usなどにこちらから問い合わせる時なども。相手の顔が見えないときなど。
  • service: 基本的に受信専用,たまに返信。Webサービス登録用。
  • recruit:就職活動用。就職サイトとか転職エージェント,企業とやりとりするときはけっこうメール来るから。
  • job: 個人事業、仕事用、不動産は事業なのでこちら。
  • money: 金融機関登録用。銀行、証券会社、クレジットカード会社、決済会社・サービス。
  • shop/store: ショッピングサイト、個人間売買サイト。
  • ユーザー名: メールアドレスの@以前はユーザー名とみなされることがあるので、ユーザー名のアドレスも用意しておくとよさそうだ。


こちらから送信するときのメールアドレス。

Webサービスに登録するときどうするか。不動産屋さんとか人に教えるときはどうするか。アフィリエイトとかドメインとか実名が求められるときはどうするか。

gmailの+を考える。gmailでは+や.をつけると無限にアドレスをつけられる。ただし,受信は+のないメール。

ただし,gmailの+は使えないときがある。@以前の部分をユーザー名とみなして,+を無効な文字とみなすサービスがある模様。

ネットではがきが印刷~郵送できるポスコミ【1枚から注文OK】

https://www.tomtop.com/もだめ。

今まで使ってきたメールとはどうやりくりするか。

Thunderbirdでやる場合,Archiveするときに既読とメールのコピーを行う。

他のアドレスのメールはmainに転送するようにしておいて,mainのメールアドレスで確認。

最終的にThunderbirdでArchiveを実行したら,宛先のメールのフォルダーに同じ内容が既読状態でコピーされることにする。

このようなフィルターを作っておく。受信時にコピーしてしまうと,未読状態でコピーされてしまうか,受信した瞬間に既読状態になってしまい,見逃す可能性が高い。

Manage Identitiesで返信時に受信したアドレスで返信できるように登録しておく。

Mozilla Thunderbird

プロファイルの統合

ImportExportToolsでデータ移行するというのが手堅い。一括操作を念頭に置いた機能になっている。数が少ないならば、emlファイルをドラッグドロップで取り込むこともできる。