「Develop」の版間の差分

提供:senooken JP Wiki
(Algorithm 再帰処理)
 
(同じ利用者による、間の90版が非表示)
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: ページ。テンプレートを使用したページ。


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


後ろからマッチ。cが置換対象。
==== 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 サポート]


/[^c]*$/: cより右端
Skyepで使用可能な絵文字の一覧。


=== glob ===
== Tool ==


* [https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/functions/glob.html glob]
=== General ===
* [https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/utilities/V3_chap02.html#tag_18_13 Shell Command Language]
 
==== Call tree ====
kcachegrindだったかな。


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


使用可能な記号は以下3個。以下の3文字は\でエスケープできる。
Doxygen+GraphVizで関数コールグラフ


* ?: 任意の1文字にマッチ。
==== kscope ====
* *: 任意の0以上の文字にマッチ。
https:/github.com/ivan0124/Linux-programming/wiki/How-to-use-KScope-to-trace-code
* [: []内の1文字にマッチ。正規表現の各括弧と同じ。ただし、先頭の否定が^ではなく、!。


ファイル名マッチ時には、追加で特殊なルールがある。
https:/sourceforge.net/projects/kscope/


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


globで.ファイルを含めたい場合、工夫が必要 ([https://www.php.net/manual/ja/function.glob.php PHP: glob - Manual])。
==== cscope ====
.[!.]* *
cbrowser/kbrowserというGUIもある。
上記のように.ファイルのマッチとそれ以外を指定する必要がある。


<code>.[!.]*</code> は、<code>.</code>と<code>..</code>以外の.ファイルにマッチする。
cscopeの大文字小文字無視検索


<code>.*</code>を指定すると、<code>.</code>/<code>..</code>がマッチするので注意する。最近のシェルは、シェル側で気を利かせているようで、<code>.*</code>だと<code>.</code> /<code>..</code>はマッチしない。
<nowiki>http://vim.1045645.n5.nabble.com/how-to-search-with-cscope-ignoring-case-td5715043.html</nowiki>


=== 引用符のネスト ===
DBを別にする必要がありそう。
シェルやプログラミング言語で、文字列リテラルの表現などで、一重引用符'と二重引用符"を使う。


JSON作成や変数展開などで、これらをネストさせたいことがある。その基本的な考え方を整理する。
==== expect ====
端末の手動操作を自動化するソフト。


交互にしていい場合は簡単二重。引用符内に一重引用符を配置、一重引用符内に二重引用符を配置すればいい。
<nowiki>*</nowiki> ^と$は使えない。代わりに、\nを使う。


問題はこれがNGな場合。特にありがちなのが、JSONの生成。JSONの引用符は二重引用符のみ。一重引用符の中だと、二重引用符の変数展開が使用不能。外側を二重引用符にする必要がある。
<nowiki>*</nowiki> 文字列の囲みに一重引用符 (') は使えない。二重引用符 (") のみ有効。


二重引用符は、内部で変数展開が可能。この都合で、バックスラッシュ\によるエスケープが有効。
<nowiki>*</nowiki> expect文はawkみたいな感じ。


基本的な方法。
<nowiki>*</nowiki> ただし、expectは注意が必要。最初のexpectにマッチしないと先に進めない。タイムアウトとかするしかない。


# 既存の一重/二重引用符などをバックスラッシュでエスケープ。
expect -c "set timeout 5; spawn cat cat.txt; expect \nFAIL {send pwd/n; expect :; exit}"
# 全体を一重/二重引用符で囲む。


何かAwkの本か何かで、基本的な考え方の説明の記載があった気がする。
https:/linuxjm.osdn.jp/html/expect/man1/expect.1.html


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


# {"ke\y":"valu\e"}
sh -eux <<-"EOT"
# エスケープ: {\"ke\\y\":\"valu\\e\"}
# 全体囲み: "{\"ke\\y\":\"valu\\e\"}"


これでOK。また何か考慮不足があればそのときに考える。
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"


例えば、シェルなら、catコマンドとコマンド置換で生テキストを使える。
expect -c "set timeout 5; spawn cat cat.txt; expect \nFAIL {send pwd/n; expect :; exit}"
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]
expect -c 'set timeout 10; spawn cat cat.txt; expect "aa F" {set AAA "abc"}; expect FAIL {send "$AAA/n"; expect " "; exit}'
* [https://stackoverflow.com/questions/64011248/how-to-handle-double-quotes-in-json-value python - How to handle double quotes in JSON value? - Stack Overflow]


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


基本的な考え方がある。
```


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


こういう感じ。JSONはawkでも任意の最終データで考える。途中にプログラミング言語でのパースがあるので、それを考慮する必要がある。
=== タイムゾーン ===
[https://qiita.com/dmikurube/items/15899ec9de643e91497c タイムゾーン呪いの書 #timezone - Qiita]


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


==== クローズ時に自動移動 ====
タイムゾーン名で判定する実装があるので、UTC-9なども避けたほうがいい。
[Configure project]-[Automatic actions]


* action=[Move the task to another project]
tz databaseのAsia/Tokyoなどの確実性が高い。
* Event name=Closing a task
=== Regular Expression ===
* Column=Done
正規表現。重要。覚えにくいが重要なものをメモしておく。
* Project=


これでDoneをclose時にアーカイブ用のプロジェクトに移動できる。
後ろからマッチ。cが置換対象。


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


==== クラス図 ====
===== マッチの前後の挿入 =====
* 汎化 (generalization): 実線白矢印。継承。   
https:/vim.fandom.com/wiki/Power_of_g
* 実現 (realization): 点線矢印。interfaceの継承。
:g/GST_.*("/s/^/LOG(INFO) << "DEBUG";/r/
* 集約: 白ひし形。
行頭・行末で引っ掛ける。
* コンポジション: 黒ひし形。子が単体で存在できない場合。親と生存期間が同一の場合。   
* 関連: 実線矢印。メソッド内インスタンスなど。
* 依存: 点線矢印。引数やローカル変数、返却値。


== VCS ==
===== 関数にログ =====
:%s/([^")]*)/) /([a-z]* /)*{/&/rLOG(INFO) << "/1";/r/g
考慮するケース
double currentTime() const override { return m_element->currentTime(); }


==== Git ====
=== glob ===


===== 差分ファイル抽出 =====
* [https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/functions/glob.html glob]
情報源: [https://qiita.com/kaminaly/items/28f9cb4e680deb700833 gitで差分ファイルを抽出する #Git - Qiita]
* [https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/utilities/V3_chap02.html#tag_18_13 Shell Command Language]


git archiveとgit diffを組み合わせる。
重要。正規表現とは似ているが異なる、パターンマッチング記法 (Pattern Matching Notation)。主に、globで採用されており、ディレクトリー・ファイルのマッチングで使われる。
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で階層を維持してコピーするしかないかも?
使用可能な記号は以下3個。以下の3文字は\でエスケープできる。


:
* ?: 任意の1文字にマッチ。
mkdir -p archive
* *: 任意の0以上の文字にマッチ。
git diff --name-only new_base 44765_upgrade-base-version | xargs -i cp -p --parent "{}" archive/
* [: []内の1文字にマッチ。正規表現の各括弧と同じ。ただし、先頭の否定が^ではなく、!。


===== マージコミット後のコミット追加 =====
ファイル名マッチ時には、追加で特殊なルールがある。
マージコミット後に次の開発作業を始めることが多い。が、直後の初回のコミットを追加したい場合困る。


git rebase -iにすると、コミットが残るから。編集はできるが、その直前にコミットの追加ができない。マージコミットは扱いが特殊で直接rebaseで編集できない。
.から始まるファイル名へのマッチには、.が必要。つまり、*?は先頭の.にはマッチしない。[!a] のような否定形の各括弧記法も.にはマッチしない。加えて、先頭の[.]もマッチするかは不定(unspecified)。


しかたないので、該当コミットでブランチを作成して、コミット。その後、既存の修正ブランチをrebaseでそのコミットの後にくっつける。これでいける。
globで.ファイルを含めたい場合、工夫が必要 ([https://www.php.net/manual/ja/function.glob.php PHP: glob - Manual])。
.[!.]* *
上記のように.ファイルのマッチとそれ以外を指定する必要がある。


===== core.autocrlf =====
<code>.[!.]*</code> は、<code>.</code>と<code>..</code>以外の.<code>.</code>始まりのファイルにマッチする。
<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


* true=コミット時にCRLFをLFに自動変換。チェックアウト時に逆。Windows向けの設定。
<code>.*</code>を指定すると、<code>.</code>/<code>..</code>がマッチするので注意する。最近のシェルは、シェル側で気を利かせているようで、<code>.*</code>だと<code>.</code> /<code>..</code>はマッチしない。
* false=変換しない。
* input=コミット時にCRLFをLFに自動変換のみ。mac/Linux向け。Windowsではチェックアウト時にCRLFになるが、mac/LinuxはLFになる。


わかりにくい。基本はfalseで良いと思われる。
=== 引用符のネスト ===
シェルやプログラミング言語で、文字列リテラルの表現などで、一重引用符'と二重引用符"を使う。


===== gitkの文字化け対策 =====
JSON作成や変数展開などで、これらをネストさせたいことがある。その基本的な考え方を整理する。
[https://www.pistolfly.com/weblog/2010/02/gitk.html gitkのエンコーディングを設定する - Pistolfly]


gitkはシステムのデフォルトエンコーディングで表示しようとするので、文字エンコーディングを指定しておく。
交互にしていい場合は簡単二重。引用符内に一重引用符を配置、一重引用符内に二重引用符を配置すればいい。
git config --global gui.encoding utf-8


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


* [https://qiita.com/yukimura1227/items/fbb076db61a2e43a32e3 gitでrename&modifyしたファイルのログを追跡できるようにしたい場合 #Git - Qiita]
二重引用符は、内部で変数展開が可能。この都合で、バックスラッシュ\によるエスケープが有効。
* [https://zenn.dev/yoichi/articles/how-git-handles-renaming Gitはファイルのリネームをどう扱うか]


改名と修正を同時にすると、改名を検知できない。
基本的な方法。


-Mオプションを指定すると、類似度で同時も検知できる。が、基本はリネーム・改名と修正は別コミットにしたほうがよさそう。
# 既存の一重/二重引用符などをバックスラッシュでエスケープ。
# 全体を一重/二重引用符で囲む。


===== 差分無視 =====
何かAwkの本か何かで、基本的な考え方の説明の記載があった気がする。
[https://qiita.com/odekekepeanuts/items/8a056b87c9e481e07e57 git diffの--ignoreオプションにおけるスペース、タブ、改行の扱いを理解する #Git - Qiita]


-wでインデント違いを無視してくれる。
[{"ke\y":"valu\e"}] を例として考える。


===== squash =====
# {"ke\y":"valu\e"}
squashすると、squash対象コミットが、対象の直前のコミットに含められる。
# エスケープ: {\"ke\\y\":\"valu\\e\"}
# 全体囲み: "{\"ke\\y\":\"valu\\e\"}"


===== gitignore =====
これでOK。また何か考慮不足があればそのときに考える。
[https://git-scm.com/docs/gitignore/en Git - gitignore Documentation]


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


* 空行は無視。
例えば、シェルなら、catコマンドとコマンド置換で生テキストを使える。
* #始まりの行はコメント扱い。
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]
* *は/以外にマッチ。?は/以外の任意の1文字にマッチ。[a-zA-Z] の範囲記法も使用可能。fnmatch(3) FNM_PATHNAMEフラグのパス名展開に準じる。
* [https://stackoverflow.com/questions/64011248/how-to-handle-double-quotes-in-json-value python - How to handle double quotes in JSON value? - Stack Overflow]
* **は特殊な意味がある。
** **/=全ディレクトリー。**/fooは配下の全fooにマッチ。**/foo/barはfoo以下の全barにマッチ。
** /**=配下のすべてにマッチ。
** a/**/b=a/b a/x/b a/x/y/bのすべてにマッチ。


後は特に明記がないが、上から順番に評価されて、最後のマッチが優先されるので、記述の順番に注意する。
JSONのvalue部分に適用したい場合。データの二重引用符をバックスラッシュでエスケープする。これはこうするしかない。JSONが二重引用符しか認めないから。


反転の!と/の扱いに特に注意が必要。
基本的な考え方がある。


先頭スラッシュをつけないと、再帰的になる。
# JSON value用に二重引用符"を\"で置換。
    $ cat .gitignore
# \"がPHP/JavaScriptで二重引用符に扱いにならないように、\を\\に置換。
    # ディレクトリ foo/bar 以外のすべてを除外
# JSON項目の二重引用符"を\"で置換。
    /*
# 全体を二重引用符"で囲む。
    !/foo
 
    /foo/*
こういう感じ。JSONはawkでも任意の最終データで考える。途中にプログラミング言語でのパースがあるので、それを考慮する必要がある。
    !/foo/bar
 
=== ケース変換 ===
[https://stackoverflow.com/questions/63116039/camelcase-to-kebab-case javascript - camelCase to kebab-case - Stack Overflow]


====== 空ディレクトリーの維持 ======
キャメルケースをチェインケースにしたり、逆にしたりなどケース変換したいことがある。正規表現を駆使して実現する。
[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は空ディレクトリーを履歴管理できない。何かファイルが必要。
=== encode ===
[https://www.sejuku.net/blog/25909 【PHP入門】URLエンコードする方法(urlencode) | 侍エンジニアブログ]


logなど維持したい空ディレクトリーに、以下の内容の.gitignoreを置く。
日本語や記号を他のコードに変換 (エンコード) する方式が何通りかある。把握しておくと役立つ。
!.gitignore
.gitignore以外を無視する。これで.gitignoreのみがあるので管理できる。


====== 指定ファイルのみ除外 ======
* パーセントエンコーディング/URLエンコード: URLで使用不能な文字を%16進数で連結。
*
* UTF-8
!.gitignore
* base64: 全データを「A-Z」「a-z」「0-9」「+」「/」の64文字で表現。文末に=を使うので実質は65文字。
ディレクトリーを残す以外 (.gitignore1ファイル以外) に、サンプルファイルなど複数ファイルを残したい場合は、上記のように*で最初に全部除外して指定ファイルのみ含める。/は必要に応じてつける。
* HTMLエンコード: HTMLで特殊な意味を持つ文字を&amp;lt;などに変換する。


===== gitattributes =====
==== Percent-encoding ====
[https://git-scm.com/docs/gitattributes Git - gitattributes Documentation]


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://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]


* text
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
* eol
上記文字はエンコードの対象外。
* working-tree-encoding
 
* ident
==== 英数変換 ====
* filter
[https://stackoverflow.com/questions/28110062/php-how-to-encode-all-characters-with-rawurlencode string - PHP How to encode all characters with rawurlencode - Stack Overflow]
* diff
* merge
* conflict-marker-size
* whitespace
* export-ignore: git archiveなどに含めないことをマーク。
* export-subst
* delta
* encoding


===== 過去コミットのメールアドレスの変更 =====
変数名への変換などで、日本語や記号を英数字 [0-9a-zA-Z] に変換したいことがある。


* [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>"
  function encode_all($str) {
--amendと併用することで、過去コミットも変更できる。
    $hex = unpack('H*', $str);
    return preg_replace('~..~', '%$0', strtoupper($hex[1]));
}
$str = 'big ƒüßchen';
print_r(encode_all($str));


数が少ないなら、rebase -iで1個ずつamendする。数が多いならfilter-branch。
==== 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など。


* [https://dev.classmethod.jp/articles/git-rebase-from-root/ [Git] 最初のコミットを含めてrebase -iする方法 | DevelopersIO]
フレームワークの中にライブラリーも含めていいと思う。
* [https://git-scm.com/docs/git-rebase Git - git-rebase Documentation]


通常、第一コミットはammend以外では変更できない。
==== 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]」


rebase --root [branch] でブランチの第一コミットも参照して改変可能。
ソフトウェアの分類、ページ分類時に役立つ。


===== ファイルのインデックスのみ削除 =====
* 言語
git rmは単独だと、gitの履歴とローカルファイルからも削除する。追跡対象から削除のみで、ローカルファイルとして残したい場合、--cachedを指定する。
* ツール: 静的解析、テスト、文書など。
git rm --cached
* フレームワーク


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




=== Fossil ===
* PHP language
* [https://gigazine.net/news/20231231-why-sqlite-does-not-use-git/ SQLiteがバージョン管理システムとしてGitを採用しない理由 - GIGAZINE]
* PHP tool
* [https://gigazine.net/news/20201229-fossil/ GitとGitHubの機能をひとつのバイナリに詰め込んだ「Fossil」レビュー - GIGAZINE]
* PHP framework


外部依存を排除しており、CGIでも動作するという点が非常に良い。気になる。Phorgeの検討が不要になる。
==== 成功時連続継続処理 ====
一度の取得件数の上限が決まっていて、終了・失敗するまで取得を継続したいという処理がそれなりに発生する。


=== GitHub ===
# 処理実行。
# 成功ならA、失敗なら終了。
# 処理実行。
# 成功ならA、失敗なら終了。


==== Account ====
こういうパターン。いくつか実装方法があるが、while (true) のパターンが重複がなくてベストだと思う。
  Username may only contain alphanumeric characters or single hyphens, and cannot begin or end with a hyphen.
        /*
ユーザー名は、英数字と-のみが使用可能。
        // 無限ループで終了条件でブレイク
        while (true) {
            // 処理実行
            if (失敗) {
                break;
            }
            成功時処理
        }
       
        // do while
        do {
            処理実行
            if (成功時) {}           
        } while ();
   
        // for (初期化; 継続判定・終了判定; 成功時式) {
            処理実行
        }
        */
do-whileは成功・終了判定を2回書く必要がある。


組織別にアカウントを分けるなら、かぶらないように末尾に-組織名のようなサフィックスがあるとよいだろう。
forだと成功処理を式でしか書けない。成功処理を関数や即時実行関数式などで書くなら悪くはないし、ベストになりえる。


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


=== ワイルドカード ===
これにさらに初回だけ、ヘッダーの取得、書き込み処理などが発生する場合、初回だけループの外でやるのがきれいだろうか?初回処理が2回登場することになるけれど。
ワイルドカードで.始まりのファイルをマッチさせたい。


以下ならマッチするが、ブレース展開 (brace expansion) はPOSIX shでは使えなかった気がする。
offsetなどで初回の判定が反復内でできるから、それで分けるのがいいか?
  echo {.*,*}
        $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);
        }


=== BOM ===
        for ($offset = 0;
[https://stackoverflow.com/questions/3127436/adding-bom-to-utf-8-files unicode - Adding BOM to UTF-8 files - Stack Overflow]
            ($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();
        }


ExcelでUTF-8ファイルを開けるように、UTF-8のBOMをファイルにつけたい。
=== character ===
printf '\xEF\xBB\xBF' > with_bom.txt
上記コードでBOMを最初に書き込んで、後は追記する。


=== awk ===
==== BOM ====
[https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/ The Open Group Base Specifications Issue 7]
UTF-8のBOM
\xef\xbb\xbf
この文字を先頭につけるとUTF-8のBOMになる。


==== 変数 ====
=== Convert ===
 
==== IP/CIDR ====
// JavaScript
<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


===== 特別 =====
再帰関数で実装するほかに、スタックで処理する方法がある。
* NF: 列数。列の全表示などで使う基本的で重要な変数。
* NR: 行番号。


===== スコープ =====
再帰関数のほうが簡単に実装できるが、関数呼び出しのオーバーヘッドがある。ネスト10-100程度くらいなら問題ない。
[http://www.fukano.jp/study_of_awk/basic/basic08.htm 変数のスコープ]


関数の仮引数のみ、ローカル変数扱いで、それ以外はグローバル変数。
パフォーマンスや再帰中の細かい制御が必要なら、スタックが有利。ただし、実装がやや複雑。


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


* actions
== UML ==
** if/else
** while/do...while/for
** break/continue
** delete
** next
** exit
* output
** print
** printf


==== 関数 ====
=== Umbrello ===


===== 組込関数 =====
==== Problem ====
altなどの重なり順番、アクティブの下になっちゃう


* Arithmetic
optの条件が表示されない。
** 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/文扱い。
=== Modelio ===


==== ヘッダー出力、列別最大長さ出力。 ====
==== クラス図 ====
<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>
* 汎化 (generalization): 実線白矢印。継承。
* 実現 (realization): 点線矢印。interfaceの継承。
* 集約: 白ひし形。
* コンポジション: 黒ひし形。子が単体で存在できない場合。親と生存期間が同一の場合。
* 関連: 実線矢印。メソッド内インスタンスなど。
* 依存: 点線矢印。引数やローカル変数、返却値。
 
=== Design ===


==== CSV ====
==== Atomic Design ====
[https://qiita.com/ko1nksm/items/19407c1c53cbbc50569a シェルスクリプトの実験のために作った POSIX 準拠 awk 実装の CSVパーサー (RFC4180対応) #ShellScript - Qiita]<syntaxhighlight lang="awk" line="1">
# csvparser.awk


## Usage
* [https://atomicdesign.bradfrost.com/chapter-2/ Atomic Design Methodology | Atomic Design by Brad Frost]
# awk -f csvparser.awk data.csv
* [https://zenn.dev/bizlink/articles/b5c8985af8407a Atomic Designの概念]


# CSV の論理的な一行毎に呼び出されるコールバック関数(サンプル)
最近のUIのコンポーネントの組み方。UIコンポーネントを粒度に分けて、ディレクトリー分けして流用するという考え方。
# 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 }
* atoms: 原子。これ以上分割不能な最小単位。input/label/buttonなど。
{
* molecules: 分子。atomsを組み合わせたり、atomsに多少修正したもの。入力フォーム、ナビゲーション、カードなど。
    idx = 0
* organisms: 有機体。分子+アルファ。入力フォーム+ヘッダーなど。複数の分子。
    sub(/\r$/, "")
* templates: テンプレート。複数の有機体。ヘッダー、メイン、フッターなど。
    while ($0 != "") {
* pages: ページ。テンプレートを使用したページ。
        if (match($0, /^(["]([^"]|["]["])*["]|[^,"]*)(,|$)/)) {
 
            fields[++idx] = ""
==== インターフェイスと抽象クラス ====
        } else if (match($0, /^["]/)) {
[https://qiita.com/nogson/items/e6575d6617f854ed6e25 PHPでインターフェイスと抽象クラスを使う #PHP - Qiita]
            fields[++idx] = substr($0, 2)
 
            for (;;) {
* インターフェイスは、クラスに複数実装できるが、抽象クラスは1つしか継承できない。→不特定のクラスで、共通のメソッドを定義したい場合。
                if (getline == 0) exit 1
* インターフェイスは、実装のあるメソッドを持つことができないが、抽象クラスは、実装のあるメソッドを持つことができる。→抽象クラスは、複数のクラスの、共通処理の中に、一部違う処理が入る場合、プロパティーが必要な場合などに使用する。
                sub(/\r$/, "")
 
                if (match($0, /^([^"]|["]["])*["](,|$)/)) break
インターフェイス
                gsub(/["]["]/, "\"")
 
                fields[idx] = fields[idx] "\n" $0
* メソッド宣言のみ。
            }
* static/constの場合に限定して、メソッド定義、定数もOK。
            fields[idx] = fields[idx] "\n"
 
        } else {
==== Config class ====
            exit 1
 
        }
* [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]
        field = substr($0, RSTART, RLENGTH)
* [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]
        $0 = substr($0, RSTART + RLENGTH)
* [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]
        lastcomma = sub(/,$/, "", field) > 0
* [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]
        gsub(/^["]|["]$/, "", field) && gsub(/["]["]/, "\"", field)
 
        fields[idx] = fields[idx] field
アプリケーションの設定を管理するクラスの設計方法。いくつか方法があり、議論がある。「[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]」で特によく議論されている。
    }
 
    if (lastcomma) fields[++idx] = ""
# シングルトン/グローバル変数: ただし、テストなどで並列アクセスが必要な場合に困ることがあるらしい。
    while (idx < max_idx) delete fields[max_idx--]
# DI/設定クラス引数: これがよく支持されている。テストしやすいなど。グローバル変数への参照を渡すようなイメージ。ただし、依存性の伝播のように、上から下に設定を渡す際に、関係ない大量の設定を渡すことがあったりする。
    callback(++row, idx, fields)
 
    max_idx = idx
2のDIが最近の主流。引数で値渡し相当にすれば、並列アクセス時も無影響。伝播の問題は設計の問題。
}
 
メソッドをmain関数で呼び出すことを想定して、必要なものだけ渡るようにして、余計なものは削除する。上位・下位の関係を明確にすれば、渡すだけのパラメーターを排除できる。


</syntaxhighlight>awkのCSVパーサー。
==== do-while/if ====
複雑なif文と相性がいい。


=== Other ===
for whileの無限ループで最後にbreakでも同じか
do {
  if (true) break;
} while(false);
if文が複雑な場合、do-whileで囲んで、breakでスキップできる。gotoに近い。


==== binary ====
==== GoF ====
[https://qiita.com/ko1nksm/items/dc8f247cdc5b7b58b736 POSIX準拠のシェルスクリプトでバイナリデータを扱う #Bash - Qiita]
基本的に、具象クラスを使わずに、インターフェイスや抽象クラスを使ってインスタンスを生成するというのが、共通する基本パターン。


バイナリーデータの読込はodコマンド。なければhexdump。
これにより、いろんなケースに同じコードで対応できる。


書込はprintf。
===== Factory Methodパターン =====
[https://blog.ecbeing.tech/entry/2021/01/20/114000 なぜあんなに難しい?Factory Methodパターン - ecbeing labs(イーシービーイング・ラボ)]


head/tailの-cはPOSIXで使えたか?
コンストラクターの代わりに、インスタンスを生成 (工場=factory) となるメソッドを使うから、FactoryMethodパターン。


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


=== bitsadmin ===
ただ、Factory Methodパターンを採用すると、コード量が増えて複雑になる。
Windowsでのファイルダウンロードコマンド


Windows 7以降ではbitsadminコマンドがあり、これがwget相当となる。
複雑でややこしいだけなので、基本的に使わなくてよいと思う。


書式:
==== Naming ====
bitsadmin /transfer <job name> <URL> <output path>
 
<job name>と<output path>は必須なので注意する。
===== camelCase =====
https://gnusocial.jp/notice/7694551
 
!it 命名規則のキャメルケース。これ英語前提です。関数名に英語以外を使うと破綻します。


=== certutil ===
getキーバリュー()みたいな関数の定義。日本語ですると境界がわからなくなるので、getキー_バリューみたいにアンダーバーで区切ったほうが分かりやすい。なるほど…
Windowsでのハッシュの確認に使える。
certutil -hashfile file


SHA1 ハッシュ (対象 C:\moconavi\windows\Moconavi\ext\chromium\moconavium.exe):
===== getMyVariable() vs myVariable() =====
e0da85b04b6970ac1f0c33db7a9ad607fdbd44eb
CertUtil: -hashfile コマンドは正常に完了しました。


=== rlogin.cmd ===
* [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]
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%


=== 実行中プロセスのパスの確認 ===
getterとsetterの命名規則。
出典: [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
getVar()にするか、Var()にするか。C++だと後者のパターンがあったりする。getを省略できるので、省スペースになる。
wmic process where "name='mysqld.exe'" get ProcessID, ExecutablePath
wmic process where "name='mysqld.exe'" get ProcessID, ExecutablePath /FORMAT:LIST


=== 簡易編集モード/挿入モード ===
ただ、コード補完で探しやすさがちょっと変わる。getを前置したほうがわかりやすいか。


* [https://softantenna.com/blog/windows-10-command-prompt-no-stop/ 【Tips】Windows 10のコマンドプロンプトが意図せず止まってしまう問題を回避する方法 | ソフトアンテナ]
===== namePrefixed() vs prefixedName() =====
* [https://superuser.com/questions/419717/windows-command-prompt-freezing-randomly Windows command prompt freezing randomly - Super User]
https://chatgpt.com/c/673bd358-3dc8-800b-8ec9-d745cc0eba85


Windows 10のcmd.exeは [簡易編集モード] が有効になっており、コマンドプロンプトを左クリックすると、テキストの選択が始まる。テキスト選択中はコマンドの実行が止まる。長時間かかるコマンドの実行中に誤操作で止まると困るので、これは無効にしたほうがよい。
名詞+修飾語 (形容詞) の場合のメソッドの命名規則。name+修飾語が複数ある場合name+修飾語がいい。オブジェクト指向でnameをオブジェクトとして扱う形に近い。name.methodみたいな。


cmd.exeを起動-左上のアイコンをクリック-[規定値]/[プロパティ]-[オプション]-[□簡易編集モード] を選ぶ。
例えば、nameMax、nameMinのような場合は後ろのほうが都合がいい。ただ、こういう場合はそもそもnameをオブジェクトにしてname.max()、name.min()にしたほうがいいという説がある。


そのほか、 <code>git log</code> のような制御が移るコマンドを実行してしばらくすると、操作できなくなる。
そうではないならば、getPrefixedName()などが自然。getQueryString()など。StringQueryではない。


[□挿入モード] にすると回避できる模様。
PHPでは以下のような命名規則が好まれる。


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


=== HTTP ===
getPrefixedNameがいいか。後置修飾にしたいならば、そもそもオブジェクト+メソッドにすることを検討する。
[https://www.rfc-editor.org/rfc/rfc9110.html RFC 9110: HTTP Semantics]


==== Content-Disposition ====
===== map =====
[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)]
<code>map_[key]_[value]</code> のような形式にすると、キーとバリューが何を意味するか分かってわかりやすい。
Content-Disposition: inline
Content-Disposition: attachment
Content-Disposition: attachment; filename="filename.jpg"
filenameでファイル名を指定する。ここの値は二重引用符で囲む。スペースを含む場合に必須になる。


==== multipart/form-data ====
===== foreach =====
rfc7578
[https://wiki.senooken.jp/PHP#Name_2 PHP - senooken JP Wiki]


* [https://datatracker.ietf.org/doc/html/rfc7578 RFC 7578 - Returning Values from Forms: multipart/form-data]
foreach系のfor文ではキーとバリューを変数に格納して反復する。ファイルや配列に対して行うことが多い。
* [https://qiita.com/sivertigo/items/14957200af5ad953d63b Multipart/form-dataの仕様メモ #HTTP - Qiita]
foreach (table as $row => $line)
その際の変数名は、上記のように$row/$lineにすると、行番号と行の値がはっきりしてわかりやすい。


ファイルアップロード用のMIME type。
===== Function argument order =====
関数の引数は入力、変更、出力の順番にする。理由はこの順番で使うから。<blockquote><nowiki>https://social.senooken.jp/notice/67270</nowiki>


リクエストヘッダー
うーん。今晩は,CODE COMPLETEでC言語の関数の引数の順番を調べたりしていて,勉強時間がないな…
Content-Type: multipart/form-data; boundary=--hogehoge
 
リクエストボディー
int func(入力,変更,出力)
--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する, 様々な形式別メモ |]
この順番。理由は,この順番で使うから。


curlでの送信理由。
memcpyとかは例外が多い。


-Fで送信データをname=data形式で指定する。ファイルの内容を指定する場合、@filenameで指定する。これを指定すると、リクエストボディーのfilename扱いにしてくれる模様。-Fを指定すると、-H 'Content-Type: multipart/form-data'が自動付与される。たぶん、-dと同様に-X POSTもつく。
x = bの語順からきているからとの憶測がある。
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などをうまくやってくれるのだと思う。


リクエストボディー全体をファイルデータにする場合。
<nowiki>https://okwave.jp/qa/q4202225.html</nowiki></blockquote>
curl -X POST -H 'Content-Type: image/jpeg' --data-binary @/var/tmp/sample.jpg <nowiki>https://xxxxx.net/xxxxxx</nowiki>


=== IP address ===
==== DB ====
出典: [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【公式】| 株式会社グローカルネット]
[http://blog.tojiru.net/article/277021312.html PDOの真の力を開放する - PHPでデータベースを扱う(3): Architect Note]


自宅サーバーを行う際、固定IPアドレスが必要になる。
DBアクセスのモデル化。行をクラスとすると扱いやすい模様。


取得方法がいくつかある。
getterを作ったり、データの妥当性のチェックなどもできる。


* 契約しているプロバイダでオプションとして申し込む方法
select/insert/などはmapperでクラスとDB列名を対応付けて処理する。自前で実装する場合はこういうつくりがいいらしい。
* 固定IPアドレスに対応しているSIMを契約する方法
* '''VPNを利用した固定IPアドレスの提供会社を利用する方法'''


VPNの固定IPアドレスが安いらしい。ryoかsuwakoが解説していた気がする。
データベース関係のデザインパターンがいくつかある。


=== Authentication ===
* Active Record
認証方式がいくつかある。HTTPで定義される認証方式 (HTTP認証) が有名。
* Data Mapper


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


Authorization HTTPヘッダーにBasicのあとに [username:password] をBASE64でエンコードして送信する認証方式。
* [https://ja.wikipedia.org/wiki/Active_Record Active Record - Wikipedia]
GET /private/index.html HTTP/1.1
* [https://www.techscore.com/tech/Ruby/Rails/other/designpattern/ デザインパターンから見たActive Record | TECHSCORE(テックスコア)]
Host: example.com
Authorization: Basic cm9vdDpwYXNzd29yZA{{=}}{{=}}
盗聴や改ざんが簡単だが、シンプルという利点がある。


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


* [https://ja.wikipedia.org/wiki/OAuth OAuth - Wikipedia]
シンプルだが、複雑な操作が苦手。


OAuth (オーオース) 権限の認可のための標準。OAuth 2.0が最新の標準。
エンティティーがテーブルと密接なため、例えばテーブル構造が変わった場合に大量に修正必要。


以下が登場人物。
Ruby on Rails/Laravel+Eloquentなどで採用。


* resource owner: あるサイトのユーザー。
===== Data Mapper pattern =====
* resource server: あるサイトのユーザーのデータの保有サーバー。
[https://gihyo.jp/dev/serial/01/ruby/0014 第14回 DataMapperの使い方 | gihyo.jp]
* clent: クライアントアプリ。リソースサーバーのデータを使用したい。
* authorization server: クライアントにサイトへのアクセスを認証するサーバー。アクセストークンを発行して行う。


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


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


# client->resource owner: Authorization Request。ここでユーザーが手操作でアクセスを承認する。
その都合、1テーブルに2クラス必要。
# 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


Consumer Key/Secret: アプリ識別用のID/PW。
User/UserMapperのような対応関係。


Access Token: サイトにアクセスするためのパスワード。
2クラス必要だが、テーブル構造が変わった場合でも基本はMapperで吸収できる。


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


==== 複数レコードの登録 ====
基本はエンティティーのプロパティーに持たせる感じ。
[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を作るしかなくないか?
<blockquote>datamapperパターンでjoinする場合、エンティティーの扱いはどうなるの?


[https://www.yamarkz.com/blog/rest-web-api-practice REST WebAPIのプラクティス | yamarkz.com]
`DataMapper`パターンで`JOIN`を行う場合、エンティティの扱いは設計次第ですが、いくつかの注意点があります。`DataMapper`パターンは、データベースのテーブルとエンティティの間にマッピングを行い、エンティティはドメインロジックを持ち、データベースアクセスの責務を持たないことが特徴です。そのため、`JOIN`の処理をどの層で行うかを慎重に設計する必要があります。


delete_bulkなどのような一括処理用のAPIを作るしかない。内部的には単一処理のAPIを作る感じだったとしても。
以下、`JOIN`を行う際のエンティティの扱いと実装方法について解説します。


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


# リクエストボディー
```python
# クエリー
 
# パス
class UserMapper:


パスはIDなどを指定する場合だけわかりやすい。それ以外のオプションはクエリーのほうがいい。
    def find_user_with_orders(self, user_id):


ボディーは、通常サーバーのアップロード・ダウンロードデータとして使われる。クエリーはデータの指定に使う。
        sql = """


この原則に従うとシンプルだろう。
            SELECT * FROM users


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


==== 検索機能のGET/POST ====
            WHERE users.id = %s


* [https://stackoverflow.com/questions/20550514/post-or-get-in-a-search-form .net - POST or GET in a search form? - Stack Overflow]
        """


検索機能にGETとPOSTのどちらを使うか?という議論がある。
        results = self.db.execute(sql, (user_id,))


データ登録するわけなじゃないのだから、GETがいいんじゃない?
       


POSTだと、JSONをそのまま送れるので、複雑なケースに対応できる。特に、配列の送信が重要。
        user = User(results[0]['user_id'], results[0]['user_name'])


GETのほうが検索条件をブックマークにできたり、URLを共有できるので、基本は便利。
        orders = [Order(row['order_id'], row['product_name'], user) for row in results]


==== レート制限対策 ====
        user.orders = orders


* [https://pikodon.com/note/php/api-cache/ APIの利用制限対策 | Web開発ノート]
        return user
* [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 リクエスト数によるアクセス制限の対策方法 – 請求管理ロボ ヘルプ]


いろいろ方法がある。
```


* cronなどでデータをサーバー上 (DBなど) に定期保存して、保存データを表示させる。
この方法では、1つのSQLクエリで必要なデータをすべて取得し、エンティティのプロパティにそれぞれのデータを設定します。
* 配列を利用して、1回のリクエストでまとめて取得する。
* インターバルを設ける。
* HTTP 429/413を検知して、リトライする。


==== 指数関数的バックオフ ====
### 2. リポジトリでの集約


* [https://docs.link.getmoneytree.com/docs/faq-rate-limiting APIレート制限は何か、どのように対処するのか?]
`JOIN`を使わず、各エンティティを個別に取得した後、リポジトリが集約の役割を担う方法もあります。リポジトリが各エンティティの`Mapper`を呼び出し、必要なエンティティ同士を関連付けることで`JOIN`を再現します。例えば、まず`UserMapper`でユーザー情報を取得し、次に`OrderMapper`で該当ユーザーの注文を取得してエンティティ間で関連付けます。
* [[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 で応答した場合に、システムがリクエストを再試行するまでの時間となります。
```python
* <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> の合計に加算するか減算するか、ランダムで選択してください。


=== curl ===
class UserRepository:
HTTPの通信のコマンドラインでの確認でよく使う。


==== Basic ====
    def __init__(self, user_mapper, order_mapper):
[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指定。
        self.user_mapper = user_mapper
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を指定する。
        self.order_mapper = order_mapper


==== curl: (60) SSL certificate problem: self-signed certificate ====
    def get_user_with_orders(self, user_id):
Ref: [https://linuxfan.info/curl-insecure curlで「自己署名証明書」を受け入れるには【curl: (60) SSL certificate problem: self signed certificate】 | LFI].


--insecureオプションを指定すると、localhostなどでの自己署名証明書を許可する。
        user = self.user_mapper.find(user_id)


==== curl: Failed writing body ====
        orders = self.order_mapper.find_by_user_id(user_id)
[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がエラーを出力する。
        user.orders = orders
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
        return user
curlは標準出力に全部書き込めたかチェックしているようで、head -n 1で切り捨てたらcurlはエラーになる。


対策は、curl -sで出力を抑制するとのこと。これで解決。
```</blockquote>UserテーブルとOrderテーブルがあって、あるユーザーの注文一覧を取得したい場合を考える。


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


==== TLS ====
クロス集計する場合は、users[0].orderみたいな感じ。メインのエンティティーのプロパティーに持たせる。フラットじゃないのでちょっと気持ち悪い。が、まあ構造としてこうなるのは順当。
Ref: [https://www.toyo.co.jp/onetech_blog/articles/detail/id=36994 SSL/TLSの復号#1 ~Wiresharkの設定~ | 東陽テクニカ | “はかる”技術で未来を創る | ワン・テクノロジーズ・カンパニー].


Wiresharkで通信パケットを確認する場合、デフォルトでTLSで暗号化されているので、内容がわからない。WiresharkでTLSに対応しておく必要がある。
方法として、1回のSQLで取得するか、それぞれのエンティティーを取得してマージするか。1回のSQLでやったほうが当然いい。


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


* ☑Allow subdissector to reassemble TCP stream
===== 1対1-多対多 =====
* ☑Reassemble out-of-order semgemnts
プログラミング言語でデータの関連付けをすることがある。


上記をチェックしておく。デフォルトでチェックされていた。
1対1の場合、配列、連想配列のキーバリュー形式のデータがぴったり。


続いて、セッションごとのPre-Master Secretを登録する。
多対多の場合。これも配列。二次元配列で基本は0要素目など。
$array[][]


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


以下のコマンド相当で、任意のファイル・場所にログファイルを指定する。
=== 対話AI ===
export SSLKEYLOGFILE=/tmp/sslkey.log
Macだとlaunchctlで設定しておくといい。これでWebブラウザー経由の場合は見えるようになる。


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


==== DoS攻撃 ====
いろいろある。
いくつか対策方法がある。
{| class="wikitable"
|+
!Name
!
!
!
|-
|Bing
|
|
|
|-
|Perplexity AI
|
|
|
|-
|ChatGPT
|
|
|
|-
|Google Gemini
|
|
|
|}


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


サーバーログにIPアドレスが残るから、それで攻撃元の国を特定して、該当国を一括アクセス拒否。これが効果あるかもしれない。
===== Plan =====
[https://openai.com/chatgpt/ ChatGPT | OpenAI]


攻撃元の国は途上国とかが多いだろうから。IPアドレスは簡単に変更できるが、国を変えるのはたいへんだろう。
Free/Plusの2のプランがある。
{| class="wikitable"
|+
!
!Free
!Plus
|-
|金額 [USD/月]
|0
|20
|-
|機能
|基本
|アーリーアクセス
|-
|エンジン
|GPT-4o mini
|GPT-4/GPT-4o/GPT-4o mini
|-
|制限
| -
|GPT-4oの5倍以上のメッセージ送信
|-
|その他
| -
|データ分析、ファイルアップロード、ビジョン、Webブラウジング
|-
|画像生成
| -
|DALL-E
|}
送信可能なメッセージ数、エンジン、画像生成などが大きな違いだろう。


==== バリデーションの実装 ====
===== Account =====
公式サイトにアカウントの意味の説明がない。しかたないので、ChatGPTに質問。<blockquote>ChatGPTに会員登録する意味は何ですか?


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


基本的に、バックエンドで主にチェックして、フロントエンドはUXの向上目的で実装する。データの重複チェックはDBアクセスが必要だったりするから。また、API経由などフロントがそもそもないケースもある。
ChatGPTに会員登録する主な利点はいくつかあります。


ただ、社内システムのような、画面経由でしか使わない。悪者がほぼいないと思われるケースは、フロントエンドでの検証だけでも十分に感じる。
1. **パーソナライズされた体験**: 登録すると、あなたの好みや過去のやり取りに基づいて、よりカスタマイズされた応答が得られます。


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


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


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


* [https://chromewebstore.google.com/detail/create-link/gcmghdmnkfdbncmnmlkkglmnnhagajbm Create Link]:
5. **セキュリティとプライバシー**: アカウントを持つことで、データの管理やプライバシーの設定をより細かく調整できます。


==== 開発者ツール ====
興味があれば、ぜひ登録を検討してみてください!他に質問があればお知らせください。</blockquote>自分の過去の質問の履歴を見れるだけでも便利かも。


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


[Elements]-[Event Listeners]-[handler]-右クリック-[Show function definition] でイベントリスナー関数の定義を確認できる。
====== 質問の分割 ======
https://chatgpt.com/c/673bdc0d-e0e0-800b-a22b-4fa19e64476c


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


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


* [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。
====== 2024-11-14 Thu ======
https://gnusocial.jp/notice/7806505<blockquote>[[/gnusocial.jp/group/32/id|!it]] [[/gnusocial.jp/group/28/id|!ai]] 業務でPHPの開発作業をしていて、ChatGPTを使いだして便利に感じています。検索エンジンの代わりに使っています。
 
例えば、「laravel eloquentでリレーション先のテーブルの主キー名の取得方法は?」と質問します。


=== Other ===
[[/chatgpt.com/c/67354314-fbdc-800b-a4e4-65f96d1a8fb2|https://chatgpt.com/c/67354314-fbdc-800b-a4e4-65f96d1a8fb2]]


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


* [https://web-toolbox.dev/ Web ToolBox | 開発者向けのオンラインツール]
こういう検索エンジンで検索しにくい質問で便利だなと思います。
* [https://tm-webtools.com/ TM - WebTools]


いくつかWeb関係の開発で役立つツール集を公開しているサイトがある。
検索エンジンで検索すると、的外れな情報も大量にヒットします。対話AIはそのごみの混ざった検索結果を分析した結果をコンパクトに返してくれます。対話AI使わなくても、検索エンジンで時間かければわかりますが、大幅に時間短縮できます。


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


* [[wikipedia:Special-use_domain_name|Special-use domain name - Wikipedia]]
個人的に、ただの知識、事実は重要度高くないと思いますが、一般社会では評価する側の頭が悪いので、これが重宝されます。
* [https://ja.wikipedia.org/wiki/.localhost .localhost - Wikipedia]


RFC 6761 で規定。RFC 2606<nowiki/>で予約。DNSに登録されることはないため、テスト目的で使用可能。ループバック (送信元にそのまま返す) インターフェイス。
同僚や先輩に聞くより対話AIのほうがよほど頭いいです。話すことないです。聞くほうが時間の無駄なので。凡人はどんどん要らなくなります。


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


== Shared Host ==
====== 2024-11-19 Tue ======
https://gnusocial.jp/notice/7867350<blockquote>[[/gnusocial.jp/group/28/id|!ai]] ChatGPTが検索エンジンの改良版としてやっぱり便利。さっきこういう質問しました。


=== Free ===
phpのメソッド名で、英単語の修飾語は前と後ろどちらがいい?例えば、namePrefixed()とprefixedName()のどちらがいい? [[/chatgpt.com/c/673bd358-3dc8-800b-8ec9-d745cc0eba85|https://chatgpt.com/c/673bd358-3dc8-800b-8ec9-d745cc0eba85]]
無料で使用可能な共用ホスティングサービスがある。


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


[https://www.star-domain.jp/service/free_server.php 無料レンタルサーバー | スタードメイン - ドメイン取得 100円(税込)~]
この間、 [[/misskey-square.net/users/9g2o6eycu3|@yuriha]] に突っ込まれた件も、たぶん対話AIとお互い会話したほうが有意義だったんじゃないかとすら思います。相手も私に突っ込む前に対話AIと会話したほうが自分の主張の自己矛盾、頓珍漢さに気づけたんじゃないかとすら思えます。私が突っ込んでまーた私がキチガイ扱いされるのも回避されます。対話AIからの客観的な指摘なら、同じ内容であっても、キチガイの私が言うより納得しやすいでしょう?同じ内容なら対話AIのほうが凡人健常者にとっては、信じ込みやすいでしょ?


jpドメインの金額が相場の中では安い方で、それに無料サーバーがついていくる点。
対話AIだとお気持ちの配慮いらないし、当たり前ですけど、キチガイ扱いされることもないので、快適です。元々対話AIには懐疑的でしたが、どちらかというと私のようなキチガイが凡人健常者の知識を拝借するためにあるような印象を持ちます。


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


ただし、SSHやコマンドは使えないので、FTPでWordPressを展開して設置するとか、そういう簡単な使い方だけ。ただ、それでもWordPressでWebサイトを構築するくらいなら十分だと思う。
もはや技術とか、ただの暗記の神経衰弱は別にいらないです。一般企業の上長とか、士業のように、単純知識でマウント取るタイプの仕事はこれで確かに駆逐されます。どうせ対話AIのほうが賢いのだから。知識量で勝てるわけないです。全世界の情報の集積結果なんだから。


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


==== メール ====
== VCS ==


* [https://www2.bwt.jp/wiki/?Custom_Filter_of_Coreserver Custom_Filter_of_Coreserver - PukiWiki]
=== List ===
* [https://help.coreserver.jp/manual/v2/spam-filter/ スパムフィルターの設定 | マニュアル | サポート | レンタルサーバー CORESERVER(コアサーバー)]
Comparison of issue-tracking systems - Wikipedia <nowiki>https://en.wikipedia.org/wiki/Comparison_of_issue-tracking_systems</nowiki>
* [https://help.coreserver.jp/manual/v1/customfilter/ カスタムフィルターの設定 | マニュアル | サポート | レンタルサーバー CORESERVER(コアサーバー)]


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


* [https://www2.bwt.jp/wiki/?CoreServer_Mail_Custom CoreServer_Mail_Custom - PukiWiki]
* Tuleap
* [https://bwt.blog.ss-blog.jp/2021-03-28 coreserverのメール設定:BWT Lab.:SSブログ]
* Phabricator/Phorge
* [https://qwerty.work/blog/2017/01/valueserver-spammail-filter-rule.php バリューサーバーのフィルター設定でスパムメール(迷惑メール)対策する方法 - QWERTY.WORK]
* MantisBT
* [https://awmt.jp/dekirukana/archives/2253 コアサーバー V1にてカスタムフィルターで「ごみ箱」を指定したときの確認方法 – AWMTの、できるかな?]
* FusionForge
* GLPI
* Faveo Helpdesk
* [https://sourcehut.org/ sourcehut - the hacker's forge]: Python製。FSF推奨。


ルールが特殊なので注意する。
VCSとの統合状況がまちまち。


ゴミ箱に振り分ける場合。
=== Git ===


順1 で[<code>./.Trash</code>] を指定
==== Commit ====


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


* 条件:  [<code>.*</code>]
git rebase -iにすると、コミットが残るから。編集はできるが、その直前にコミットの追加ができない。マージコミットは扱いが特殊で直接rebaseで編集できない。
* 処理:  <code>./</code>、に振り分ける


条件部分には正規表現が使えるように見える。
しかたないので、該当コミットでブランチを作成して、コミット。その後、既存の修正ブランチをrebaseでそのコミットの後にくっつける。これでいける。


破棄にしないといけない。転送する場合、カスタムフィルターの中に転送を入れる。条件を.*にする。
===== コミットオプション =====
[https://git-scm.com/docs/git-commit Git - git-commit Documentation]


カスタムフィルターにくせがある。
コミットメッセージ指定のためのオプションがある。


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


==== Value Domain ネットde診断 byGMO ====
基本は-m。-mの複数指定。


* [https://www.value-domain.com/information/detail/?no=20240606-1 弊社レンタルサーバー上で運用中のドメインにおける自動セキュリティ診断開始のお知らせ | お知らせ - バリュードメイン]
===== 過去コミットのメールアドレスの変更 =====
* [https://www.value-domain.com/security/net-de-shindan/ Value Domain ネットde診断 byGMO - バリュードメイン]


2024-06-07 Friからバリュードメイン系の利用者に無料で提供しているセキュリティー診断ツール。
* [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の名前やメールアドレスを過去からまとめて変更する]


== Analytics ==
単一コミットのメールアドレスを指定する場合、commitに--authorを指定する。
git commit --author="John Doe <john@doe.org>"
--amendと併用することで、過去コミットも変更できる。


=== Tool ===
数が少ないなら、rebase -iで1個ずつamendする。数が多いならfilter-branch。
サイト分析用のツールがいくつかある ([https://hidesunblog.com/blog-ranking-sites/ 2023年ブログランキング!おすすめブログランキングサイト比較【一般人向け】])。


* SimilarWeb
===== 第一コミットの変更 =====
* Ubersuggest
* ahrefs
* Googleキーワードプランナー


=== 閲覧数取得 ===
* [https://dev.classmethod.jp/articles/git-rebase-from-root/ [Git] 最初のコミットを含めてrebase -iする方法 | DevelopersIO]
出典: [https://affiliate-jpn.com/archives/5595 GoogleAnalyticsで自サイトの人気記事ランキングを表示する方法 | アフィリエイトJAPAN]
* [https://git-scm.com/docs/git-rebase Git - git-rebase Documentation]


* [行動]-[サイトコンテンツ]-[全てのページ]
通常、第一コミットはammend以外では変更できない。
* [表示する行数]=5000
* [エクスポート]=TSV


=== 流入元特定 ===
rebase --root [branch] でブランチの第一コミットも参照して改変可能。
[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 revert -m 1 マージコミット
git reset --hard HEAD~1 # マージコミット前
どちらか。


・自由形式レポートを作成
==== stash ====


・セグメント作成 > ユーザーセグメント
===== 復元 =====
[https://qiita.com/generosity-naman/items/237338f8fe5b7e3b9a76 Git Stashの復元: 誤って削除されたスタッシュの復元方法 #Git-Stash - Qiita]


・条件は page_view > パラメータ page_location > 含む:会員登録画面のURL を指定
git stash drop実行時に、削除したコミットのSHA1が表示される。


・「会員登録画面閲覧ユーザー」などセグメント名をセットして保存
そのSHA1をapplyで指定すれば、取り込める。
git stash apply [stash_hash]


・探索レポートにセグメントを適用
===== リモート =====
[https://qiita.com/mather314/items/a1536c52a2eb0426b2b5 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はオブジェクトへのアクセスが必要なので、ローカルにないとダメとか。


※ページ閲覧の発生しなかったセッションはランディングページが (not set)になります。
https:/git-scm.com/docs/git-ls-remote.html


 開きっぱなしのタブから再訪問するセッションなどが該当します。ご参考までに。</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>
https:/stackoverflow.com/questions/10649814/get-last-git-tag-from-a-remote-repo-without-cloning


== Server ==
git rev-listでいけそう。


=== httpd ===
https:/gist.github.com/rponte/fdc0724dd984088606b0
Apache HTTP Server


==== Access Control ====
===== 差分ファイル抽出 =====
出典: [https://httpd.apache.org/docs/2.4/en/howto/access.html Access Control - Apache HTTP Server Version 2.4]。
情報源: [https://qiita.com/kaminaly/items/28f9cb4e680deb700833 gitで差分ファイルを抽出する #Git - Qiita]。


DoS攻撃対策などで重要な設定。
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以下の場合だけ。ファイル数が多い場合だめ。


mod_authz_core/mod_authz_hostがコアモジュール。mod_rewriteも関係ある。
git diff --name-onlyで一覧を出力させて、1個ずつcp -pで階層を維持してコピーするしかないかも?


基本構文は以下。
例:
  Require host <address>
  mkdir -p archive
  Require ip <ip address>
  git diff --name-only new_base 44765_upgrade-base-version | xargs -i cp -p --parent "{}" archive/
1番目の形式はドメイン名。2番目はIPアドレス。部分マッチする。マッチしたもののアクセスを許可する。


Requireの直後にnotを指定してアクセス禁止にできる。こちらが重要。
===== core.autocrlf =====
<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


=== E-mail ===
* true=コミット時にCRLFをLFに自動変換。チェックアウト時に逆。Windows向けの設定。
[[https://www.itti.jp/web-direction/spam-blacklist-release/ サーバーIPがブラックリストに載ってメール送信エラーになるのを解除する方法]]
* false=変換しない。
* input=コミット時にCRLFをLFに自動変換のみ。mac/Linux向け。Windowsではチェックアウト時にCRLFになるが、mac/LinuxはLFになる。


MailHog: Go言語製のメールサーバーソフト。
わかりにくい。基本はfalseで良いと思われる。


=== Debian ===
===== gitkの文字化け対策 =====
[https://www.pistolfly.com/weblog/2010/02/gitk.html gitkのエンコーディングを設定する - Pistolfly]


==== PHP8 ====
gitkはシステムのデフォルトエンコーディングで表示しようとするので、文字エンコーディングを指定しておく。
[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 config --global gui.encoding utf-8


Debian 11の場合、PHP 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


sudo apt update
===== 改名と修正 =====


sudo apt install -y lsb-release ca-certificates apt-transport-https software-properties-common gnupg2
* [https://qiita.com/yukimura1227/items/fbb076db61a2e43a32e3 gitでrename&modifyしたファイルのログを追跡できるようにしたい場合 #Git - Qiita]
* [https://zenn.dev/yoichi/articles/how-git-handles-renaming Gitはファイルのリネームをどう扱うか]


PHPパッケージを追加する。
改名と修正を同時にすると、改名を検知できない。


echo "deb <nowiki>https://packages.sury.org/php/</nowiki> $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/sury-php.list
-Mオプションを指定すると、類似度で同時も検知できる。が、基本はリネーム・改名と修正は別コミットにしたほうがよさそう。


wget -qO - <nowiki>https://packages.sury.org/php/apt.gpg</nowiki> | sudo apt-key add -
===== 差分無視 =====
[https://qiita.com/odekekepeanuts/items/8a056b87c9e481e07e57 git diffの--ignoreオプションにおけるスペース、タブ、改行の扱いを理解する #Git - Qiita]


sudo apt update
-wでインデント違いを無視してくれる。


これでPHP8を参照できるので、インストールする。
===== squash =====
squashすると、squash対象コミットが、対象の直前のコミットに含められる。


sudo apt install php8.2
===== gitignore =====
[https://git-scm.com/docs/gitignore/en Git - gitignore Documentation]


[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>)
====== Format ======
記述方法を整理する。


インストールしたら、PHPのバージョンを切り替える。
* 空行は無視。
 
* #始まりの行はコメント扱い。
a2dismod php7.4
* 終端スペースは無視。
* !接頭辞はパターン否定。つまり、除外ではなく含める。以前除外された一致を再び含める。ただし、親ディレクトリーが除外されている場合、以下のファイルは含められない。パフォーマンス上の理由。順番に注意する。
* /はディレクトリー区切りとして使用。先頭、中間、末尾で登場する。
** 先頭と中間の/は相対パスを意味する。
** それ以外、末尾の/と/なしの場合、現在以下のディレクトリーにもマッチする。
** 末尾が/で終わる場合、ディレクトリーのみに一致。/がない場合、ディレクトリーとファイルの両方に一致。
* *は/以外にマッチ。?は/以外の任意の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のすべてにマッチ。


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


sudo systemctl restart apache2
反転の!と/の扱いに特に注意が必要。


php 8.2にするとこういうエラー。
先頭スラッシュをつけないと、再帰的になる。
    $ cat .gitignore
    # ディレクトリ foo/bar 以外のすべてを除外
    /*
    !/foo
    /foo/*
    !/foo/bar


[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
====== 空ディレクトリーの維持 ======
[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]


念のためdockerで起動を試みましたが、同じくトップ画面を開くと同じエラーになります。
gitは空ディレクトリーを履歴管理できない。何かファイルが必要。


<<nowiki>https://notabug.org/gnusocialjp/gnusocial/src/main/docker/development</nowiki>> にDockerでの起動方法があります。`docker compose up -d` を実行するだけでlocalhostでアクセスできます。
logなど維持したい空ディレクトリーに、以下の内容の.gitignoreを置く。
!.gitignore
.gitignore以外を無視する。これで.gitignoreのみがあるので管理できる。


私とあなたとの環境の違いを排除したいので、dockerのインストールだけ頑張って、それでdockerでも簡単に動作確認してくれませんか?
====== 指定ファイルのみ除外 ======
*
!.gitignore
ディレクトリーを残す以外 (.gitignore1ファイル以外) に、サンプルファイルなど複数ファイルを残したい場合は、上記のように*で最初に全部除外して指定ファイルのみ含める。/は必要に応じてつける。


==== alternative ====
===== gitattributes =====
Ref: [https://wiki.debian.org/DebianAlternatives DebianAlternatives - Debian Wiki].
[https://git-scm.com/docs/gitattributes Git - gitattributes Documentation]


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


=== XAMPP ===
* text
 
* eol
==== ポート番号変更 ====
* working-tree-encoding
[https://qiita.com/neneta0921/items/3c2f9ac8ea9b5bcfc6e6 Xamppでポート競合を防ぐ方法 #PHP - Qiita]
* ident
* filter
* diff
* merge
* conflict-marker-size
* whitespace
* export-ignore: git archiveなどに含めないことをマーク。
* export-subst
* delta
* encoding


XAMPP Control PanelのConfigから変更可能。
===== ファイルのインデックスのみ削除 =====
git rmは単独だと、gitの履歴とローカルファイルからも削除する。追跡対象から削除のみで、ローカルファイルとして残したい場合、--cachedを指定する。
git rm --cached


phpmyadminはConfigのphpmyadminで、Servers.portを追加する。
==== gitk ====


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


==== About ====
==== Other ====
[https://ja.wikipedia.org/wiki/Cron cron - Wikipedia]


UNIX系OSのジョブ管理ツール。タスクの定期実行を可能にする。
===== 他のブランチとの同一化 =====
git diff HEAD master | patch -p 1
patchの他にgit applyでもいい。


cronの名前は時間を意味するギリシア語chronosに由来する。
===== .netrc =====
https://social.senooken.jp/conversation/1573147#notice-2217499


指定した時間に1回だけ実行するなら、atがある。電子メールの送信などで役立つ。
Gitのパスワード入力の省略方法に~/.netrcがある。


==== Format ====
しかし、man netrcするとわかるけど、これはもともとFTPのためのもの。なぜGitで使えるんだ?Gitの文書で言及がない。
cronの動作はcrontab (cron table) ファイルで指定する。


以下の形式になっている。
In conversation Thursday, 21-Feb-2019 10:58:47 JST from web permalink
# ┌───────────── 分(0〜59)
# │ ┌───────────── 時(0〜23)
# │ │ ┌───────────── 日(1〜31)
# │ │ │ ┌───────────── 月(1〜12)JAN-DEC
# │ │ │ │ ┌───────────── 曜日(0〜6〈日〜土〉、一部のシステムでは7も日曜日) SUN-SAT
# │ │ │ │ │
# │ │ │ │ │
# * * * * * [予約するコマンド]
日時部分はいくつか指定方法がある。


* *: すべて。
せのお (妹尾 賢)せのお (妹尾 賢) in reply to
* */n: nごとに実行 (*/5)
* ,: 複数の時間間隔を指定 (1,2,3)
* -: 範囲。
* %: コマンド内の%はエスケープされていないと改行文字に変換され、標準入力としてコマンドに渡される。


ユーザーはcrontab -eで自分の設定ファイルを編集できる。crontabファイルの直接編集は非推奨で、crontabコマンドでの修正が推奨されている。
理由が分かった。


==== Command ====
1. Gitはhttpとhttpsの通信にcURLを使っている。


* 編集: crontab -e
<nowiki>https://github.com/git/git/blob/master/INSTALL#L141</nowiki>
* 表示: crontab -l
* 削除: crontab -r


-u: 実行ユーザー指定。
2. cURLが.netrcにも対応しているから。


==== Log ====
<nowiki>https://ec.haxx.se/usingcurl-netrc.html</nowiki>
/var/log/cron


[https://askubuntu.com/questions/85558/verify-if-crontab-works cron - Verify if crontab works - Ask Ubuntu]
=== GitHub ===


デーモン自体の確認は以下。
==== Account ====
  systemctl status cron
  Username may only contain alphanumeric characters or single hyphens, and cannot begin or end with a hyphen.
systemctl restart cron
ユーザー名は、英数字と-のみが使用可能。


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


=== Keybind ===
=== 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の検討が不要になる。
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-クリック
=== Phorge ===
* c-s-alt-矢印
[https://we.phorge.it/ Home]
ジャンプ


* 括弧ジャンプ: C-S-\
PhorgeはPhabricatorのフォーク。


=== Config ===
==== About ====


==== Default terminal ====
===== Introduction =====
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].
[https://we.phorge.it/book/phorge/article/introduction/ ◉ Introduction]


[F1]-[Terminal: Select Default Profile]
以下が主な機能。


=== cscope ===
* コードレビューツール=Differential
cscope用のプラグインが何個かある。
* リポジトリーブラウザー=Diffusion
* バグトラッカー=Maniphest
* ウィキ=Phiriction


* [https://marketplace.visualstudio.com/items?itemName=xulion.codescope scope4code - Visual Studio Marketplace]
GitHubの自己ホスト。
* [https://marketplace.visualstudio.com/items?itemName=SeungukShin.cscope-code cscope-code - Visual Studio Marketplace]


scope4codeのほうがいろいろできそうだが、うまく動作しなかった。使い方がよくわからない。
===== Phabricator =====
[[wikipedia:Phabricator|Phabricator - Wikipedia]]


cscope-codeはシンプルだが動作した。こちらを当分使うことにする。
PhabricatorはもともとFacebook社内のBTSシステム。PHP製。2021-06-01に開発終了。


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


=== Vim ===
* AngularJS
* Discord
* Facebook


* [https://marketplace.visualstudio.com/items?itemName=vscodevim.vim Vim - Visual Studio Marketplace]
==== Install ====
[https://we.phorge.it/book/phorge/article/installation_guide/ ◉ Installation Guide]


VSCodedでVimのキー操作を使うためのプラグイン。これが一番人気。いや、Vimのエミューレーターは中途半端な感じだから使わないほうがいいかな。
[https://ipv6.rs/tutorial/Ubuntu_Server_Latest/Phorge/ Self Host with IPv6rs - IPv6 Provider - How to Install Phorge on Ubuntu Server Latest]


=== Extension ===
===== Requirement =====
CSS
LAMP環境で動作する。


Tailwind CSS IntelliSense
共用ホストでも動作するが、一部機能しない。通常コンピューターを推奨している。


==== PHP ====
* MySQL: 5.5以上。
Laravel Blade Snippets
* 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 <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
 
"mysql.host": "localhost", "mysql.user": "phorge", "mysql.pass": "password", "mysql.port": 3306, "mysql.charset": "utf8", "mysql.database": "phorgedb"
後は開くだけ。


===== PHP Intelephense =====
===== Config =====
Ref: [https://marketplace.visualstudio.com/items?itemName=bmewburn.vscode-intelephense-client PHP Intelephense - Visual Studio Marketplace].
[https://we.phorge.it/book/phorge/article/configuration_guide/ ◉ Configuration Guide]


VSCodeのPHPの補完拡張として人気が高い。
以下のコマンドでユーザーを認識させる。
phorge/ $ ./bin/storage upgrade --user <user> --password <password>


====== Quick Start ======
==== Diffusion ====
設置後、しておくべき設定がある。


* Go to <code>Extensions</code>.
===== Hosting =====
* Search for <code>@builtin php</code>
[https://we.phorge.it/book/phorge/article/diffusion_hosting/ ◉ Diffusion User Guide: Repository Hosting]
* Disable <code>PHP Language Features</code>. Leave <code>PHP Language Basics</code> enabled for syntax highlighting.


VSCodeの [PHP Language Features] を無効にしておくとのこと。
== Shell ==


後は、.php以外の拡張子でPHPファイルがあれば、関連付けを追加するとか。
=== Shell Command Language ===


====== Module ======
==== Compound Commands ====
peclなどPHPの標準モジュールで一部認識できないものがある。
[https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/utilities/V3_chap02.html#tag_18_09_04 Shell Command Language]


[https://stackoverflow.com/questions/62258598/undefined-type-imagick-in-vscodes-intelephense php - Undefined type 'Imagick' in VSCode's intelephense - Stack Overflow]」にあるように、そういう場合は [Settings]-[Stubs] で追加するとよい。
===== Case Conditional Construct =====
case word in
    [(]pattern1) compound-list;;
    [[(]pattern[ | pattern] ... ) compound-list;;] ...
    [[(]pattern[ | pattern] ... ) compound-list]
esac


====== Coding ======
* 未マッチで終了ステータス0。
Ref: [https://beyondjapan.com/blog/2020/02/intelephense-vscode-php/ VSCode で PHP 開発するならインテリセンス最強の intelephense を使おう | 株式会社ビヨンド].
* pattern部分: シェル展開が有効。他はglob。
* |でOR検索相当。
* 最後のパターンの;;は省略可能。if文のようにも使える。
* 全パターンの捕捉は最後に*。空でもマッチする。?は最低1文字必要。


intelephenseでコード補完を認識しやすい書き方というのがある。
BREでは未対応な|のORマッチに対応しているのが最大の特徴。文法なのでコマンドを実行せず早い。grepを使わずにできるだけこちらを使ったほうがいい。


まず、型をつけられるものはつける。<syntaxhighlight lang="php">
=== ワイルドカード ===
function superMethod()
ワイルドカードで.始まりのファイルをマッチさせたい。
{
    /** @var AwesomeService $awesomeService */
    $awesomeService = $this->app->make(AwesomeService::class);
    $awesomeService->awesomeMethod();
}
</syntaxhighlight>ローカル変数も型名を指定する。これをしないと、インスタンスでコード補完が効かない。


== Project ==
以下ならマッチするが、ブレース展開 (brace expansion) はPOSIX shでは使えなかった気がする。
echo {.*,*}


* [https://gigazine.net/news/20240217-open-source-non-code-contribution/ オープンソースの開発プロジェクトではコーディング以外のドキュメント化やサポートなどの貢献が特に重要 - GIGAZINE]
=== BOM ===
* [https://gigazine.net/news/20240229-open-source-project-business/ オープンソースプロジェクトを有料化して月収100万円の事業家に転身したソフトウェア開発者 - GIGAZINE]
[https://stackoverflow.com/questions/3127436/adding-bom-to-utf-8-files unicode - Adding BOM to UTF-8 files - Stack Overflow]


== DB ==
ExcelでUTF-8ファイルを開けるように、UTF-8のBOMをファイルにつけたい。
printf '\xEF\xBB\xBF' > with_bom.txt
上記コードでBOMを最初に書き込んで、後は追記する。


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


===== 画像データのパス/BLOBでの格納 =====
==== 変数 ====


* [https://stackoverflow.com/questions/1347461/saving-images-files-or-blobs database - Saving images: files or blobs? - Stack Overflow]
===== 特別 =====
* [https://stackoverflow.com/questions/3748/storing-images-in-db-yea-or-nay database - Storing Images in DB - Yea or Nay? - Stack Overflow]
* NF: 列数。列の全表示などで使う基本的で重要な変数。
* [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]
* NR: 行番号。
* [https://teratail.com/questions/296506 データベースに画像を保存するメリット・デメリットと必要性について]
* [https://teratail.com/questions/81233 データベースに画像を保存するのはありでしょうか?]


画像のファイルサイズが1MB以下の場合は問題ない。が、それ以外だと問題があるので、ファイルパスで扱うのがいいらしい。
===== スコープ =====
[http://www.fukano.jp/study_of_awk/basic/basic08.htm 変数のスコープ]


==== カラム順序 ====
関数の仮引数のみ、ローカル変数扱いで、それ以外はグローバル変数。
テーブルのカラム・列の順序。これに意味があるのか?カラムを追加する場合などに影響がある。


* [https://teratail.com/questions/26532 MySQLでカラムの順番は重要ですか?]
==== 文/statement ====
* [https://teratail.com/questions/97539 定義するカラムの順番]
* [https://qiita.com/Tachy_Pochy/items/7d8d16611adcb5a08cbe テーブルのカラムを増やす際に末尾に追加するのではなく、カラムの並び順を変更したい #考え方 - Qiita]
* [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]
* [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]


パフォーマンスに影響がある。特に下2個の情報が参考になる。
* actions
** if/else
** while/do...while/for
** break/continue
** delete
** next
** exit
* output
** print
** printf


基本的に、頻繁に使用する列 (主キー、外部キー、頻出検索、頻出更新の順) を先頭に配置する。ただし、null許容は全体的に後ろ。null許容の中でも頻度順にする。
==== 関数 ====


ディスクスペースの利用率、使用するデータの効率などに影響がある模様。
===== 組込関数 =====


==== NULL ====
* Arithmetic
Ref: [https://qiita.com/daichi_yamazaki/items/ea3516080948e95bbf26 NOT NULL 制約をつけるべきカラムとは #PostgreSQL - Qiita].
** atan2
 
** cos
絶対に必要な項目にNOT NULL制約をつける。NULLを許容する列は、最後のほうに集めると、ストレージなどの効率がいい。
** sin
 
** exp
例えば、取得に失敗した場合に、値をどうするのか?などを考えるとよい。
** log
 
** sqrt
==== int/string ====
** int
 
** rand
* [https://stackoverflow.com/questions/747802/integer-vs-string-in-database language agnostic - Integer vs String in database - Stack Overflow]
** srand
* [https://teratail.com/questions/259465 データベースの値の持ち方は文字列にするか数字にするか迷っています]
* String
 
** gsub
データベースのカラムでIDやコード類を定義する場合、型をintなどの数値系、charなどの文字列系にするかの議論がある。
** index
 
** length
* WHEREの範囲、算術計算など数値計算が伴うなら数値。データを何に使うかの意味論が重要。
** match
* 数値のほうが高速。
** split
* 郵便番号のように先頭が0つく場合、文字列。
** sprintf
* 数値だと、auto incrementで登録時の重複除去を保証できる。
** sub
* 値を変更する可能性がないなら数値。
** substr
* 文字列型だと文字数の検討が必要。
** tolower
 
** toupper
==== INT/BIGINT ====
* I/O
** close
** getline
** system


* [https://qiita.com/tk20211228/items/fbed24e7c97bf10112a0 MySQLにおけるint型IDの限界とクラッシュ回避のための対策 #MySQL - Qiita]
print/printfは関数ではなく、statement/文扱い。
* [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型で問題ない。
==== ヘッダー出力、列別最大長さ出力。 ====
<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>


BIGINTなら、1日100万件で25269512429年。BIGINTならほぼ問題ない。
==== CSV ====
[https://qiita.com/ko1nksm/items/19407c1c53cbbc50569a シェルスクリプトの実験のために作った POSIX 準拠 awk 実装の CSVパーサー (RFC4180対応) #ShellScript - Qiita]<syntaxhighlight lang="awk" line="1">
# csvparser.awk


ただ、BIGINTはINTの2倍のサイズになるのでストレージも消費する。よく考えておく。
## Usage
# awk -f csvparser.awk data.csv


BIGINTでも足りない場合、プライマリーキーを文字列にして、UUIDやhash値を使う。
# 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 }
[https://jsol-datamanagement.com/solution/solution-575/ マスタデータって何?マスタデータについて詳しく解説! - J-MDM/Snowflake]
{
 
    idx = 0
ユーザー、顧客や拠点の情報など、ベースとなるデータのこと。
    sub(/\r$/, "")
 
    while ($0 != "") {
マスターの他に、トランザクションというのもある。これは、売買などシステムや業務の稼働に伴って生じるデータ。
        if (match($0, /^(["]([^"]|["]["])*["]|[^,"]*)(,|$)/)) {
 
            fields[++idx] = ""
==== DB ID ====
        } else if (match($0, /^["]/)) {
DBのIDの採番規則。非常に重要。全体のパフォーマンスにも影響する。
            fields[++idx] = substr($0, 2)
 
            for (;;) {
[https://zenn.dev/praha/articles/3c84e3818891c3 idをautoincrementして何が悪いの?]
                if (getline == 0) exit 1
 
                sub(/\r$/, "")
[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]
                if (match($0, /^([^"]|["]["])*["](,|$)/)) break
 
                gsub(/["]["]/, "\"")
# <mark>生成されたIDは時間順に並べ替え可能である必要がある</mark>(例えば、写真 ID のリストは、写真に関する詳細情報を取得せずに並べ替えることができます)
                fields[idx] = fields[idx] "\n" $0
# ID は理想的には 64 ビットである必要があります (インデックスが小さくなり、Redis などのシステムでより優れたストレージを実現するため)
            }
# システムには、新しい「可動部分」をできるだけ少なく導入する必要があります。私たちが非常に少数のエンジニアで Instagram を拡張できたのは、信頼できるシンプルでわかりやすいソリューションを選択したことが大きな理由です。
            fields[idx] = fields[idx] "\n"
 
        } else {
Instagramは独自の計算式でIDを算出している。
            exit 1
 
        }
日時、ユーザーID、自動増分値。
        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
}


この3要素で構成して算出している。これでバッティングせずに時間ソートで64ビットで収まる。よく考えられている。
</syntaxhighlight>awkのCSVパーサー。先頭のBOMはあると認識できないので、tail -c +4でBOMを除外して使う。
tail -c +4 data/101543.csv | awk -f csvparser.awk


==== Sharding ====
=== Other ===
[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]


シャーディング。DBの負荷分散の手法。
==== binary ====
[https://qiita.com/ko1nksm/items/dc8f247cdc5b7b58b736 POSIX準拠のシェルスクリプトでバイナリデータを扱う #Bash - Qiita]


データをレコード・行単位で水平分割して、複数のデータベースサーバーに分散して記録する。
バイナリーデータの読込はodコマンド。なければhexdump。


分散したDBの単位をシャードと呼んでいる。データが増大しても台数を増やせば問題ない。
書込はprintf。


ただし、どのデータがどのサーバーで記録しているかを把握する必要がある。ハッシュ値などから計算する。
head/tailの-cはPOSIXで使えたか?


==== 親子関係 ====
== cmd.exe ==
親子関係、ツリー構造、階層構造を表現したいことがある。


[https://teratail.com/questions/281348 1つのテーブルで親子関係を管理する方法]
=== Control block ===


基本的に、親コードのカラムをどこかのテーブルに持たせて対応させる。
==== for ====
あくまでコマンド。


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


==== Standard ====
* [https://chicagopile1-75.hatenablog.com/entry/2018/05/23/143502 バッチファイルで2重ループ - ハムスターに飼われる院生のブログ]
[[wikipedia:ISO/IEC_9075|ISO/IEC 9075 - Wikipedia]]


ISO/IEC 9075がSQLの標準。標準外のSQL/関数は独自実装なので扱いには注意が必要。標準のみの使用が望ましい。
* [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/]


ANSI SQLと呼んだりするらしい。
ネストはできない。二重ループしたければ、関数にしてそれを呼び出す。


[[wikipedia:List_of_SQL_reserved_words|List of SQL reserved words - Wikipedia]]
=== bitsadmin ===
Windowsでのファイルダウンロードコマンド


ここに標準SQLの予約語一覧がある。
Windows 7以降ではbitsadminコマンドがあり、これがwget相当となる。


=== Naming ===
書式:
bitsadmin /transfer <job name> <URL> <output path>
<job name>と<output path>は必須なので注意する。


==== IDとコード ====
=== certutil ===
Windowsでのハッシュの確認に使える。
certutil -hashfile file


* [https://atmarkit.itmedia.co.jp/bbs/phpBB/viewtopic.php?topic=30818&forum=26 「列名の付け方(~CD or ~ID ?)」(1) Database Expert - @IT]
SHA1 ハッシュ (対象 C:\moconavi\windows\Moconavi\ext\chromium\moconavium.exe):
* [https://irof.hateblo.jp/entry/2021/10/26/181920 コード、区分、フラグ、IDと名前。 - 日々常々]
e0da85b04b6970ac1f0c33db7a9ad607fdbd44eb
CertUtil: -hashfile コマンドは正常に完了しました。


コードは広い概念。
=== rlogin.cmd ===
 
コマンドキーの送信を自動化できる?
IDはコードの内、一意なもの。
rem rlogin.cmd
 
==== 命名規則 ====
@Echo off
* [https://webapp.perlzemi.com/blog/20191113074356.html データベースのテーブル名とフィールド名の命名規約 - Perl Webアプリ開発入門]
Set SERVER=192.168.0.0
* [https://www.yiiframework.com/wiki/227/guidelines-for-good-schema-design Guidelines for good schema design | Wiki | Yii PHP Framework]
Set USERNAME=
 
Set PASSWORD=
DBスキーマの命名規則はあまりない。Yiiの規約がけっこうしっかりしている。
 
Cmdkey /generic:TERMSRV/%SERVER% /user:%USERNAME% /pass:%PASSWORD%
* 複数形ではなく単数形でデータベースのテーブルに名前を付ける
Start mstsc /v:%SERVER%
* フィールド名の前にDBテーブル名を追加しない
Timeout 5
* モデルクラス名にテーブルプレフィックスを含めない
Cmdkey /delete:TERMSRV/%SERVER%
* テーブルのID列に「id」という名前を付けます
* 意味のある主キー名を避ける
* データベーススキーマで外部キーの関係を定義する
* 「id」で終わる外部キーフィールドに名前を付ける
* 単数形/複数形の性質を反映する名前関係を行う
 
==== Convention ====
Ref: [https://style.potepan.com/articles/26931.html SQLで大文字・小文字のルールはある?区別・変換方法も一緒に教えます! | ポテパンスタイル].


予約語以外、基本的に全部小文字で、複数単語はハイフン区切りにしたほうがいいらしい。
=== 実行中プロセスのパスの確認 ===
出典: [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


==== enum/string ====
=== 簡易編集モード/挿入モード ===


* [https://zenn.dev/tonbi_attack/articles/fb796ac3cf9720 DBで区分値などのCODEは数値ではなく文字列を利用するべき]
* [https://softantenna.com/blog/windows-10-command-prompt-no-stop/ 【Tips】Windows 10のコマンドプロンプトが意図せず止まってしまう問題を回避する方法 | ソフトアンテナ]
* [https://teratail.com/questions/154006 区分値は数値にすべきか意味のある文字列にすべきか]
* [https://superuser.com/questions/419717/windows-command-prompt-freezing-randomly Windows command prompt freezing randomly - Super User]


区分系データを数字で持つか、文字列で持つか。
Windows 10のcmd.exeは [簡易編集モード] が有効になっており、コマンドプロンプトを左クリックすると、テキストの選択が始まる。テキスト選択中はコマンドの実行が止まる。長時間かかるコマンドの実行中に誤操作で止まると困るので、これは無効にしたほうがよい。


文字列だとわかりやすい。数字で持つと、意味の把握にカラム定義など、別の資料を確認する必要がある。アプリ側で表示に毎回そのマップや変換が必要になる。
cmd.exeを起動-左上のアイコンをクリック-[規定値]/[プロパティ]-[オプション]-[□簡易編集モード] を選ぶ。


数値で必要ならマスターの主キーにする。基本は文字列でいいと思う。
そのほか、 <code>git log</code> のような制御が移るコマンドを実行してしばらくすると、操作できなくなる。


=== SQL ===
[□挿入モード] にすると回避できる模様。


==== JOIN ====
== Web ==
[https://products.sint.co.jp/topsic/blog/sql-bootcamp-07 SQLのテーブル結合(JOIN, UNION, NATURAL)を覚えよう!基本構文と使用例を解説]


外部テーブルと外部キーで結合の方法がいくつかある。
=== URL ===


* INNER JOIN: AND。両方のテーブルにある項目のみ。
==== クエリー配列 ====
** SELECT ... FROM ... INNER JOIN テーブル名 ON 項目A = 項目B
* OUTER JOIN: OR。片方がなくても。
* CROSS JOIN: 全組み合わせ。
* NATURAL: 同名項目を取得。
* UNION/UNION ALL: 2以上のSELECT結果の結合。
他にWHEREで結合する方法がある。


結合すると、同名カラムは上書きされる。必要なら、select column as column_nameで別名をつける。
* [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]


結合する場合、同じ値だから通常は問題ない。
やり方がいくつかある。


[https://zenn.dev/kasamifutoshi/scraps/8c8cf445f50445 【Laravel】目的別クエリビルダの記述方法まとめ(記事を書く前の整理用)]
# 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


addSelectで列名を地道に追加する。これが確実。
データが決まっているならcsvがシンプル。


[https://rimane.net/inner-join-1037/ 結合したテーブルに同じ名前のカラムがあっても正しく取り出す方法【MySQL+PHP】 - りまねどっとねっと]
=== HTTP ===
[https://www.rfc-editor.org/rfc/rfc9110.html RFC 9110: HTTP Semantics]


GroupConcatで文字列で結合する。
==== Content-Disposition ====
[https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Content-Disposition Content-Disposition - HTTP | MDN]


[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]
[https://datatracker.ietf.org/doc/html/rfc6266 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


==== 一括更新 ====
* [https://datatracker.ietf.org/doc/html/rfc7578 RFC 7578 - Returning Values from Forms: multipart/form-data]
Ref: [https://zenn.dev/rescuenow/articles/5b16ab6c4d9cf9 MySQLで複数行を一括更新するクエリの実装方法].
* [https://qiita.com/sivertigo/items/14957200af5ad953d63b Multipart/form-dataの仕様メモ #HTTP - Qiita]


ELT/FIELDを併用すれば一括更新可能とのこと。
ファイルアップロード用のMIME type。


==== UPSERT ====
リクエストヘッダー
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プログラミング入門].
Content-Type: multipart/form-data; boundary=--hogehoge
 
リクエストボディー
INSERTするかUPDATEするか、一度SELECTで値の有無を確認してから本来しないといけない。SQLを2回実行必要で、処理が無駄になるので、これを1回で行う。これがUPSERTと呼ばれるもの。ただし、UPSERTというSQLがあるわけではなく、DBごとの独自拡張になる。
--hogehoge
 
Content-Disposition: form-data; name="user_name"
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という文を使う。
Content-Type: text/plain
 
==== NULLを含むLIKE ====
test
[https://stackoverflow.com/questions/3924400/like-does-not-accept-null-value sql - like '%' does not accept NULL value - Stack Overflow]
--hogehoge
 
Content-Disposition: form-data; name="email"
[https://qiita.com/umekikazuya/items/61c16a36824c334e31e5 【SQL】NULL値を制御/SQLマスターへの道「COALESCE」 #初心者 - Qiita]
 
sample@mail.com
LIKEで文字列検索する際、SELECT * FROM DB WHERE <column> LIKE '%%';であいまい検索してもNULLの場合ヒットしない。
--hogehoge
  where COALESCE([table].[column],<nowiki>''</nowiki>) like '<parameter>'
Content-Disposition: form-data; name="gender"
  IFNULL([table].[column], <nowiki>''</nowiki>) like '%'
   
COALESCEかISNULLで引数に空文字を指定するとうまくいく模様。
  male
 
--hogehoge
COALESCEが標準なのでこれを使う。
Content-Disposition: form-data; name="user_profile" filename="image.jpeg"
 
Content-Type: image/jpeg
COALESCE (コアリース) は引数のリストから、最初の非NULLを取得する。NULLを含むデータの処理に便利。
 
\xff\xd8\....
ISNULL(<value>, <orValue>) はCOALESCEの引数2個版。理由がないならシンプルなISNULLを使うとよい。
--hogehoge--
ヘッダーでmultipart/form-dataを明記して、ボディーでデータを指定する。


同じ名前の関数で、動きが違う。
[https://weblabo.oscasierra.net/curl-post/ curlコマンドでPOSTする, 様々な形式別メモ |]


「[https://mysql.sql55.com/sql/mysql-isnull-coalesce.php MySQL の ISNULL()・COALESCE() - MySQL の基礎 - MySQL 入門]」MySQLのISNULLは引数1個で、boolを返すだけ。
curlでの送信理由。


COALESCE() や IFNULL() を使うしかない。
-Fで送信データをname=data形式で指定する。ファイルの内容を指定する場合、@filenameで指定する。これを指定すると、リクエストボディーのfilename扱いにしてくれる模様。-Fを指定すると、-H 'Content-Type: multipart/form-data'が自動付与される。たぶん、-dと同様に-X POSTもつく。
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などをうまくやってくれるのだと思う。


NULLIF/COALESCEは標準。
リクエストボディー全体をファイルデータにする場合。
curl -X POST -H 'Content-Type: image/jpeg' --data-binary @/var/tmp/sample.jpg <nowiki>https://xxxxx.net/xxxxxx</nowiki>


MYSQLのNULLIFは引数1=引数2の場合、trueでNULLを、そうでなければ1個目の引数を返す。IFNULLと逆。
=== IP address ===
<code>NULLIF(引数1, 引数2);</code>
出典: [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【公式】| 株式会社グローカルネット]。
以下の CASE 文と同等です。
<CASE
WHEN 引数1 = 引数2
THEN NULL
ELSE 引数1
END;


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


* [https://dbflute.seasar.org/ja/manual/function/genbafit/implfit/datefromto/ 日付範囲の条件指定を定型化(安全に) | DBFlute]
取得方法がいくつかある。
* [https://zenn.dev/shuhei_takada/articles/d1444e409330ad SQLで日付の範囲指定をしたいときにありがちなミス]


注意点がある。
* 契約しているプロバイダでオプションとして申し込む方法
* 固定IPアドレスに対応しているSIMを契約する方法
* '''VPNを利用した固定IPアドレスの提供会社を利用する方法'''


2024-01-01から2024-01-02としたい場合、いくつか記述方法がある。
VPNの固定IPアドレスが安いらしい。ryoかsuwakoが解説していた気がする。
where PURCHASE_DATETIME >= '2024-01-01' and PURCHASE_DATETIME <= '2024-01-02'


SELECT * FROM users WHERE id BETWEEN 2 AND 4;
=== Authentication ===
SELECT * FROM users WHERE id >= 2 AND id <= 4;
認証方式がいくつかある。HTTPで定義される認証方式 (HTTP認証) が有名。
ただし、上記はまずい。2024-01-02T00:00までしか判定されない。方法がいくつかある。


# DATE関数で日付部分のみ抽出: <code>SELECT * FROM users WHERE DATE(created_at) BETWEEN '2022-01-01' AND '2022-01-02'</code>
==== Basic認証 ====
# 1日進めて小なりで抽出:  <code>where PURCHASE_DATETIME >= '2024-01-01' and PURCHASE_DATETIME < '2024-01-03'</code>
出典: [https://ja.wikipedia.org/wiki/Basic%E8%AA%8D%E8%A8%BC Basic認証 - Wikipedia]。
# ミリ秒まで指定: <code>DATETIME <= '2010-10-31 23:59:59.999'</code>


3はミリ秒の.999の部分がどこまでいるのか?という問題があるしスマートではない。
Authorization HTTPヘッダーにBasicのあとに [username:password] をBASE64でエンコードして送信する認証方式。
GET /private/index.html HTTP/1.1
Host: example.com
Authorization: Basic cm9vdDpwYXNzd29yZA{{=}}{{=}}
盗聴や改ざんが簡単だが、シンプルという利点がある。


1-2で対応するのがよい。1がいいか。
==== OAuth ====
Ref


==== Echo/SELECTだけでtable作成 ====
* [https://ja.wikipedia.org/wiki/OAuth OAuth - Wikipedia]


* [https://takuya-1st.hatenablog.jp/entry/2017/01/18/133015 SQLでecho/print するための代替方法 - それマグで!]
OAuth (オーオース) 権限の認可のための標準。OAuth 2.0が最新の標準。


* [https://qiita.com/Hiraku/items/aafc3b58d2efa4e97511 SQL SELECT基礎(3) その場で表を作る #SQL - Qiita]
以下が登場人物。


SQLでechoのようにリテラル表示したいことがある。
* resource owner: あるサイトのユーザー。
select '##  A ' as <nowiki>''</nowiki>;
* resource server: あるサイトのユーザーのデータの保有サーバー。
asでカラム名を空にすると、必要なものだけになる。
* clent: クライアントアプリ。リソースサーバーのデータを使用したい。
* authorization server: クライアントにサイトへのアクセスを認証するサーバー。アクセストークンを発行して行う。


UNION ALLで複数のselectを結合できる。
アクセストークンが実質的なパスワードのようなものだが、resource serverのパスワードを直接渡していない点が重要な違い。パスワードを直接渡さないことで、機能別に権限を細かく利用可否を制御できる。
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 (既定値) の場合
|}
基本的に、以下と思っておけばいい。


* 一重引用符: 文字列定数
# client->resource owner: Authorization Request。ここでユーザーが手操作でアクセスを承認する。
# 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


* 二重引用符: 引用識別子
Consumer Key/Secret: アプリ識別用のID/PW。


引用識別子は、テーブル名、カラム名など、DB中のオブジェクト。
Access Token: サイトにアクセスするためのパスワード。


=== phpMyAdmin ===
=== API ===


==== テーブル定義出力 ====
==== 複数レコードの登録 ====
[https://superuser.com/questions/168595/how-to-export-mysql-schema-from-phpmyadmin database - How to export mysql schema from phpmyadmin? - Super User]
[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を作るしかなくないか?


* フォーマット=Texy! text
[https://www.yamarkz.com/blog/rest-web-api-practice REST WebAPIのプラクティス | yamarkz.com]
* 出力:◎出力をテキストで表示する
* フォーマット特有のオプション:ダンプするテーブル=構造


これで出力・表示すると使いやすい。
delete_bulkなどのような一括処理用のAPIを作るしかない。内部的には単一処理のAPIを作る感じだったとしても。


=== MySQL ===
==== パラメーター ====
[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]


==== SQL ====
パラメーターの指定に3種類ある。


===== カラム名検索 =====
# リクエストボディー
[https://qiita.com/dkwnm/items/3aa7be0bca95a2a75304 MySQLで指定されたカラム名を持つテーブルを検索する #MySQL - Qiita]
# クエリー
select table_name, column_name from information_schema.columns where column_name = '検索したいカラム名' and table_schema = '検索対象のデータベース名';
# パス


==== Type ====
パスはIDなどを指定する場合だけわかりやすい。それ以外のオプションはクエリーのほうがいい。
[https://dev.mysql.com/doc/refman/8.0/ja/data-types.html MySQL :: MySQL 8.0 リファレンスマニュアル :: 11 データ型]


データ型の書式がある。
ボディーは、通常サーバーのアップロード・ダウンロードデータとして使われる。クエリーはデータの指定に使う。


* DECIMAL(M [, D]): M=全体の桁数。D=内小数部の桁数。
この原則に従うとシンプルだろう。
* CHAR(M)/VARCHAR(M): M=格納最大文字数。CHARのM=0-255までで末尾はスペース。VARCHARはM=0-65535までで、可変長文字列で256以上もOK。末尾のスペースは削除される。先頭にプレフィクスの1-2バイトのデータを付与している。255バイト以下の文字列なら1バイト、256バイト以上なら2バイト追加。


===== Backup =====
* URIには長さの制限がある。
mysql -u username -p database_name <file.sql
* ボディー
** 引数が非常に多い場合。
** 画像などバイナリーデータ。
** キー・値構造を持たない場合。
* クエリー文字列
** 引数を簡単に確認できる。
** 共通の引数の場合。


==== Error ====
==== 検索機能のGET/POST ====


===== Error: [PDOException] PDO::__construct(): The server requested authentication method unknown to the client [caching_sha2_password] =====
* [https://stackoverflow.com/questions/20550514/post-or-get-in-a-search-form .net - POST or GET in a search form? - Stack Overflow]
* [https://www.petitmonte.com/database/mysql_authentication_plugin.html MySQL8.0以降で接続できない場合は「認証プラグイン」を変更する]
* [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になってから、認証方式が変わったらしく、そのままだと接続に失敗する。
検索機能にGETとPOSTのどちらを使うか?という議論がある。


PHP 7.1.16, 7.2.4 以降から対応しているらしい。それ以前だと設定が必要。
データ登録するわけなじゃないのだから、GETがいいんじゃない?


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


===== Character =====
GETのほうが検索条件をブックマークにできたり、URLを共有できるので、基本は便利。
[https://qiita.com/tfunato/items/e48ad0a37b8244a788f6 MySQLの文字コードとCollation #MySQL - Qiita]


DBで使用する文字セットと、その照合順序を選択できる。
==== レート制限対策 ====


文字コードはutf8mb4で問題ない。照合順序も基本はutf8mb4_binで問題ないと思う。
* [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 リクエスト数によるアクセス制限の対策方法 – 請求管理ロボ ヘルプ]


A ≠ a 区別する
いろいろ方法がある。


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


は≠ぱ≠ば 区別する
==== 指数関数的バックオフ ====


utf8mb4_general_ciは上2個を区別しない。
* [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> の合計に加算するか減算するか、ランダムで選択してください。


ただし、あいまい検索にすると、対象範囲が増えるので、少し遅くなる模様 ([https://yakst.com/ja/posts/5431 CharsetとCollationの設定がMySQLのパフォーマンスに与える影響 | Yakst])。
=== curl ===
HTTPの通信のコマンドラインでの確認でよく使う。


===== SQL mode =====
==== Basic ====
[https://dev.mysql.com/doc/refman/8.0/ja/sql-mode.html#sql-mode-combo MySQL :: MySQL 8.0 リファレンスマニュアル :: 5.1.11 サーバー SQL モード]
[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で送信する場合、ヘッダー指定が必須。


SQLの基本的な動きを制御する設定がある。以下で現在値を確認。
<nowiki>*</nowiki>-F: multipart/formのform指定。
  SELECT @@GLOBAL.sql_mode;
  curl -F "coolfiles=@fil1.gif;type=image/gif,fil2.txt,fil3.html"
SELECT @@SESSION.sql_mode;
  <nowiki>http://www.example.com/postit.cgi</nowiki>
以下で設定。
@でfilename相当の指定。;でmime typeも指定できる。
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。
@/</;type=自体を送信したい場合、-Fではなく、--form-stringを指定する。


カンマで区切って複数指定できる。
==== curl: (60) SSL certificate problem: self-signed certificate ====
Ref: [https://linuxfan.info/curl-insecure curlで「自己署名証明書」を受け入れるには【curl: (60) SSL certificate problem: self signed certificate】 | LFI].


モードの値としては、ANSIが重要。基本はこれでよい。
--insecureオプションを指定すると、localhostなどでの自己署名証明書を許可する。


== Office ==
==== 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]


=== Font ===
以下のように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


* [https://moji.or.jp/ipafont/ IPAexフォントおよびIPAフォントについて | 一般社団法人 文字情報技術促進協議会]: 日本語の日本公式フォント。IPAexMincho/IPAexGothic。
curl: Failed writing body
* [https://itouhiro.github.io/mixfont-mplus-ipa/migu/ Miguフォント : M+とIPAの合成フォント]: Miguフォント。Migu 1C/Migu1M。IPAフォントとM+フォントの合成。半濁点の視認性が高かったり、コーディング用フォントとして手堅い。
curlは標準出力に全部書き込めたかチェックしているようで、head -n 1で切り捨てたらcurlはエラーになる。


日本語と英語でフォントを分けられないソフトがあったりするので、必然的に日本語フォントが優先される。
対策は、curl -sで出力を抑制するとのこと。これで解決。


* 明朝体: IPAexMinch
=== Wireshark ===
* ゴシック: Migu 1C
* 等幅: Migu 1M
* スライド: Migu 1C


以前はスライド用にMigMix 1P/Migu 1Pを使っていた。視認性が高いから。その後、2011-04-18にMigu 1Cとさらに視認性を重視したフォントが生まれた ([https://itouhiro.github.io/mixfont-mplus-ipa/changelog.html 変更履歴 : M+とIPAの合成フォント])。Migu 1Cでいい。
==== TLS ====
Ref: [https://www.toyo.co.jp/onetech_blog/articles/detail/id=36994 SSL/TLSの復号#1 ~Wiresharkの設定~ | 東陽テクニカ | “はかる”技術で未来を創る | ワン・テクノロジーズ・カンパニー].


=== Excel ===
Wiresharkで通信パケットを確認する場合、デフォルトでTLSで暗号化されているので、内容がわからない。WiresharkでTLSに対応しておく必要がある。


==== オートシェイプの全選択 ====
[Preferences]-[Protocols]-[TCP] を選ぶ。
Ref: [https://aka-aca.com/tips014-shapes-select-01/ シート上の図形(オートシェイプ)を全て選択した状態にするショートカットキー【エクセルTips】]


[C-g]-[セル選択]-[オブジェクト]
* ☑Allow subdissector to reassemble TCP stream
* ☑Reassemble out-of-order semgemnts


==== 日付の数値対策 ====
上記をチェックしておく。デフォルトでチェックされていた。
[https://tokusengai.com/_ct/17544077 【Excel】入力した日付が5桁の数字になるのを防ぐ「書式設定」の確認方法 | 特選街web]


[https://pentan.info/else/excel_date_number.html Excelの日付が数字になるときの対処法 - [その他 + その他] ぺんたん info]
続いて、セッションごとのPre-Master Secretを登録する。


日付のデータが5桁の数字になって困ることがある。
Chrome/Firefoxだと、環境変数SSLKEYLOGFILEを設定すれば、このファイルにTLSセッションキーを出力するので、これをWiresharkで読み込むことで、復号対応する。


これはセルの書式設定が、[標準] や [数値] になっているから。[日付] に変更すれば解決する。
以下のコマンド相当で、任意のファイル・場所にログファイルを指定する。
export SSLKEYLOGFILE=/tmp/sslkey.log
Macだとlaunchctlで設定しておくといい。これでWebブラウザー経由の場合は見えるようになる。


セル参照、数式の場合は、TEXT関数で表示形式を指定する必要がある。"yyyy-mm-dd"を指定しておくとよいだろう。
=== Security ===


=== Word ===
==== DoS攻撃 ====
いくつか対策方法がある。


==== キーワード変数 ====
* [https://lite.ip2location.com/ip-address-ranges-by-country?lang=ja 国別のIPアドレス範囲]
[https://mylife8.net/cross-reference-word-bulk-replacement/ 【Word】文書中に何度も登場する文字列を1か所変更するだけで他の箇所も一括で変更する方法 | My Life 8]
* [https://rakko.tools/tools/11/ IPアドレスから住所検索:国、地域の特定 | ラッコツールズ🔧]


例えば契約書などで、同じ氏名や住所が同一文書内に複数回登場することがある。一箇所変更すれば、全体も反映されるようにしたい。
サーバーログにIPアドレスが残るから、それで攻撃元の国を特定して、該当国を一括アクセス拒否。これが効果あるかもしれない。


ブックマークと相互参照を利用する。
攻撃元の国は途上国とかが多いだろうから。IPアドレスは簡単に変更できるが、国を変えるのはたいへんだろう。


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


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


==== テキストボックスの内部余白 ====
基本的に、バックエンドで主にチェックして、フロントエンドはUXの向上目的で実装する。データの重複チェックはDBアクセスが必要だったりするから。また、API経由などフロントがそもそもないケースもある。
[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]


テキストボックスに二重に余白がある。内部余白は、[Format]-[Text Attributes...] から変更可能。
ただ、社内システムのような、画面経由でしか使わない。悪者がほぼいないと思われるケースは、フロントエンドでの検証だけでも十分に感じる。


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


図形の配置でグリッドとスナップが重要。
* [https://www.youfit.co.jp/archives/4545 フォームの二重送信を防止する方法 - 福岡・東京のシステム開発会社 (株)ユーフィット]
* [https://qiita.com/syobochim/items/120109315f671918f28d さいきょうの二重サブミット対策 #JavaScript - Qiita]


グリッドの間隔類は、[Preferences]-[LibreOffice Draw]-[Grid] で設定する。
submitボタンのダブルクリック、リロード、ブラウザーバック・フォワードなど、フォーム周りで注意が必要な保安要素がある。


[Resolution] がグリッド () の表示間隔。その横の [Subdivision] はグリッド同士の細分化個数。グリッドをあまり細かくしすぎると、目が疲れる。
# ボタン連打
# ブラウザーバック
# リロード (PRG)


例えば、グリッドを1間隔にして、subdivisionを2にすると、0.5間隔でグリッドの間をスナップできる。
項目ごとにすべき対策が異なる。


=== LibreOffice Calc ===
===== 連打 =====


==== Formula ====
* [https://www.youfit.co.jp/archives/4545 フォームの二重送信を防止する方法 - 福岡・東京のシステム開発会社 (株)ユーフィット]
* [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]


===== evaluate =====
基本は、ボタンのsubmitのイベント内でdisabled=trueでの無効化。


* [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]
似た考え方で、スプラッシュのモーダル表示もあり。これがわかりやすいかもしれない。
* [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]
$("form").submit(function() {
* [https://ask.libreoffice.org/t/evaluate-math-expressions/104248 Evaluate math expressions - English - Ask LibreOffice]
  var self = this;
* [https://forum.openoffice.org/en/forum/viewtopic.php?t=3497 Apache OpenOffice Community Forum - [Solved] Evaluate a string - (View topic)]
  $(":submit", self).prop("disabled", true);
  setTimeout(function() {
    $(":submit", self).prop("disabled", false);
  }, 10000);
});
停止にしたら、二度通せなくなるので、タイムアウトで戻すとよい。


セル内のテキストを数式として評価してほしい場面に遭遇した。
=== Browser ===


例えば、画素数 (720x720) の合計。Excelだとevaluateという関数があるが、Calcにはない。マクロなどで頑張る。あるいは、数式ではないがF9で数式に変換できるらしい。
==== Chromium ====


==E-mail==
===== Extension =====
Chromme系で愛用拡張機能を列挙する。


===General===
* [https://chromewebstore.google.com/detail/create-link/gcmghdmnkfdbncmnmlkkglmnnhagajbm Create Link]:


====Naming====
==== devtool/開発者ツール ====


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


*webmaster
[Elements]-[Event Listeners]-[handler]-右クリック-[Show function definition] でイベントリスナー関数の定義を確認できる。
*support
*info
*service
*pr
*billing
*氏名


[https://news.mynavi.jp/article/20120315-mailaddress/ 売上をアップするメールアドレス、商機を失うメールアドレス | マイナビニュース]
===== イベント監視 =====
[https://stackoverflow.com/questions/3787555/how-to-find-out-which-javascript-events-fired How to find out which JavaScript events fired? - Stack Overflow]


[https://webtan.impress.co.jp/e/2015/03/31/19657 infoやwebmasterなど企業サイトが備えるべきメールボックスのルール、ご存じですか? | 編集長ブログ―安田英久 | Web担当者Forum]
monitorEvent関数で監視できるらしい。他に、FirefoxのFirebugのlog eventsでも監視できるらしい。


[https://rfc-jp.nic.ad.jp/rfc-jp/RFC2142-JP.txt rfc-jp.nic.ad.jp/rfc-jp/RFC2142-JP.txt]
==== Other ====
 
===== Windows Safari =====
 
* [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]


[https://www.tains.tohoku.ac.jp/news/st-news-23/3437.html <nowiki>SuperTAINS News No.23 [Page.5]</nowiki>]
一応ある。2012-05-09のSafari 5.1.7までWindows版が提供されていた。DL1531。


[https://fumidzuki.com/knowledge/109/ 【Mail】メールアドレス作成のガイドライン(RFC2142) – fumidzuki]
=== Other ===


公開用のメールアドレス。何にしようか考えていた。
==== Tool ====


<nowiki>RFC 2142</nowiki>でいくつか推奨されている。
* [https://web-toolbox.dev/ Web ToolBox | 開発者向けのオンラインツール]
* [https://tm-webtools.com/ TM - WebTools]


info@ support@ answer@ inquery@ contact@ pubic@
いくつかWeb関係の開発で役立つツール集を公開しているサイトがある。


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


=====develop=====
* [[wikipedia:Special-use_domain_name|Special-use domain name - Wikipedia]]
* [https://ja.wikipedia.org/wiki/.localhost .localhost - Wikipedia]


<html>
RFC 6761 で規定。RFC 2606<nowiki/>で予約。DNSに登録されることはないため、テスト目的で使用可能。ループバック (送信元にそのまま返す) インターフェイス。
<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がいいと思う。
IPv4=127.0.0.1/IPv6=::1とされている。


===== category =====
== Shared Host ==
目的に応じて使い分けたほうがよさそう。


[https://upa-pc.blogspot.com/2014/06/mail-security.html メールアドレスを何個ぐらい使い分けたら安全・快適に過ごせるのか - Dr.ウーパのコンピュータ備忘録]
=== Free ===
無料で使用可能な共用ホスティングサービスがある。


メールアドレス流出時の被害防止
==== スタードメイン無料サーバー ====
ドメインをセットで利用する必要があるものの、スタードメインのスタードメイン無料サーバーがけっこういい。


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


必要な数
jpドメインの金額が相場の中では安い方で、それに無料サーバーがついていくる点。


* 銀行・証券会社
* ディスク容量 20GB
* 知り合い
* DB 1GB
* ショッピングサイト


その他
ただし、SSHやコマンドは使えないので、FTPでWordPressを展開して設置するとか、そういう簡単な使い方だけ。ただ、それでもWordPressでWebサイトを構築するくらいなら十分だと思う。


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


メールアドレスの種類
==== メール ====


* フリーメール
* [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(コアサーバー)]


[https://afmasakun01.com/3373.html メールアドレスの種類とアフィリエイトにおける3つの使い分け方法 | アフィリエイト]
情報


* サービス登録用
* [https://www2.bwt.jp/wiki/?CoreServer_Mail_Custom CoreServer_Mail_Custom - PukiWiki]
* メルマガ購読用(捨てアド)
* [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の、できるかな?]


[https://d.hatena.ne.jp/okmount/20080505/1209914528 メールアドレスの使い分けかた(前編) - 学習する機械、学習しない人間]
ルールが特殊なので注意する。


[https://d.hatena.ne.jp/okmount/20080506/1210002001 メールアドレスの使い分けかた(後編) - 学習する機械、学習しない人間]
ゴミ箱に振り分ける場合。


これらを考えてどういう名前で何個用意するかを考える。
順1 で[<code>./.Trash</code>] を指定


とりあえずメインで使うmainというアドレスを一つ用意する。残りをどうするか。
順2


Webサイト公開用にcontact
* 条件:  [<code>.*</code>]
* 処理:  <code>./</code>、に振り分ける


* main: メインで使うメール。人に直接教えるときや,お金が絡む場合,ショッピングサイトなど実名が求められるような重要な内容にはこれ。こちらから送信するときもこれ。相手の顔が見えているとき。
条件部分には正規表現が使えるように見える。
* contact:受信専用,公開用。問い合わせ用。なんかフォーラムやブログのコメント欄やcontact usなどにこちらから問い合わせる時なども。相手の顔が見えないときなど。
 
* service: 基本的に受信専用,たまに返信。Webサービス登録用。
破棄にしないといけない。転送する場合、カスタムフィルターの中に転送を入れる。条件を.*にする。
* recruit:就職活動用。就職サイトとか転職エージェント,企業とやりとりするときはけっこうメール来るから。
 
カスタムフィルターにくせがある。
 
* エスケープ(\を前置する)が必要な文字は「'」「"」「|」「`」「~」「?」「!」
 
==== Value Domain ネットde診断 byGMO ====
 
* [https://www.value-domain.com/information/detail/?no=20240606-1 弊社レンタルサーバー上で運用中のドメインにおける自動セキュリティ診断開始のお知らせ | お知らせ - バリュードメイン]
* [https://www.value-domain.com/security/net-de-shindan/ Value Domain ネットde診断 byGMO - バリュードメイン]
 
2024-06-07 Friからバリュードメイン系の利用者に無料で提供しているセキュリティー診断ツール。
 
== Analytics ==
 
==== Exam ====
<nowiki>##</nowiki> About
 
<nowiki>https://gnusocial.jp/notice/4506679</nowiki>
 
<nowiki>###</nowiki> 全般
 
- マーケティング・ビジネス実務検定
 
- IMA検定
 
- Web検定
 
- ネットマーケティング検定
 
<nowiki>###</nowiki> 解析系
 
- ウェブ解析士
 
- GAIQ
 
- 統計検定
 
- Webアナリスト検定
 
GAIQが無料だしどうせ使うからいいかな。
 
<nowiki>https://wacul-ai.com/blog/access-analysis/google-analytics-method/gaiq/</nowiki>
 
<nowiki>https://www.plan-b.co.jp/blog/seo/12792/</nowiki>
 
<nowiki>##</nowiki> URL
 
- <nowiki>https://ceres-inc.jp/business-tips/recommended-webmarketing-shikaku/</nowiki>
 
- <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>
 
- <nowiki>https://digitor.jp/textbook/web-analytical-qualification/</nowiki>
 
=== Tool ===
サイト分析用のツールがいくつかある ([https://hidesunblog.com/blog-ranking-sites/ 2023年ブログランキング!おすすめブログランキングサイト比較【一般人向け】])。
 
* SimilarWeb
* Ubersuggest
* ahrefs
* 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ファイルをドラッグドロップで取り込むこともできる。