「Develop」の版間の差分

提供:senooken JP Wiki
(stash 復元)
(Confluence)
 
(同じ利用者による、間の54版が非表示)
35行目: 35行目:
Skyepで使用可能な絵文字の一覧。
Skyepで使用可能な絵文字の一覧。


== Coding ==
==== Confluence ====
ページの中で、 [作成] を選んでページを作ると、階層が勝手にできて、子ページへのリンクもできる。


=== タイムゾーン ===
== Tool ==
[https://qiita.com/dmikurube/items/15899ec9de643e91497c タイムゾーン呪いの書 #timezone - Qiita]


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


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


tz databaseのAsia/Tokyoなどの確実性が高い。
kscopeもこれか。
=== Regular Expression ===
正規表現。重要。覚えにくいが重要なものをメモしておく。


後ろからマッチ。cが置換対象。
Doxygen+GraphVizで関数コールグラフ


/[^c]*$/: cより右端
==== kscope ====
https:/github.com/ivan0124/Linux-programming/wiki/How-to-use-KScope-to-trace-code


=== glob ===
https:/sourceforge.net/projects/kscope/


* [https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/functions/glob.html glob]
http:/www.lemis.com/grog/software/kscope.php
* [https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/utilities/V3_chap02.html#tag_18_13 Shell Command Language]


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


使用可能な記号は以下3個。以下の3文字は\でエスケープできる。
cscopeの大文字小文字無視検索


* ?: 任意の1文字にマッチ。
<nowiki>http://vim.1045645.n5.nabble.com/how-to-search-with-cscope-ignoring-case-td5715043.html</nowiki>
* *: 任意の0以上の文字にマッチ。
* [: []内の1文字にマッチ。正規表現の各括弧と同じ。ただし、先頭の否定が^ではなく、!。


ファイル名マッチ時には、追加で特殊なルールがある。
DBを別にする必要がありそう。


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


globで.ファイルを含めたい場合、工夫が必要 ([https://www.php.net/manual/ja/function.glob.php PHP: glob - Manual])。
<nowiki>*</nowiki> ^と$は使えない。代わりに、\nを使う。
.[!.]* *
上記のように.ファイルのマッチとそれ以外を指定する必要がある。


<code>.[!.]*</code> は、<code>.</code>と<code>..</code>以外の.<code>.</code>始まりのファイルにマッチする。
<nowiki>*</nowiki> 文字列の囲みに一重引用符 (') は使えない。二重引用符 (") のみ有効。


<code>.*</code>を指定すると、<code>.</code>/<code>..</code>がマッチするので注意する。最近のシェルは、シェル側で気を利かせているようで、<code>.*</code>だと<code>.</code> /<code>..</code>はマッチしない。
<nowiki>*</nowiki> expect文はawkみたいな感じ。


=== 引用符のネスト ===
<nowiki>*</nowiki> ただし、expectは注意が必要。最初のexpectにマッチしないと先に進めない。タイムアウトとかするしかない。
シェルやプログラミング言語で、文字列リテラルの表現などで、一重引用符'と二重引用符"を使う。


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


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


二重引用符は、内部で変数展開が可能。この都合で、バックスラッシュ\によるエスケープが有効。
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"
# 全体を一重/二重引用符で囲む。


何かAwkの本か何かで、基本的な考え方の説明の記載があった気がする。
expect -c "set timeout 5; spawn cat cat.txt; expect \nFAIL {send pwd/n; expect :; exit}"


[{"ke\y":"valu\e"}] を例として考える。
expect -c 'set timeout 10; spawn cat cat.txt; expect "aa F" {set AAA "abc"}; expect FAIL {send "$AAA/n"; expect " "; exit}'


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


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


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


例えば、シェルなら、catコマンドとコマンド置換で生テキストを使える。
=== タイムゾーン ===
echo $(cat <<-'EOT'
[https://qiita.com/dmikurube/items/15899ec9de643e91497c タイムゾーン呪いの書 #timezone - Qiita]
{"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]
3文字形式は避けたほうが無難。
* [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が二重引用符しか認めないから。
タイムゾーン名で判定する実装があるので、UTC-9なども避けたほうがいい。


基本的な考え方がある。
tz databaseのAsia/Tokyoなどの確実性が高い。
=== Regular Expression ===
正規表現。重要。覚えにくいが重要なものをメモしておく。


# JSON value用に二重引用符"を\"で置換。
後ろからマッチ。cが置換対象。
# \"がPHP/JavaScriptで二重引用符に扱いにならないように、\を\\に置換。
# JSON項目の二重引用符"を\"で置換。
# 全体を二重引用符"で囲む。


こういう感じ。JSONはawkでも任意の最終データで考える。途中にプログラミング言語でのパースがあるので、それを考慮する必要がある。
==== Case ====
/[^c]*$/: cより右端


=== ケース変換 ===
===== マッチの前後の挿入 =====
[https://stackoverflow.com/questions/63116039/camelcase-to-kebab-case javascript - camelCase to kebab-case - Stack Overflow]
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(); }


=== Term ===
=== glob ===
紛らわしい用語がある。


* ミドルウェア: 名前通り中間のソフトウェア。DBやアプリケーションサーバーなどが該当。単独で動作が重要なポイント ([https://sackle.co.jp/blog/detail/1248-2 ミドルウェアとは何か?代表的な製品や使用例とあわせて解説! - サックルMAGAZINE]、[https://system-kanji.com/posts/middleware-development ミドルウェアとは?アプリ・システム開発との関係・仕組み・役割・具体例を解説【2024年最新版】 | システム幹事])。
* [https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/functions/glob.html glob]
* フレームワーク: 単体で動作しない。アプリ開発のテンプレート。Django/Ruby on Rails/Vue.jsなど ([https://www.pentasecurity.co.jp/pentapro/entry/framework_library 【3分ITキーワード】 フレームワークとライブラリの違いは? - ペンタPRO:ペンタセキュリティが提供するセキュリティ情報まとめサイト])。
* [https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/utilities/V3_chap02.html#tag_18_13 Shell Command Language]
* ライブラリー: 単体で動作しない。よく使われるコードの集まり。機能単位。jQuery/Numpy/matplotlib/Qtなど。


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


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


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


==== Problem ====
ファイル名マッチ時には、追加で特殊なルールがある。
altなどの重なり順番、アクティブの下になっちゃう


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


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


==== クラス図 ====
<code>.[!.]*</code> は、<code>.</code>と<code>..</code>以外の.<code>.</code>始まりのファイルにマッチする。
* 汎化 (generalization): 実線白矢印。継承。
* 実現 (realization): 点線矢印。interfaceの継承。
* 集約: 白ひし形。
* コンポジション: 黒ひし形。子が単体で存在できない場合。親と生存期間が同一の場合。
* 関連: 実線矢印。メソッド内インスタンスなど。
* 依存: 点線矢印。引数やローカル変数、返却値。


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


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


* [https://atomicdesign.bradfrost.com/chapter-2/ Atomic Design Methodology | Atomic Design by Brad Frost]
JSON作成や変数展開などで、これらをネストさせたいことがある。その基本的な考え方を整理する。
* [https://zenn.dev/bizlink/articles/b5c8985af8407a Atomic Designの概念]


最近のUIのコンポーネントの組み方。UIコンポーネントを粒度に分けて、ディレクトリー分けして流用するという考え方。
交互にしていい場合は簡単二重。引用符内に一重引用符を配置、一重引用符内に二重引用符を配置すればいい。


* atoms: 原子。これ以上分割不能な最小単位。input/label/buttonなど。
問題はこれがNGな場合。特にありがちなのが、JSONの生成。JSONの引用符は二重引用符のみ。一重引用符の中だと、二重引用符の変数展開が使用不能。外側を二重引用符にする必要がある。
* molecules: 分子。atomsを組み合わせたり、atomsに多少修正したもの。入力フォーム、ナビゲーション、カードなど。
* organisms: 有機体。分子+アルファ。入力フォーム+ヘッダーなど。複数の分子。
* templates: テンプレート。複数の有機体。ヘッダー、メイン、フッターなど。
* pages: ページ。テンプレートを使用したページ。


==== インターフェイスと抽象クラス ====
二重引用符は、内部で変数展開が可能。この都合で、バックスラッシュ\によるエスケープが有効。
[https://qiita.com/nogson/items/e6575d6617f854ed6e25 PHPでインターフェイスと抽象クラスを使う #PHP - Qiita]


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


インターフェイス
# 既存の一重/二重引用符などをバックスラッシュでエスケープ。
# 全体を一重/二重引用符で囲む。


* メソッド宣言のみ。
何かAwkの本か何かで、基本的な考え方の説明の記載があった気がする。
* static/constの場合に限定して、メソッド定義、定数もOK。


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


* [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]
# {"ke\y":"valu\e"}
* [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]
# エスケープ: {\"ke\\y\":\"valu\\e\"}
* [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]
# 全体囲み: "{\"ke\\y\":\"valu\\e\"}"
* [https://softwareengineering.stackexchange.com/questions/441985/best-practice-design-pattern-for-working-with-a-config-file json - Best practice/design pattern for working with a config file - Software Engineering Stack Exchange]


アプリケーションの設定を管理するクラスの設計方法。いくつか方法があり、議論がある。「[https://softwareengineering.stackexchange.com/questions/386212/best-way-to-provide-configuration-parameters-for-objects-far-away-from-the-start Best way to provide configuration parameters for objects far away from the starting point - Software Engineering Stack Exchange]」で特によく議論されている。
これでOK。また何か考慮不足があればそのときに考える。


# シングルトン/グローバル変数: ただし、テストなどで並列アクセスが必要な場合に困ることがあるらしい。
ただ、元データに修正が必要なので、そのまま行きたい。ヒアドキュメント的なものが使えるならそれを使うのがいい。
# DI/設定クラス引数: これがよく支持されている。テストしやすいなど。グローバル変数への参照を渡すようなイメージ。ただし、依存性の伝播のように、上から下に設定を渡す際に、関係ない大量の設定を渡すことがあったりする。


2のDIが最近の主流。引数で値渡し相当にすれば、並列アクセス時も無影響。伝播の問題は設計の問題。
例えば、シェルなら、catコマンドとコマンド置換で生テキストを使える。
echo $(cat <<-'EOT'
{"ke\y":"valu\e"}
EOT
)
.envなどで使える技?いや使えない。.envではシンプルなコマンドしか使えず、ヒアドキュメントは使えない模様。


メソッドをmain関数で呼び出すことを想定して、必要なものだけ渡るようにして、余計なものは削除する。上位・下位の関係を明確にすれば、渡すだけのパラメーターを排除できる。
* [https://stackoverflow.com/questions/15637429/how-to-escape-double-quotes-in-json How to escape double quotes in JSON - Stack Overflow]
* [https://stackoverflow.com/questions/64011248/how-to-handle-double-quotes-in-json-value python - How to handle double quotes in JSON value? - Stack Overflow]


==== do-while/if ====
JSONのvalue部分に適用したい場合。データの二重引用符をバックスラッシュでエスケープする。これはこうするしかない。JSONが二重引用符しか認めないから。
複雑なif文と相性がいい。


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


==== GoF ====
# JSON value用に二重引用符"を\"で置換。
基本的に、具象クラスを使わずに、インターフェイスや抽象クラスを使ってインスタンスを生成するというのが、共通する基本パターン。
# \"がPHP/JavaScriptで二重引用符に扱いにならないように、\を\\に置換。
# JSON項目の二重引用符"を\"で置換。
# 全体を二重引用符"で囲む。


これにより、いろんなケースに同じコードで対応できる。
こういう感じ。JSONはawkでも任意の最終データで考える。途中にプログラミング言語でのパースがあるので、それを考慮する必要がある。
 
=== ケース変換 ===
[https://stackoverflow.com/questions/63116039/camelcase-to-kebab-case javascript - camelCase to kebab-case - Stack Overflow]


===== Factory Methodパターン =====
キャメルケースをチェインケースにしたり、逆にしたりなどケース変換したいことがある。正規表現を駆使して実現する。
[https://blog.ecbeing.tech/entry/2021/01/20/114000 なぜあんなに難しい?Factory Methodパターン - ecbeing labs(イーシービーイング・ラボ)]


コンストラクターの代わりに、インスタンスを生成 (工場=factory) となるメソッドを使うから、FactoryMethodパターン。
=== encode ===
[https://www.sejuku.net/blog/25909 【PHP入門】URLエンコードする方法(urlencode) | 侍エンジニアブログ]


引数の内容に応じて、異なるクラスを作成する。
日本語や記号を他のコードに変換 (エンコード) する方式が何通りかある。把握しておくと役立つ。


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


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


==== Naming ====
* [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]


===== getMyVariable() vs myVariable() =====
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
上記文字はエンコードの対象外。


* [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]
[https://stackoverflow.com/questions/28110062/php-how-to-encode-all-characters-with-rawurlencode string - PHP How to encode all characters with rawurlencode - Stack Overflow]


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


getVar()にするか、Var()にするか。C++だと後者のパターンがあったりする。getを省略できるので、省スペースになる。
こういう目的だと%エンコーディングが適している。


ただ、コード補完で探しやすさがちょっと変わる。getを前置したほうがわかりやすいか。
ただし、一部の記号を許可しているので、自前で変換する。
function encode_all($str) {
    $hex = unpack('H*', $str);
    return preg_replace('~..~', '%$0', strtoupper($hex[1]));
}
$str = 'big ƒüßchen';
print_r(encode_all($str));


==== Term ====
紛らわしい用語がある。


* ミドルウェア: 名前通り中間のソフトウェア。DBやアプリケーションサーバーなどが該当。単独で動作が重要なポイント ([https://sackle.co.jp/blog/detail/1248-2 ミドルウェアとは何か?代表的な製品や使用例とあわせて解説! - サックルMAGAZINE]、[https://system-kanji.com/posts/middleware-development ミドルウェアとは?アプリ・システム開発との関係・仕組み・役割・具体例を解説【2024年最新版】 | システム幹事])。
* フレームワーク: 単体で動作しない。アプリ開発のテンプレート。Django/Ruby on Rails/Vue.jsなど ([https://www.pentasecurity.co.jp/pentapro/entry/framework_library 【3分ITキーワード】 フレームワークとライブラリの違いは? - ペンタPRO:ペンタセキュリティが提供するセキュリティ情報まとめサイト])。
* ライブラリー: 単体で動作しない。よく使われるコードの集まり。機能単位。jQuery/Numpy/matplotlib/Qtなど。


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


== AI ==
==== 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]」


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


==== List ====
* 言語
[https://notepm.jp/blog/24168 【2024年版】対話型AIサービスおすすめ11選を徹底比較!チャットボットとの違い・メリット・課題・選び方なども紹介 - NotePM]
* ツール: 静的解析、テスト、文書など。
* フレームワーク


いろいろある。
MediaWikiのページ名は全体で固有が条件なので、言語名+分類名でページを作るといい。
{| class="wikitable"
|+
!Name
!
!
!
|-
|Bing
|
|
|
|-
|Perplexity AI
|
|
|
|-
|ChatGPT
|
|
|
|-
|Google Gemini
|
|
|
|}


==== ChatGPT ====


===== Plan =====
* PHP language
[https://openai.com/chatgpt/ ChatGPT | OpenAI]
* PHP tool
* PHP framework
 
==== 成功時連続継続処理 ====
一度の取得件数の上限が決まっていて、終了・失敗するまで取得を継続したいという処理がそれなりに発生する。
 
# 処理実行。
# 成功ならA、失敗なら終了。
# 処理実行。
# 成功なら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になる。


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


===== Account =====
==== IP/CIDR ====
公式サイトにアカウントの意味の説明がない。しかたないので、ChatGPTに質問。<blockquote>ChatGPTに会員登録する意味は何ですか?
// 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 ===


ChatGPTに会員登録する主な利点はいくつかあります。
==== 再帰処理 ====
https://chatgpt.com/c/673d9bfe-2414-800b-9922-f94be6dbe950


1. **パーソナライズされた体験**: 登録すると、あなたの好みや過去のやり取りに基づいて、よりカスタマイズされた応答が得られます。
配列の配列、オブジェクトのオブジェクトなど、再帰的な構造はけっこう遭遇する。


2. **履歴の管理**: 過去のチャット履歴を保存し、いつでも見返すことができるため、情報の確認が簡単になります。
再帰関数で実装するほかに、スタックで処理する方法がある。


3. **新機能へのアクセス**: 登録ユーザーは新しい機能やアップデートを優先的に利用できる場合があります。
再帰関数のほうが簡単に実装できるが、関数呼び出しのオーバーヘッドがある。ネスト10-100程度くらいなら問題ない。


4. **プレミアム機能**: 一部のサービスでは、会員登録をすることで、より高度な機能やサポートが提供されることがあります。
パフォーマンスや再帰中の細かい制御が必要なら、スタックが有利。ただし、実装がやや複雑。


5. **セキュリティとプライバシー**: アカウントを持つことで、データの管理やプライバシーの設定をより細かく調整できます。
最初は再帰関数で実装して、後でボトルネックになったらスタックというのも手。


興味があれば、ぜひ登録を検討してみてください!他に質問があればお知らせください。</blockquote>自分の過去の質問の履歴を見れるだけでも便利かも。
https://chatgpt.com/c/6745228f-8b20-800b-8a41-bdaece8c03f5


== VCS ==
再帰関数とスタックの他に、JSONなどの文字列にシリアライズして、文字列処理で対応するという手もある。


=== List ===
JSONPath/XPathなどの方法もあるが、基本的には外部ライブラリーが必要。
Comparison of issue-tracking systems - Wikipedia <nowiki>https://en.wikipedia.org/wiki/Comparison_of_issue-tracking_systems</nowiki>


BTS。GitHubみたいな。PHP製の以下がよさそう。
シンプルなケース以外は、再帰関数で処理したほうが結局シンプルな感じがする。


* Tuleap
=== Other ===
* Phabricator/Phorge
* MantisBT
* FusionForge
* GLPI
* Faveo Helpdesk


VCSとの統合状況がまちまち。
==== コメントの著者名 ====
https://chatgpt.com/c/67469d8d-7e64-800b-b82d-8c74f4e13c08


=== Git ===
GNU socialのソースコードのコメントに著者名が大量にあった鬱陶しい。


==== Commit ====
大規模プロジェクトになると、編集者が膨大になる。VCSに任せて、本文には記載しなくていいと思う。


===== マージコミット後のコミット追加 =====
git blameで行単位で編集者が分かる。
マージコミット後に次の開発作業を始めることが多い。が、直後の初回のコミットを追加したい場合困る。


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


しかたないので、該当コミットでブランチを作成して、コミット。その後、既存の修正ブランチをrebaseでそのコミットの後にくっつける。これでいける。
=== Tool ===
https://chatgpt.com/c/67441feb-d004-800b-96fd-0d9b04ffc628


===== コミットオプション =====
* デスクトップ
[https://git-scm.com/docs/git-commit Git - git-commit Documentation]
** StarUML
** ArgoUML
** UMLet
* クラウド
** Lucidchart: 有料。
** Creately: 有料。
** diagrams.net: モデルじゃない。


コミットメッセージ指定のためのオプションがある。
UmbrelloとModelioはそれらと比較して何がよかったのだっけ?


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


基本は-m。-mの複数指定。
==== Problem ====
altなどの重なり順番、アクティブの下になっちゃう


===== 過去コミットのメールアドレスの変更 =====
optの条件が表示されない。


* [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]
=== Modelio ===
* [https://zenn.dev/flyingbarbarian/articles/241627cae5988a Gitのcommitの名前やメールアドレスを過去からまとめて変更する]


単一コミットのメールアドレスを指定する場合、commitに--authorを指定する。
==== クラス図 ====
git commit --author="John Doe <john@doe.org>"
* 汎化 (generalization): 実線白矢印。継承。
--amendと併用することで、過去コミットも変更できる。
* 実現 (realization): 点線矢印。interfaceの継承。
* 集約: 白ひし形。
* コンポジション: 黒ひし形。子が単体で存在できない場合。親と生存期間が同一の場合。
* 関連: 実線矢印。メソッド内インスタンスなど。
* 依存: 点線矢印。引数やローカル変数、返却値。


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


===== 第一コミットの変更 =====
==== Atomic Design ====


* [https://dev.classmethod.jp/articles/git-rebase-from-root/ [Git] 最初のコミットを含めてrebase -iする方法 | DevelopersIO]
* [https://atomicdesign.bradfrost.com/chapter-2/ Atomic Design Methodology | Atomic Design by Brad Frost]
* [https://git-scm.com/docs/git-rebase Git - git-rebase Documentation]
* [https://zenn.dev/bizlink/articles/b5c8985af8407a Atomic Designの概念]


通常、第一コミットはammend以外では変更できない。
最近のUIのコンポーネントの組み方。UIコンポーネントを粒度に分けて、ディレクトリー分けして流用するという考え方。


rebase --root [branch] でブランチの第一コミットも参照して改変可能。
* atoms: 原子。これ以上分割不能な最小単位。input/label/buttonなど。
* molecules: 分子。atomsを組み合わせたり、atomsに多少修正したもの。入力フォーム、ナビゲーション、カードなど。
* organisms: 有機体。分子+アルファ。入力フォーム+ヘッダーなど。複数の分子。
* templates: テンプレート。複数の有機体。ヘッダー、メイン、フッターなど。
* pages: ページ。テンプレートを使用したページ。


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


===== 復元 =====
* インターフェイスは、クラスに複数実装できるが、抽象クラスは1つしか継承できない。→不特定のクラスで、共通のメソッドを定義したい場合。
[https://qiita.com/generosity-naman/items/237338f8fe5b7e3b9a76 Git Stashの復元: 誤って削除されたスタッシュの復元方法 #Git-Stash - Qiita]
* インターフェイスは、実装のあるメソッドを持つことができないが、抽象クラスは、実装のあるメソッドを持つことができる。→抽象クラスは、複数のクラスの、共通処理の中に、一部違う処理が入る場合、プロパティーが必要な場合などに使用する。


git stash drop実行時に、削除したコミットのSHA1が表示される。
インターフェイス


そのSHA1をapplyで指定すれば、取り込める。
* メソッド宣言のみ。
git stash apply [stash_hash]
* static/constの場合に限定して、メソッド定義、定数もOK。


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


===== 差分ファイル抽出 =====
* [https://softwareengineering.stackexchange.com/questions/197272/best-practice-for-creating-a-global-config-class-used-by-numerous-components c++ - Best practice for creating a 'global' config class used by numerous components - Software Engineering Stack Exchange]
情報源: [https://qiita.com/kaminaly/items/28f9cb4e680deb700833 gitで差分ファイルを抽出する #Git - Qiita]
* [https://softwareengineering.stackexchange.com/questions/386212/best-way-to-provide-configuration-parameters-for-objects-far-away-from-the-start Best way to provide configuration parameters for objects far away from the starting point - Software Engineering Stack Exchange]
* [https://softwareengineering.stackexchange.com/questions/114924/config-class-struct-pattern-or-anti-pattern-alternatives?newreg=b46538fc865f46b08f6bf06d317925bf design - Config Class/Struct: Pattern or Anti-Pattern? Alternatives? - Software Engineering Stack Exchange]
* [https://softwareengineering.stackexchange.com/questions/441985/best-practice-design-pattern-for-working-with-a-config-file json - Best practice/design pattern for working with a config file - Software Engineering Stack Exchange]


git archiveとgit diffを組み合わせる。
アプリケーションの設定を管理するクラスの設計方法。いくつか方法があり、議論がある。「[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]」で特によく議論されている。
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で階層を維持してコピーするしかないかも?
# シングルトン/グローバル変数: ただし、テストなどで並列アクセスが必要な場合に困ることがあるらしい。
# DI/設定クラス引数: これがよく支持されている。テストしやすいなど。グローバル変数への参照を渡すようなイメージ。ただし、依存性の伝播のように、上から下に設定を渡す際に、関係ない大量の設定を渡すことがあったりする。


例:
2のDIが最近の主流。引数で値渡し相当にすれば、並列アクセス時も無影響。伝播の問題は設計の問題。
mkdir -p archive
git diff --name-only new_base 44765_upgrade-base-version | xargs -i cp -p --parent "{}" archive/


===== core.autocrlf =====
メソッドをmain関数で呼び出すことを想定して、必要なものだけ渡るようにして、余計なものは削除する。上位・下位の関係を明確にすれば、渡すだけのパラメーターを排除できる。
<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向けの設定。
==== do-while/if ====
* false=変換しない。
複雑なif文と相性がいい。
* input=コミット時にCRLFをLFに自動変換のみ。mac/Linux向け。Windowsではチェックアウト時にCRLFになるが、mac/LinuxはLFになる。


わかりにくい。基本はfalseで良いと思われる。
for whileの無限ループで最後にbreakでも同じか
do {
  if (true) break;
} while(false);
if文が複雑な場合、do-whileで囲んで、breakでスキップできる。gotoに近い。


===== gitkの文字化け対策 =====
==== GoF ====
[https://www.pistolfly.com/weblog/2010/02/gitk.html gitkのエンコーディングを設定する - Pistolfly]
基本的に、具象クラスを使わずに、インターフェイスや抽象クラスを使ってインスタンスを生成するというのが、共通する基本パターン。


gitkはシステムのデフォルトエンコーディングで表示しようとするので、文字エンコーディングを指定しておく。
これにより、いろんなケースに同じコードで対応できる。
git config --global gui.encoding utf-8


===== ファイル名などの文字化け対策 =====
===== Factory Methodパターン =====
[https://qiita.com/kumazo/items/2169e1ee7be278f82b94 Git for Windows で日本語を使いたい #Vim - Qiita]
[https://blog.ecbeing.tech/entry/2021/01/20/114000 なぜあんなに難しい?Factory Methodパターン - ecbeing labs(イーシービーイング・ラボ)]
git config --global core.quotepath false
git config --global gui.encoding utf-8


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


* [https://qiita.com/yukimura1227/items/fbb076db61a2e43a32e3 gitでrename&modifyしたファイルのログを追跡できるようにしたい場合 #Git - Qiita]
引数の内容に応じて、異なるクラスを作成する。
* [https://zenn.dev/yoichi/articles/how-git-handles-renaming Gitはファイルのリネームをどう扱うか]


改名と修正を同時にすると、改名を検知できない。
ただ、Factory Methodパターンを採用すると、コード量が増えて複雑になる。


-Mオプションを指定すると、類似度で同時も検知できる。が、基本はリネーム・改名と修正は別コミットにしたほうがよさそう。
複雑でややこしいだけなので、基本的に使わなくてよいと思う。


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


-wでインデント違いを無視してくれる。
===== camelCase =====
https://gnusocial.jp/notice/7694551


===== squash =====
!it 命名規則のキャメルケース。これ英語前提です。関数名に英語以外を使うと破綻します。
squashすると、squash対象コミットが、対象の直前のコミットに含められる。


===== gitignore =====
getキーバリュー()みたいな関数の定義。日本語ですると境界がわからなくなるので、getキー_バリューみたいにアンダーバーで区切ったほうが分かりやすい。なるほど…
[https://git-scm.com/docs/gitignore/en Git - gitignore Documentation]


====== Format ======
===== getMyVariable() vs myVariable() =====
記述方法を整理する。
 
* [https://stackoverflow.com/questions/3532828/php-methods-getmyvariable-vs-myvariable naming conventions - PHP methods: getMyVariable() vs myVariable() - Stack Overflow]
* [https://stackoverflow.com/questions/139427/which-coding-convention-to-follow-for-php Which Coding convention to follow for PHP? - Stack Overflow]
 
getterとsetterの命名規則。
 
getVar()にするか、Var()にするか。C++だと後者のパターンがあったりする。getを省略できるので、省スペースになる。


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


後は特に明記がないが、上から順番に評価されて、最後のマッチが優先されるので、記述の順番に注意する。
===== namePrefixed() vs prefixedName() =====
https://chatgpt.com/c/673bd358-3dc8-800b-8ec9-d745cc0eba85


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


先頭スラッシュをつけないと、再帰的になる。
例えば、nameMax、nameMinのような場合は後ろのほうが都合がいい。ただ、こういう場合はそもそもnameをオブジェクトにしてname.max()、name.min()にしたほうがいいという説がある。
    $ cat .gitignore
 
    # ディレクトリ foo/bar 以外のすべてを除外
そうではないならば、getPrefixedName()などが自然。getQueryString()など。StringQueryではない。
    /*
 
    !/foo
PHPでは以下のような命名規則が好まれる。
    /foo/*
 
    !/foo/bar
* 動詞+修飾対象=getPrefixedName/isPrefixed()
* 修飾対象+状態/修飾語=prefixdName
 
getPrefixedNameがいいか。後置修飾にしたいならば、そもそもオブジェクト+メソッドにすることを検討する。
 
===== map =====
連想配列とかハッシュ、オブジェクトなどでキーバリュー形式のデータ構造を扱うことがある。そういう変数の命名規則。


====== 空ディレクトリーの維持 ======
<code>map_[key]_[value]</code> のような形式にすると、キーとバリューが何を意味するか分かってわかりやすい。
[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は空ディレクトリーを履歴管理できない。何かファイルが必要。
===== array/foreach =====


logなど維持したい空ディレクトリーに、以下の内容の.gitignoreを置く。
* [https://wiki.senooken.jp/PHP#Name_2 PHP - senooken JP Wiki]
!.gitignore
* https://chatgpt.com/c/6747aee4-ab64-800b-88d7-940a5c4201bf
.gitignore以外を無視する。これで.gitignoreのみがあるので管理できる。


====== 指定ファイルのみ除外 ======
foreach系のfor文ではキーとバリューを変数に格納して反復する。ファイルや配列に対して行うことが多い。
*
  foreach (table as $row => $line)
  !.gitignore
その際の変数名は、上記のように$row/$lineにすると、行番号と行の値がはっきりしてわかりやすい。
ディレクトリーを残す以外 (.gitignore1ファイル以外) に、サンプルファイルなど複数ファイルを残したい場合は、上記のように*で最初に全部除外して指定ファイルのみ含める。/は必要に応じてつける。


===== gitattributes =====
いいえ。これは問題がある。ネストした場合などに命名規則を維持できない。
[https://git-scm.com/docs/gitattributes Git - gitattributes Documentation]


gitignoreに似ていて、パターンにマッチしたパスに対する設定を行える。
* 配列、コレクション類: 複数形があるなら複数形。困ったらListの接尾辞。
* 反復時。キーバリュー形式の場合、単数形_key/_value。valueだけの場合、単数形。また、_valueは単数形でもいいかもしれない。


* text
上記の命名規則だとわかりやすい。
* eol
$rows = [[]];
* working-tree-encoding
foreach ($rows as $row_key => $row_value) {
* ident
  foreach ($row_value as $column_key => $column_value) {}
* filter
}
* diff
* merge
* conflict-marker-size
foreach ($row_list as $row_key => $row) {
* whitespace
    foreach ($row as $column_key => $column) {
* export-ignore: git archiveなどに含めないことをマーク。
    }
* export-subst
}
* delta
* encoding
foreach ($rows as $row_index => $row_value) {
  foreach ($row_value as $column_index => $column_value) {
  }
}
value部分に単数形を使うと、検索時にkey部分もヒットして、作業しにくいかもしれない。基本はkey/valueの接尾辞がよいと感じる。
 
もっというなら、接尾辞の文字数が揃うので、keyよりindexのほうがよいかもしれない。ただ、indexは添え字の数字の意味合いが強いので、やっぱりkey/valueでいいか。


===== ファイルのインデックスのみ削除 =====
===== Function argument order =====
git rmは単独だと、gitの履歴とローカルファイルからも削除する。追跡対象から削除のみで、ローカルファイルとして残したい場合、--cachedを指定する。
関数の引数は入力、変更、出力の順番にする。理由はこの順番で使うから。<blockquote><nowiki>https://social.senooken.jp/notice/67270</nowiki>
git rm --cached


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


===== problem =====
int func(入力,変更,出力)
ブランチ名が長いと、右クリックしにくい


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


==== Account ====
memcpyとかは例外が多い。
Username may only contain alphanumeric characters or single hyphens, and cannot begin or end with a hyphen.
ユーザー名は、英数字と-のみが使用可能。


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


=== Fossil ===
<nowiki>https://okwave.jp/qa/q4202225.html</nowiki></blockquote>
* [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の検討が不要になる。
==== DB ====
[http://blog.tojiru.net/article/277021312.html PDOの真の力を開放する - PHPでデータベースを扱う(3): Architect Note]


=== Phorge ===
DBアクセスのモデル化。行をクラスとすると扱いやすい模様。
[https://we.phorge.it/ Home]


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


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


===== Introduction =====
データベース関係のデザインパターンがいくつかある。
[https://we.phorge.it/book/phorge/article/introduction/ ◉ Introduction]


以下が主な機能。
* Active Record
* Data Mapper


* コードレビューツール=Differential
===== Active Record pattern =====
* リポジトリーブラウザー=Diffusion
* バグトラッカー=Maniphest
* ウィキ=Phiriction


GitHubの自己ホスト。
* [https://ja.wikipedia.org/wiki/Active_Record Active Record - Wikipedia]
* [https://www.techscore.com/tech/Ruby/Rails/other/designpattern/ デザインパターンから見たActive Record | TECHSCORE(テックスコア)]


===== Phabricator =====
テーブルレコードに対応するクラスを用意して、そのクラス自体にDB操作もさせる。
[[wikipedia:Phabricator|Phabricator - Wikipedia]]


PhabricatorはもともとFacebook社内のBTSシステム。PHP製。2021-06-01に開発終了。
シンプルだが、複雑な操作が苦手。


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


* AngularJS
Ruby on Rails/Laravel+Eloquentなどで採用。
* Discord
* Facebook


==== Install ====
===== Data Mapper pattern =====
[https://we.phorge.it/book/phorge/article/installation_guide/ ◉ Installation Guide]
[https://gihyo.jp/dev/serial/01/ruby/0014 第14回 DataMapperの使い方 | gihyo.jp]


[https://ipv6.rs/tutorial/Ubuntu_Server_Latest/Phorge/ Self Host with IPv6rs - IPv6 Provider - How to Install Phorge on Ubuntu Server Latest]
テーブルのレコードをクラスにするのはARと共通。


===== Requirement =====
ただし、DB操作用のクラスを用意してそちらでDB操作する。
LAMP環境で動作する。


共用ホストでも動作するが、一部機能しない。通常コンピューターを推奨している。
その都合、1テーブルに2クラス必要。


* MySQL: 5.5以上。
User/UserMapperのような対応関係。
* PHP 7.2以上
* git: 2.5.0以上。
* PHP extension: mbstring, iconv, mysql (or mysqli), curl, pcntl


ドメインはサブディレクトリーはだめで、サブドメインじゃないとダメ。
2クラス必要だが、テーブル構造が変わった場合でも基本はMapperで吸収できる。


===== Download =====
===== JOIN =====
以下のコマンドで取得する。
Active RecordもData MapperもJOIN時の扱いが一番重要。単一エンティティーしか扱わないならどちらも同じ。
$ 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"
<blockquote>datamapperパターンでjoinする場合、エンティティーの扱いはどうなるの?
後は開くだけ。


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


以下のコマンドでユーザーを認識させる。
以下、`JOIN`を行う際のエンティティの扱いと実装方法について解説します。
phorge/ $ ./bin/storage upgrade --user <user> --password <password>


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


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


== Shell ==
```python


=== ワイルドカード ===
class UserMapper:
ワイルドカードで.始まりのファイルをマッチさせたい。


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


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


ExcelでUTF-8ファイルを開けるように、UTF-8のBOMをファイルにつけたい。
            SELECT * FROM users
printf '\xEF\xBB\xBF' > with_bom.txt
 
上記コードでBOMを最初に書き込んで、後は追記する。
            JOIN orders ON users.id = orders.user_id
 
            WHERE users.id = %s


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


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


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


===== スコープ =====
        user = User(results[0]['user_id'], results[0]['user_name'])
[http://www.fukano.jp/study_of_awk/basic/basic08.htm 変数のスコープ]


関数の仮引数のみ、ローカル変数扱いで、それ以外はグローバル変数。
        orders = [Order(row['order_id'], row['product_name'], user) for row in results]


==== 文/statement ====
        user.orders = orders


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


==== 関数 ====
```


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


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


==== ヘッダー出力、列別最大長さ出力。 ====
class UserRepository:
<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>


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


## Usage
```</blockquote>UserテーブルとOrderテーブルがあって、あるユーザーの注文一覧を取得したい場合を考える。
# awk -f csvparser.awk data.csv


# CSV の論理的な一行毎に呼び出されるコールバック関数(サンプル)
結局、user.ordersみたいな感じで、エンティティーに外部テーブルのレコードを配列で持たせるつくりになる。
# 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 }
クロス集計する場合は、users[0].orderみたいな感じ。メインのエンティティーのプロパティーに持たせる。フラットじゃないのでちょっと気持ち悪い。が、まあ構造としてこうなるのは順当。
{
    idx = 0
    sub(/\r$/, "")
    while ($0 != "") {
        if (match($0, /^(["]([^"]|["]["])*["]|[^,"]*)(,|$)/)) {
            fields[++idx] = ""
        } else if (match($0, /^["]/)) {
            fields[++idx] = substr($0, 2)
            for (;;) {
                if (getline == 0) exit 1
                sub(/\r$/, "")
                if (match($0, /^([^"]|["]["])*["](,|$)/)) break
                gsub(/["]["]/, "\"")
                fields[idx] = fields[idx] "\n" $0
            }
            fields[idx] = fields[idx] "\n"
        } else {
            exit 1
        }
        field = substr($0, RSTART, RLENGTH)
        $0 = substr($0, RSTART + RLENGTH)
        lastcomma = sub(/,$/, "", field) > 0
        gsub(/^["]|["]$/, "", field) && gsub(/["]["]/, "\"", field)
        fields[idx] = fields[idx] field
    }
    if (lastcomma) fields[++idx] = ""
    while (idx < max_idx) delete fields[max_idx--]
    callback(++row, idx, fields)
    max_idx = idx
}


</syntaxhighlight>awkのCSVパーサー。先頭のBOMはあると認識できないので、tail -c +4でBOMを除外して使う。
方法として、1回のSQLで取得するか、それぞれのエンティティーを取得してマージするか。1回のSQLでやったほうが当然いい。
tail -c +4 data/101543.csv | awk -f csvparser.awk


=== Other ===
==== Other ====


==== binary ====
===== 1対1-多対多 =====
[https://qiita.com/ko1nksm/items/dc8f247cdc5b7b58b736 POSIX準拠のシェルスクリプトでバイナリデータを扱う #Bash - Qiita]
プログラミング言語でデータの関連付けをすることがある。
 
1対1の場合、配列、連想配列のキーバリュー形式のデータがぴったり。
 
多対多の場合。これも配列。二次元配列で基本は0要素目など。
$array[][]
 
==== Project ====
 
===== レガシープロジェクトの立て直し =====
https://chatgpt.com/c/67481a93-adc0-800b-81c4-20d763133002
 
1. 現状分析


バイナリーデータの読込はodコマンド。なければhexdump。
(1) ソフトウェアの動作確認


書込はprintf。
現在の環境でアプリケーションを動作させる。


head/tailの-cはPOSIXで使えたか?
どの部分が機能していて、どこが問題かを確認する。


== cmd.exe ==
必要であればエラーログを確認する。


=== bitsadmin ===
(2) 依存関係の調査
Windowsでのファイルダウンロードコマンド


Windows 7以降ではbitsadminコマンドがあり、これがwget相当となる。
アプリケーションのライブラリやフレームワークのバージョンを調査。


書式:
サポートが終了しているもの、互換性が失われたものを特定。
bitsadmin /transfer <job name> <URL> <output path>
<job name>と<output path>は必須なので注意する。


=== certutil ===
(3) コードベースの状態評価
Windowsでのハッシュの確認に使える。
certutil -hashfile file


SHA1 ハッシュ (対象 C:\moconavi\windows\Moconavi\ext\chromium\moconavium.exe):
コードの品質 (可読性、設計、テストカバレッジ) を確認。
e0da85b04b6970ac1f0c33db7a9ad607fdbd44eb
CertUtil: -hashfile コマンドは正常に完了しました。


=== rlogin.cmd ===
セキュリティリスクを特定する (例えば、脆弱性が放置されていないか)。
コマンドキーの送信を自動化できる?
 
rem rlogin.cmd
2. 計画立案
 
@Echo off
(1) ゴール設定
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%


=== 実行中プロセスのパスの確認 ===
具体的な目標を設定 (例: パフォーマンス改善、保守性向上、セキュリティ強化)
出典: [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


=== 簡易編集モード/挿入モード ===
(2) 優先順位の決定


* [https://softantenna.com/blog/windows-10-command-prompt-no-stop/ 【Tips】Windows 10のコマンドプロンプトが意図せず止まってしまう問題を回避する方法 | ソフトアンテナ]
どの機能を維持し、どの機能を削除または置き換えるか決定。
* [https://superuser.com/questions/419717/windows-command-prompt-freezing-randomly Windows command prompt freezing randomly - Super User]


Windows 10のcmd.exeは [簡易編集モード] が有効になっており、コマンドプロンプトを左クリックすると、テキストの選択が始まる。テキスト選択中はコマンドの実行が止まる。長時間かかるコマンドの実行中に誤操作で止まると困るので、これは無効にしたほうがよい。
ユーザーに直接影響を与える部分を優先。


cmd.exeを起動-左上のアイコンをクリック-[規定値]/[プロパティ]-[オプション]-[□簡易編集モード] を選ぶ。
(3) リスク評価とバックアップ


そのほか、 <code>git log</code> のような制御が移るコマンドを実行してしばらくすると、操作できなくなる。
修正に伴うリスクを評価し、現行システムのバックアップを取得。


[□挿入モード] にすると回避できる模様。
3. 環境整備


== Web ==
(1) 開発環境のモダナイズ


=== HTTP ===
ローカル環境やコンテナ (Docker) を用意してテストを容易にする。
[https://www.rfc-editor.org/rfc/rfc9110.html RFC 9110: HTTP Semantics]


==== Content-Disposition ====
CI/CD パイプラインの整備。
[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)]
(2) 依存関係の更新
Content-Disposition: inline
 
Content-Disposition: attachment
サポートされていないライブラリやフレームワークをアップグレードまたは置き換える。
Content-Disposition: attachment; filename="filename.jpg"
 
filenameでファイル名を指定する。ここの値は二重引用符で囲む。スペースを含む場合に必須になる。
(3) セキュリティの確保
 
古いOSSの脆弱性を修正。
 
HTTPSの導入、認証強化、インプット検証など。
 
4. コードのモダナイズ
 
(1) リファクタリング
 
レガシーコードをよりモダンで可読性の高いコードに変換。
 
デザインパターンを適用して保守性を向上。
 
(2) テストの追加
 
ユニットテスト、統合テストを導入。


==== multipart/form-data ====
既存の機能が壊れないことを確認するための自動化されたテスト。
rfc7578


* [https://datatracker.ietf.org/doc/html/rfc7578 RFC 7578 - Returning Values from Forms: multipart/form-data]
(3) フロントエンド/バックエンドの分離
* [https://qiita.com/sivertigo/items/14957200af5ad953d63b Multipart/form-dataの仕様メモ #HTTP - Qiita]


ファイルアップロード用のMIME type。
必要に応じてモノリシック構造を分離し、モダンなアーキテクチャ (SPA、Microservices など) に移行。


リクエストヘッダー
5. 機能拡張とデプロイ
Content-Type: multipart/form-data; boundary=--hogehoge
 
リクエストボディー
(1) 新しい機能の追加
--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での送信理由。
(2) 運用環境でのテスト


-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などをうまくやってくれるのだと思う。


リクエストボディー全体をファイルデータにする場合。
(3) 本番環境にデプロイ
curl -X POST -H 'Content-Type: image/jpeg' --data-binary @/var/tmp/sample.jpg <nowiki>https://xxxxx.net/xxxxxx</nowiki>


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


自宅サーバーを行う際、固定IPアドレスが必要になる。
6. 継続的改善


取得方法がいくつかある。
(1) モニタリングの導入


* 契約しているプロバイダでオプションとして申し込む方法
エラーログやパフォーマンスを監視し、迅速に対応できる仕組みを導入。
* 固定IPアドレスに対応しているSIMを契約する方法
* '''VPNを利用した固定IPアドレスの提供会社を利用する方法'''


VPNの固定IPアドレスが安いらしい。ryoかsuwakoが解説していた気がする。
(2) 定期的なアップデート


=== Authentication ===
フレームワークやライブラリを継続的に更新し、レガシー化を防ぐ。
認証方式がいくつかある。HTTPで定義される認証方式 (HTTP認証) が有名。


==== Basic認証 ====
(3) コミュニティへの貢献
出典: [https://ja.wikipedia.org/wiki/Basic%E8%AA%8D%E8%A8%BC Basic認証 - Wikipedia]。


Authorization HTTPヘッダーにBasicのあとに [username:password] をBASE64でエンコードして送信する認証方式。
OSSとしての性質を活かし、変更内容をコミュニティに共有することでフィードバックを得る。
GET /private/index.html HTTP/1.1
Host: example.com
Authorization: Basic cm9vdDpwYXNzd29yZA{{=}}{{=}}
盗聴や改ざんが簡単だが、シンプルという利点がある。


==== OAuth ====
このプロセスを通じて、安定した動作を保ちながら徐々に近代化することが可能です。特に、「現状分析」と「環境整備」をしっかり行うことで、後続の作業がスムーズになります。
Ref


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


OAuth (オーオース) 権限の認可のための標準。OAuth 2.0が最新の標準。
=== 対話AI ===


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


* resource owner: あるサイトのユーザー。
いろいろある。
* resource server: あるサイトのユーザーのデータの保有サーバー。
{| class="wikitable"
* clent: クライアントアプリ。リソースサーバーのデータを使用したい。
|+
* authorization server: クライアントにサイトへのアクセスを認証するサーバー。アクセストークンを発行して行う。
!Name
!
!
!
|-
|Bing
|
|
|
|-
|Perplexity AI
|
|
|
|-
|ChatGPT
|
|
|
|-
|Google Gemini
|
|
|
|}


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


処理の流れ。
===== Plan =====
[https://openai.com/chatgpt/ ChatGPT | OpenAI]


# client->resource owner: Authorization Request。ここでユーザーが手操作でアクセスを承認する。
Free/Plusの2のプランがある。
# client<-resource owner: Authorization Grant。
{| class="wikitable"
# client->authorization server: Authorization Grant。承認された情報でアクセストークンを要求。
|+
# client<-authorization server: Access Token
!
# client->resource server: Access Token。アクセストークンでアクセス。
!Free
# client<-resource server: Access Token
!Plus
 
|-
Consumer Key/Secret: アプリ識別用のID/PW。
|金額 [USD/月]
 
|0
Access Token: サイトにアクセスするためのパスワード。
|20
 
|-
=== API ===
|機能
|基本
|アーリーアクセス
|-
|エンジン
|GPT-4o mini
|GPT-4/GPT-4o/GPT-4o mini
|-
|制限
| -
|GPT-4oの5倍以上のメッセージ送信
|-
|その他
| -
|データ分析、ファイルアップロード、ビジョン、Webブラウジング
|-
|画像生成
| -
|DALL-E
|}
送信可能なメッセージ数、エンジン、画像生成などが大きな違いだろう。


==== 複数レコードの登録 ====
===== Account =====
[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 | 個人開発ブログ]
公式サイトにアカウントの意味の説明がない。しかたないので、ChatGPTに質問。<blockquote>ChatGPTに会員登録する意味は何ですか?


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


[https://www.yamarkz.com/blog/rest-web-api-practice REST WebAPIのプラクティス | yamarkz.com]
ChatGPTに会員登録する主な利点はいくつかあります。


delete_bulkなどのような一括処理用のAPIを作るしかない。内部的には単一処理のAPIを作る感じだったとしても。
1. **パーソナライズされた体験**: 登録すると、あなたの好みや過去のやり取りに基づいて、よりカスタマイズされた応答が得られます。


==== パラメーター ====
2. **履歴の管理**: 過去のチャット履歴を保存し、いつでも見返すことができるため、情報の確認が簡単になります。
[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種類ある。
3. **新機能へのアクセス**: 登録ユーザーは新しい機能やアップデートを優先的に利用できる場合があります。


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


パスはIDなどを指定する場合だけわかりやすい。それ以外のオプションはクエリーのほうがいい。
5. **セキュリティとプライバシー**: アカウントを持つことで、データの管理やプライバシーの設定をより細かく調整できます。


ボディーは、通常サーバーのアップロード・ダウンロードデータとして使われる。クエリーはデータの指定に使う。
興味があれば、ぜひ登録を検討してみてください!他に質問があればお知らせください。</blockquote>自分の過去の質問の履歴を見れるだけでも便利かも。


この原則に従うとシンプルだろう。
===== 方法 =====


* URIには長さの制限がある。
====== 質問の分割 ======
* ボディー
https://chatgpt.com/c/673bdc0d-e0e0-800b-a22b-4fa19e64476c
** 引数が非常に多い場合。
** 画像などバイナリーデータ。
** キー・値構造を持たない場合。
* クエリー文字列
** 引数を簡単に確認できる。
** 共通の引数の場合。


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


* [https://stackoverflow.com/questions/20550514/post-or-get-in-a-search-form .net - POST or GET in a search form? - Stack Overflow]
A. どちらでも問題ない。が、質問が関連しているなら同じチャットで継続したほうがいい。直前の質問も文脈を考慮できる。完全に話が異なるなら分けたほうが後で整理したり、URLを共有したときにわかりやすい。


検索機能にGETとPOSTのどちらを使うか?という議論がある。
===== 感想 =====


データ登録するわけなじゃないのだから、GETがいいんじゃない?
====== 2024-11-14 Thu ======
https://gnusocial.jp/notice/7806505<blockquote>[[/gnusocial.jp/group/32/id|!it]] [[/gnusocial.jp/group/28/id|!ai]] 業務でPHPの開発作業をしていて、ChatGPTを使いだして便利に感じています。検索エンジンの代わりに使っています。


POSTだと、JSONをそのまま送れるので、複雑なケースに対応できる。特に、配列の送信が重要。
例えば、「laravel eloquentでリレーション先のテーブルの主キー名の取得方法は?」と質問します。


GETのほうが検索条件をブックマークにできたり、URLを共有できるので、基本は便利。
[[/chatgpt.com/c/67354314-fbdc-800b-a4e4-65f96d1a8fb2|https://chatgpt.com/c/67354314-fbdc-800b-a4e4-65f96d1a8fb2]]


==== レート制限対策 ====
getRelatedというややマニアックなメソッドを教えてくれます[eloquent getrelated] で検索してもなかなかたどり着けないです。
 
こういう検索エンジンで検索しにくい質問で便利だなと思います。


* [https://pikodon.com/note/php/api-cache/ APIの利用制限対策 | Web開発ノート]
検索エンジンで検索すると、的外れな情報も大量にヒットします。対話AIはそのごみの混ざった検索結果を分析した結果をコンパクトに返してくれます。対話AI使わなくても、検索エンジンで時間かければわかりますが、大幅に時間短縮できます。
* [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 リクエスト数によるアクセス制限の対策方法 – 請求管理ロボ ヘルプ]


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


* cronなどでデータをサーバー上 (DBなど) に定期保存して、保存データを表示させる。
個人的に、ただの知識、事実は重要度高くないと思いますが、一般社会では評価する側の頭が悪いので、これが重宝されます。
* 配列を利用して、1回のリクエストでまとめて取得する。
* インターバルを設ける。
* HTTP 429/413を検知して、リトライする。


==== 指数関数的バックオフ ====
同僚や先輩に聞くより対話AIのほうがよほど頭いいです。話すことないです。聞くほうが時間の無駄なので。凡人はどんどん要らなくなります。


* [https://docs.link.getmoneytree.com/docs/faq-rate-limiting APIレート制限は何か、どのように対処するのか?]
一方、私みたいなキチガイのデータは少ないので、検索エンジンやAIに聞いても出てこないです。世界で自分だけのオリジナルに専念するのがたぶんいいです。</blockquote>
* [[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 で応答した場合に、システムがリクエストを再試行するまでの時間となります。
====== 2024-11-19 Tue ======
* <code>base</code> は最初の間隔、つまり最初の再試行までの待ち時間です。この値には3000msを使用することをお勧めします。
https://gnusocial.jp/notice/7867350<blockquote>[[/gnusocial.jp/group/28/id|!ai]] ChatGPTが検索エンジンの改良版としてやっぱり便利。さっきこういう質問しました。
* <code>n</code> は、現在の呼び出しの前にリクエストが通らなかった数です。複数のスレッドやプロセスを使用して並行してAPIを呼び出している場合、<code>n</code>の値は現在のスレッド/プロセスにスコープされます。この値は、現在のスレッド/プロセスが、最後に成功した応答から何回 429 "Too Many Requests" エラーに遭遇したかを表します。
* <code>jitter</code> は 0 から <code>base</code> の間の乱数です。これは、複数のスレッド/プロセスが全く同時にAPIを呼び出さないように、リクエストを少しずつ分散させるために使用されます。システムが待機するたびに、この乱数値を再計算し <code>wait_interval</code> の合計に加算するか減算するか、ランダムで選択してください。


=== curl ===
phpのメソッド名で、英単語の修飾語は前と後ろどちらがいい?例えば、namePrefixed()とprefixedName()のどちらがいい? [[/chatgpt.com/c/673bd358-3dc8-800b-8ec9-d745cc0eba85|https://chatgpt.com/c/673bd358-3dc8-800b-8ec9-d745cc0eba85]]
HTTPの通信のコマンドラインでの確認でよく使う。


==== Basic ====
私はこのレベルの細かい疑問がすぐ浮かぶのです。これを人間にきくと、頓珍漢な回答だったり、そもそも回答してもらえないし、何ならこういう質問した私がなぜかキチガイ扱いされて、微妙な雰囲気になって、質問できなくなって、ストレスが溜まって、居づらくなって早期退職になるんです。意味不明です。ただの質問にお気持ちの配慮とか面倒なので。
[https://curl.se/docs/tutorial.html curl - Tutorial]
* -X: メソッド指定
* -d/--data-urlencode: リクエストボディー (key=value)を指定。-X POSTも自動指定になる。
curl -H "Content-Type: application/json" -d '{"name":"佐藤", "mail":"sato@example.com"}' localhost:5000/api/v1/users
JSONで送信する場合、ヘッダー指定が必須。


<nowiki>*</nowiki>-F: multipart/formのform指定。
この間、 [[/misskey-square.net/users/9g2o6eycu3|@yuriha]] に突っ込まれた件も、たぶん対話AIとお互い会話したほうが有意義だったんじゃないかとすら思います。相手も私に突っ込む前に対話AIと会話したほうが自分の主張の自己矛盾、頓珍漢さに気づけたんじゃないかとすら思えます。私が突っ込んでまーた私がキチガイ扱いされるのも回避されます。対話AIからの客観的な指摘なら、同じ内容であっても、キチガイの私が言うより納得しやすいでしょう?同じ内容なら対話AIのほうが凡人健常者にとっては、信じ込みやすいでしょ?
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を指定する。
対話AIだとお気持ちの配慮いらないし、当たり前ですけど、キチガイ扱いされることもないので、快適です。元々対話AIには懐疑的でしたが、どちらかというと私のようなキチガイが凡人健常者の知識を拝借するためにあるような印象を持ちます。


==== curl: (60) SSL certificate problem: self-signed certificate ====
検索エンジンでも調べることはできますが、めちゃくちゃ時間かかるんです。自分で複数の意見をみつけて、頭の中で比較検討して整理するので。これを一瞬でやってくれるのが楽。途中のデータ整理、目視は単純作業に近いのです。他のことに頭使えます。
Ref: [https://linuxfan.info/curl-insecure curlで「自己署名証明書」を受け入れるには【curl: (60) SSL certificate problem: self signed certificate】 | LFI].


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


==== curl: Failed writing body ====
凡人健常者の知識を拝借して、世界でだれにも真似できないキチガイ部分に専念できます。GNU socialの開発もこれでいけると思います。</blockquote>
[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がエラーを出力する。
== VCS ==
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
=== List ===
curlは標準出力に全部書き込めたかチェックしているようで、head -n 1で切り捨てたらcurlはエラーになる。
Comparison of issue-tracking systems - Wikipedia <nowiki>https://en.wikipedia.org/wiki/Comparison_of_issue-tracking_systems</nowiki>


対策は、curl -sで出力を抑制するとのこと。これで解決。
BTS。GitHubみたいな。PHP製の以下がよさそう。


=== Wireshark ===
* Tuleap
* Phabricator/Phorge: 共用サーバー不能。
* MantisBT
* FusionForge
* GLPI
* Faveo Helpdesk
* [https://sourcehut.org/ sourcehut - the hacker's forge]: Python製。FSF推奨。
* Fossil


==== TLS ====
VCSとの統合状況がまちまち。
Ref: [https://www.toyo.co.jp/onetech_blog/articles/detail/id=36994 SSL/TLSの復号#1 ~Wiresharkの設定~ | 東陽テクニカ | “はかる”技術で未来を創る | ワン・テクノロジーズ・カンパニー].


Wiresharkで通信パケットを確認する場合、デフォルトでTLSで暗号化されているので、内容がわからない。WiresharkでTLSに対応しておく必要がある。
phorgeがダメだったので、Mantis/Fossil/sourcehutあたりが共用サーバーで検討可能か。


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


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


上記をチェックしておく。デフォルトでチェックされていた。
===== マージコミット後のコミット追加 =====
マージコミット後に次の開発作業を始めることが多い。が、直後の初回のコミットを追加したい場合困る。


続いて、セッションごとのPre-Master Secretを登録する。
git rebase -iにすると、コミットが残るから。編集はできるが、その直前にコミットの追加ができない。マージコミットは扱いが特殊で直接rebaseで編集できない。


Chrome/Firefoxだと、環境変数SSLKEYLOGFILEを設定すれば、このファイルにTLSセッションキーを出力するので、これをWiresharkで読み込むことで、復号対応する。
しかたないので、該当コミットでブランチを作成して、コミット。その後、既存の修正ブランチをrebaseでそのコミットの後にくっつける。これでいける。


以下のコマンド相当で、任意のファイル・場所にログファイルを指定する。
===== コミットオプション =====
export SSLKEYLOGFILE=/tmp/sslkey.log
[https://git-scm.com/docs/git-commit Git - git-commit Documentation]
Macだとlaunchctlで設定しておくといい。これでWebブラウザー経由の場合は見えるようになる。


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


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


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


サーバーログにIPアドレスが残るから、それで攻撃元の国を特定して、該当国を一括アクセス拒否。これが効果あるかもしれない。
===== 過去コミットのメールアドレスの変更 =====


攻撃元の国は途上国とかが多いだろうから。IPアドレスは簡単に変更できるが、国を変えるのはたいへんだろう。
* [https://www.git-tower.com/learn/git/faq/change-author-name-email How can I change the author (name / email) of a commit? | Learn Version Control with Git]
* [https://zenn.dev/flyingbarbarian/articles/241627cae5988a Gitのcommitの名前やメールアドレスを過去からまとめて変更する]


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


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


基本的に、バックエンドで主にチェックして、フロントエンドはUXの向上目的で実装する。データの重複チェックはDBアクセスが必要だったりするから。また、API経由などフロントがそもそもないケースもある。
===== 第一コミットの変更 =====


ただ、社内システムのような、画面経由でしか使わない。悪者がほぼいないと思われるケースは、フロントエンドでの検証だけでも十分に感じる。
* [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以外では変更できない。


* [https://www.youfit.co.jp/archives/4545 フォームの二重送信を防止する方法 - 福岡・東京のシステム開発会社 (株)ユーフィット]
rebase --root [branch] でブランチの第一コミットも参照して改変可能。
* [https://qiita.com/syobochim/items/120109315f671918f28d さいきょうの二重サブミット対策 #JavaScript - Qiita]


submitボタンのダブルクリック、リロード、ブラウザーバック・フォワードなど、フォーム周りで注意が必要な保安要素がある。
===== マージコミットの打ち消し =====
マージコミットは扱いがやや特殊。
git revert -m 1 マージコミット
git reset --hard HEAD~1 # マージコミット前
どちらか。


# ボタン連打
==== stash ====
# ブラウザーバック
# リロード (PRG)


項目ごとにすべき対策が異なる。
===== 復元 =====
[https://qiita.com/generosity-naman/items/237338f8fe5b7e3b9a76 Git Stashの復元: 誤って削除されたスタッシュの復元方法 #Git-Stash - Qiita]


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


* [https://www.youfit.co.jp/archives/4545 フォームの二重送信を防止する方法 - 福岡・東京のシステム開発会社 (株)ユーフィット]
そのSHA1をapplyで指定すれば、取り込める。
* [https://qiita.com/syobochim/items/120109315f671918f28d さいきょうの二重サブミット対策 #JavaScript - Qiita]
git stash apply [stash_hash]
* [https://codezine.jp/article/detail/769 JavaScriptを利用してフォームの二重送信を防止する|CodeZine(コードジン)]
* [https://blog.nisesagi.com/3150/ JavaScriptでformの2重送信を防止する | にせサギ ネットサギ体験ブログ]
* [https://yutaihara.com/archives/569 Javascriptで送信ボタン二度押しによる二重送信を防止する方法 | Yuta Ihara.com]


基本は、ボタンのsubmitのイベント内でdisabled=trueでの無効化。
===== リモート =====
[https://qiita.com/mather314/items/a1536c52a2eb0426b2b5 gitの不要なブランチを消すコマンド #Git - Qiita]
git fetch -p/--prune
リモートの削除済みブランチをローカルに同期する。


似た考え方で、スプラッシュのモーダル表示もあり。これがわかりやすいかもしれない。
===== リモートの最新タグ =====
$("form").submit(function() {
https:/stackoverflow.com/questions/20734181/how-to-get-list-of-latest-tags-in-remote-git
  var self = this;
  $(":submit", self).prop("disabled", true);
  setTimeout(function() {
    $(":submit", self).prop("disabled", false);
  }, 10000);
});
停止にしたら、二度通せなくなるので、タイムアウトで戻すとよい。


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


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


===== Extension =====
https:/git-scm.com/docs/git-ls-remote.html
Chromme系で愛用拡張機能を列挙する。


* [https://chromewebstore.google.com/detail/create-link/gcmghdmnkfdbncmnmlkkglmnnhagajbm Create Link]:
https:/stackoverflow.com/questions/10649814/get-last-git-tag-from-a-remote-repo-without-cloning


==== devtool/開発者ツール ====
git rev-listでいけそう。


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


[Elements]-[Event Listeners]-[handler]-右クリック-[Show function definition] でイベントリスナー関数の定義を確認できる。
===== 差分ファイル抽出 =====
情報源: [https://qiita.com/kaminaly/items/28f9cb4e680deb700833 gitで差分ファイルを抽出する #Git - Qiita]


===== イベント監視 =====
git archiveとgit diffを組み合わせる。
[https://stackoverflow.com/questions/3787555/how-to-find-out-which-javascript-events-fired How to find out which JavaScript events fired? - Stack Overflow]
git archive --format=zip --prefix=root/ HEAD `git diff --diff-filter=d --name-only HEAD^ HEAD` -o archive.zip
ただし、この方法はファイル数がARG_MAX以下の場合だけ。ファイル数が多い場合だめ。


monitorEvent関数で監視できるらしい。他に、FirefoxのFirebugのlog eventsでも監視できるらしい。
git diff --name-onlyで一覧を出力させて、1個ずつcp -pで階層を維持してコピーするしかないかも?


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


===== Windows Safari =====
===== 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


* [https://web.archive.org/web/20220220134447/https://jp.techcrunch.com/2012/07/27/20120725apple-safari-for-windows-ends/ Appleは静かにWindows版Safariの開発から手を引いてしまったのだろうか? | TechCrunch Japan]
* true=コミット時にCRLFをLFに自動変換。チェックアウト時に逆。Windows向けの設定。
* [http://web.archive.org/web/20120728130701/https://support.apple.com/kb/DL1531 Safari 5.1.7 for Windows]
* false=変換しない。
* input=コミット時にCRLFをLFに自動変換のみ。mac/Linux向け。Windowsではチェックアウト時にCRLFになるが、mac/LinuxはLFになる。


一応ある。2012-05-09のSafari 5.1.7までWindows版が提供されていた。DL1531。
わかりにくい。基本はfalseで良いと思われる。


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


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


* [https://web-toolbox.dev/ Web ToolBox | 開発者向けのオンラインツール]
===== ファイル名などの文字化け対策 =====
* [https://tm-webtools.com/ TM - WebTools]
[https://qiita.com/kumazo/items/2169e1ee7be278f82b94 Git for Windows で日本語を使いたい #Vim - Qiita]
git config --global core.quotepath false
git config --global gui.encoding utf-8


いくつかWeb関係の開発で役立つツール集を公開しているサイトがある。
===== 改名と修正 =====


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


* [[wikipedia:Special-use_domain_name|Special-use domain name - Wikipedia]]
改名と修正を同時にすると、改名を検知できない。
* [https://ja.wikipedia.org/wiki/.localhost .localhost - Wikipedia]


RFC 6761 で規定。RFC 2606<nowiki/>で予約。DNSに登録されることはないため、テスト目的で使用可能。ループバック (送信元にそのまま返す) インターフェイス。
-Mオプションを指定すると、類似度で同時も検知できる。が、基本はリネーム・改名と修正は別コミットにしたほうがよさそう。


IPv4=127.0.0.1/IPv6=::1とされている。
===== 差分無視 =====
[https://qiita.com/odekekepeanuts/items/8a056b87c9e481e07e57 git diffの--ignoreオプションにおけるスペース、タブ、改行の扱いを理解する #Git - Qiita]


== Shared Host ==
-wでインデント違いを無視してくれる。


=== Free ===
===== squash =====
無料で使用可能な共用ホスティングサービスがある。
squashすると、squash対象コミットが、対象の直前のコミットに含められる。


==== スタードメイン無料サーバー ====
===== gitignore =====
ドメインをセットで利用する必要があるものの、スタードメインのスタードメイン無料サーバーがけっこういい。
[https://git-scm.com/docs/gitignore/en Git - gitignore Documentation]


[https://www.star-domain.jp/service/free_server.php 無料レンタルサーバー | スタードメイン - ドメイン取得 100円(税込)~]
====== Format ======
記述方法を整理する。


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


* ディスク容量 20GB
後は特に明記がないが、上から順番に評価されて、最後のマッチが優先されるので、記述の順番に注意する。
* DB 1GB


ただし、SSHやコマンドは使えないので、FTPでWordPressを展開して設置するとか、そういう簡単な使い方だけ。ただ、それでもWordPressでWebサイトを構築するくらいなら十分だと思う。
反転の!と/の扱いに特に注意が必要。


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


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


* [https://www2.bwt.jp/wiki/?Custom_Filter_of_Coreserver Custom_Filter_of_Coreserver - PukiWiki]
gitは空ディレクトリーを履歴管理できない。何かファイルが必要。
* [https://help.coreserver.jp/manual/v2/spam-filter/ スパムフィルターの設定 | マニュアル | サポート | レンタルサーバー CORESERVER(コアサーバー)]
* [https://help.coreserver.jp/manual/v1/customfilter/ カスタムフィルターの設定 | マニュアル | サポート | レンタルサーバー CORESERVER(コアサーバー)]


情報
logなど維持したい空ディレクトリーに、以下の内容の.gitignoreを置く。
!.gitignore
.gitignore以外を無視する。これで.gitignoreのみがあるので管理できる。


* [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]
!.gitignore
* [https://awmt.jp/dekirukana/archives/2253 コアサーバー V1にてカスタムフィルターで「ごみ箱」を指定したときの確認方法 – AWMTの、できるかな?]
ディレクトリーを残す以外 (.gitignore1ファイル以外) に、サンプルファイルなど複数ファイルを残したい場合は、上記のように*で最初に全部除外して指定ファイルのみ含める。/は必要に応じてつける。


ルールが特殊なので注意する。
===== gitattributes =====
[https://git-scm.com/docs/gitattributes Git - gitattributes Documentation]


ゴミ箱に振り分ける場合。
gitignoreに似ていて、パターンにマッチしたパスに対する設定を行える。


順1 で[<code>./.Trash</code>] を指定
* text
* eol
* working-tree-encoding
* ident
* filter
* diff
* merge
* conflict-marker-size
* whitespace
* export-ignore: git archiveなどに含めないことをマーク。
* export-subst
* delta
* encoding


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


* 条件:  [<code>.*</code>]
==== gitk ====
* 処理:  <code>./</code>、に振り分ける


条件部分には正規表現が使えるように見える。
===== problem =====
ブランチ名が長いと、右クリックしにくい


破棄にしないといけない。転送する場合、カスタムフィルターの中に転送を入れる。条件を.*にする。
==== Other ====


カスタムフィルターにくせがある。
===== 他のブランチとの同一化 =====
git diff HEAD master | patch -p 1
patchの他にgit applyでもいい。


* エスケープ(\を前置する)が必要な文字は「'」「"」「|」「`」「~」「?」「!」
===== .netrc =====
https://social.senooken.jp/conversation/1573147#notice-2217499


==== Value Domain ネットde診断 byGMO ====
Gitのパスワード入力の省略方法に~/.netrcがある。


* [https://www.value-domain.com/information/detail/?no=20240606-1 弊社レンタルサーバー上で運用中のドメインにおける自動セキュリティ診断開始のお知らせ | お知らせ - バリュードメイン]
しかし、man netrcするとわかるけど、これはもともとFTPのためのもの。なぜGitで使えるんだ?Gitの文書で言及がない。
* [https://www.value-domain.com/security/net-de-shindan/ Value Domain ネットde診断 byGMO - バリュードメイン]


2024-06-07 Friからバリュードメイン系の利用者に無料で提供しているセキュリティー診断ツール。
In conversation Thursday, 21-Feb-2019 10:58:47 JST from web permalink


== Analytics ==
せのお (妹尾 賢)せのお (妹尾 賢) in reply to


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


* SimilarWeb
1. Gitはhttpとhttpsの通信にcURLを使っている。
* Ubersuggest
* ahrefs
* Googleキーワードプランナー


=== 閲覧数取得 ===
<nowiki>https://github.com/git/git/blob/master/INSTALL#L141</nowiki>
出典: [https://affiliate-jpn.com/archives/5595 GoogleAnalyticsで自サイトの人気記事ランキングを表示する方法 | アフィリエイトJAPAN]。


* [行動]-[サイトコンテンツ]-[全てのページ]
2. cURLが.netrcにも対応しているから。
* [表示する行数]=5000
* [エクスポート]=TSV


=== 流入元特定 ===
<nowiki>https://ec.haxx.se/usingcurl-netrc.html</nowiki>
「[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>こんにちは。


探索レポートでユーザーセグメントを作成する集計方法はいかがでしょうか。
=== GitHub ===


・自由形式レポートを作成
==== Account ====
Username may only contain alphanumeric characters or single hyphens, and cannot begin or end with a hyphen.
ユーザー名は、英数字と-のみが使用可能。


・セグメント作成 > ユーザーセグメント
組織別にアカウントを分けるなら、かぶらないように末尾に-組織名のようなサフィックスがあるとよいだろう。


・条件は page_view > パラメータ page_location > 含む:会員登録画面のURL を指定
=== 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の検討が不要になる。


・探索レポートにセグメントを適用
=== Phorge ===
[https://we.phorge.it/ Home]


・ディメンション:セッションの参照元 / メディア、ランディング ページ + クエリ文字列
PhorgeはPhabricatorのフォーク。


・指標:セッション
==== About ====


ご確認よろしくお願いいたします。
===== Introduction =====
[https://we.phorge.it/book/phorge/article/introduction/ ◉ Introduction]


※ページ閲覧の発生しなかったセッションはランディングページが (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>
* コードレビューツール=Differential
* リポジトリーブラウザー=Diffusion
* バグトラッカー=Maniphest
* ウィキ=Phiriction


== Server ==
GitHubの自己ホスト。


=== httpd ===
===== Phabricator =====
Apache HTTP Server
[[wikipedia:Phabricator|Phabricator - Wikipedia]]


==== Access Control ====
PhabricatorはもともとFacebook社内のBTSシステム。PHP製。2021-06-01に開発終了。
出典: [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も関係ある。
* AngularJS
* Discord
* Facebook


基本構文は以下。
==== Install ====
Require host <address>
Require ip <ip address>
1番目の形式はドメイン名。2番目はIPアドレス。部分マッチする。マッチしたもののアクセスを許可する。


Requireの直後にnotを指定してアクセス禁止にできる。こちらが重要。
* [https://we.phorge.it/book/phorge/article/installation_guide/ ◉ Installation Guide]
* [https://ipv6.rs/tutorial/Ubuntu_Server_Latest/Phorge/ Self Host with IPv6rs - IPv6 Provider - How to Install Phorge on Ubuntu Server Latest]
* https://chatgpt.com/c/6749041b-a1b4-800b-a134-96a8029c086e


=== E-mail ===
===== Requirement =====
[[https://www.itti.jp/web-direction/spam-blacklist-release/ サーバーIPがブラックリストに載ってメール送信エラーになるのを解除する方法]]
LAMP環境で動作する。


MailHog: Go言語製のメールサーバーソフト。
共用ホストでも動作するが、一部機能しない。通常コンピューターを推奨している。


=== Debian ===
* MySQL: 5.5以上。
 
* PHP 7.2以上
==== PHP8 ====
* git: 2.5.0以上。
[How To Install PHP 8.0 on Debian 11/10/9 | ComputingForGeeks](<nowiki>https://computingforgeeks.com/how-to-install-php-on-debian-linux/</nowiki>)
* PHP extension: mbstring, iconv, mysql (or mysqli), curl, pcntl


Debian 11の場合、PHP 8には外部リポジトリーが必要なので追加する。
ドメインはサブディレクトリーはだめで、サブドメインじゃないとダメ。


sudo apt update
===== 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


sudo apt install -y lsb-release ca-certificates apt-transport-https software-properties-common gnupg2
"mysql.host": "localhost", "mysql.user": "phorge", "mysql.pass": "password", "mysql.port": 3306, "mysql.charset": "utf8", "mysql.database": "phorgedb"
 
後は開くだけ。
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 -
こういうディレクトリー構成想定。
public_html
+ phorge.gnusocial.jp 公開ディレクトリー。
+ phorge phorge関係の格納場所。
  + phorge
  + arcanist
取得。
TAG=2024.35
mkdir phorge
cd phorge
PKG=phorge
git clone --depth 1 [https://we.phorge.it/source/phorge.git https://we.phorge.it/source/$PKG.git]
cd $PKG; git fetch --depth 1 origin tag $TAG; git checkout $TAG; cd ..
PKG=arcanist
git clone --depth 1 [https://we.phorge.it/source/arcanist.git https://we.phorge.it/source/$PKG.git]
cd $PKG; git fetch --depth 1 origin tag $TAG; git checkout $TAG; cd ..


sudo apt update
git config --add safe.directory arcanist
git config --add safe.directory phorge
phorge/webrootが公開ディレクトリーになるので、これをシンボリックリンクで公開ディレクトリーにリンクする。
DOMAIN=phorge.gnusocial.jp
ln -fns phorge/phorge/webroot ../$DOMAIN
「[https://we.phorge.it/book/phorge/article/configuration_guide/ ◉ Configuration Guide]」に記載のあるリダイレクト設定をする。


これでPHP8を参照できるので、インストールする。
以下相当の設定を行う。
<VirtualHost *>
  # Change this to the domain which points to your host.
  ServerName phorge.example.com
  # Change this to the path where you put 'phorge' when you checked it
  # out from the upstream when following the Installation Guide.
  #
  # Make sure you include "/webroot" at the end!
  DocumentRoot /path/to/phorge/webroot
  RewriteEngine on
  RewriteRule ^(.*)$          /index.php?__path__=$1  [B,L,QSA]
</VirtualHost>
<Directory "/path/to/phorge/webroot">
  Require all granted
</Directory>
具体的には、phorge/webroot/.htaccessに以下を記載して、ファイルがなければ作成する。
cat >phorge/webroot/.htaccess <<-'EOT'
RewriteEngine on
RewriteRule ^(.*)$ /index.php?__path__=$1 [B,L,QSA]
EOT
上記設定後phorge.gnusocial.jpにアクセスすると以下のエラーになる。
Request parameter '__path__' is not set. Your rewrite rules are not configured correctly.


sudo apt install php8.2
* [https://stackoverflow.com/questions/25368612/phabricator-rewrite-rules-configuring-issue apache - Phabricator rewrite rules configuring issue - Stack Overflow]
* [https://stackoverflow.com/questions/49344737/phabricator-install-rewrite-rules-are-not-configured-correctly php - Phabricator install. Rewrite rules are not configured correctly - Stack Overflow]


[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>)
上記が少し参考になる。require指令を指定していないのが問題。


インストールしたら、PHPのバージョンを切り替える。
うーん。この問題を解決できない。調べても解決例が出てこない。断念する。他のソフトにする。


a2dismod php7.4
===== Config =====
[https://we.phorge.it/book/phorge/article/configuration_guide/ ◉ Configuration Guide]


a2enmod php8.2
以下のコマンドでユーザーを認識させる。
phorge/ $ ./bin/storage upgrade --user <user> --password <password>


sudo systemctl restart apache2
==== Diffusion ====


php 8.2にするとこういうエラー。
===== Hosting =====
[https://we.phorge.it/book/phorge/article/diffusion_hosting/ ◉ Diffusion User Guide: Repository Hosting]


[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
== Shell ==


念のためdockerで起動を試みましたが、同じくトップ画面を開くと同じエラーになります。
=== Shell Command Language ===


<<nowiki>https://notabug.org/gnusocialjp/gnusocial/src/main/docker/development</nowiki>> にDockerでの起動方法があります。`docker compose up -d` を実行するだけでlocalhostでアクセスできます。
==== Compound Commands ====
[https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/utilities/V3_chap02.html#tag_18_09_04 Shell Command Language]


私とあなたとの環境の違いを排除したいので、dockerのインストールだけ頑張って、それでdockerでも簡単に動作確認してくれませんか?
===== Case Conditional Construct =====
case word in
    [(]pattern1) compound-list;;
    [[(]pattern[ | pattern] ... ) compound-list;;] ...
    [[(]pattern[ | pattern] ... ) compound-list]
esac


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


OS内でバージョン違いのプログラムを管理するための仕組みがある。それがupdate-alternativesコマンド。<syntaxhighlight lang="sh">
BREでは未対応な|のORマッチに対応しているのが最大の特徴。文法なのでコマンドを実行せず早い。grepを使わずにできるだけこちらを使ったほうがいい。
sudo update-alternatives --display vi
sudo update-alternatives --config vi
</syntaxhighlight>オプションとコマンド名を指定することで、現在の実体と更新ができる。


=== XAMPP ===
=== ワイルドカード ===
ワイルドカードで.始まりのファイルをマッチさせたい。


==== ポート番号変更 ====
以下ならマッチするが、ブレース展開 (brace expansion) はPOSIX shでは使えなかった気がする。
[https://qiita.com/neneta0921/items/3c2f9ac8ea9b5bcfc6e6 Xamppでポート競合を防ぐ方法 #PHP - Qiita]
echo {.*,*}


XAMPP Control PanelのConfigから変更可能。
=== BOM ===
[https://stackoverflow.com/questions/3127436/adding-bom-to-utf-8-files unicode - Adding BOM to UTF-8 files - Stack Overflow]


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


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


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


UNIX系OSのジョブ管理ツール。タスクの定期実行を可能にする。
===== 特別 =====
* NF: 列数。列の全表示などで使う基本的で重要な変数。
* NR: 行番号。


cronの名前は時間を意味するギリシア語chronosに由来する。
===== スコープ =====
[http://www.fukano.jp/study_of_awk/basic/basic08.htm 変数のスコープ]


指定した時間に1回だけ実行するなら、atがある。電子メールの送信などで役立つ。
関数の仮引数のみ、ローカル変数扱いで、それ以外はグローバル変数。


==== Format ====
==== 文/statement ====
cronの動作はcrontab (cron table) ファイルで指定する。


以下の形式になっている。
* actions
# ┌───────────── 分(0〜59)
** if/else
# │ ┌───────────── 時(0〜23)
** while/do...while/for
# │ │ ┌───────────── 日(1〜31)
** break/continue
# │ │ │ ┌───────────── 月(1〜12)JAN-DEC
** delete
# │ │ │ │ ┌───────────── 曜日(0〜6〈日〜土〉、一部のシステムでは7も日曜日) SUN-SAT
** next
# │ │ │ │ │
** exit
# │ │ │ │ │
* output
# * * * * * [予約するコマンド]
** print
日時部分はいくつか指定方法がある。
** printf
 
* *: すべて。
* */n: nごとに実行 (*/5)。
* ,: 複数の時間間隔を指定 (1,2,3)
* -: 範囲。
* %: コマンド内の%はエスケープされていないと改行文字に変換され、標準入力としてコマンドに渡される。


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


==== Command ====
===== 組込関数 =====


* 編集: crontab -e
* Arithmetic
* 表示: crontab -l
** atan2
* 削除: crontab -r
** cos
 
** sin
-u: 実行ユーザー指定。
** exp
 
** log
==== Log ====
** sqrt
/var/log/cron
** int
 
** rand
[https://askubuntu.com/questions/85558/verify-if-crontab-works cron - Verify if crontab works - Ask Ubuntu]
** srand
 
* String
デーモン自体の確認は以下。
** gsub
systemctl status cron
** index
systemctl restart cron
** length
 
** match
== Visual Studio Code ==
** split
 
** sprintf
=== Keybind ===
** sub
 
** substr
==== 矩形選択 ====
** tolower
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].
** toupper
* I/O
** close
** getline
** system


* s-alt-クリック
print/printfは関数ではなく、statement/文扱い。
* c-s-alt-矢印
ジャンプ


* 括弧ジャンプ: C-S-\
==== ヘッダー出力、列別最大長さ出力。 ====
<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>


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


==== Default terminal ====
## Usage
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].
# awk -f csvparser.awk data.csv


[F1]-[Terminal: Select Default Profile]
# 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
    }
}


=== cscope ===
BEGIN { row = max_idx = 0 }
cscope用のプラグインが何個かある。
{
 
    idx = 0
* [https://marketplace.visualstudio.com/items?itemName=xulion.codescope scope4code - Visual Studio Marketplace]
    sub(/\r$/, "")
* [https://marketplace.visualstudio.com/items?itemName=SeungukShin.cscope-code cscope-code - Visual Studio Marketplace]
    while ($0 != "") {
 
        if (match($0, /^(["]([^"]|["]["])*["]|[^,"]*)(,|$)/)) {
scope4codeのほうがいろいろできそうだが、うまく動作しなかった。使い方がよくわからない。
            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
}


cscope-codeはシンプルだが動作した。こちらを当分使うことにする。
</syntaxhighlight>awkのCSVパーサー。先頭のBOMはあると認識できないので、tail -c +4でBOMを除外して使う。
tail -c +4 data/101543.csv | awk -f csvparser.awk


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


=== Vim ===
==== binary ====
[https://qiita.com/ko1nksm/items/dc8f247cdc5b7b58b736 POSIX準拠のシェルスクリプトでバイナリデータを扱う #Bash - Qiita]


* [https://marketplace.visualstudio.com/items?itemName=vscodevim.vim Vim - Visual Studio Marketplace]
バイナリーデータの読込はodコマンド。なければhexdump。


VSCodedでVimのキー操作を使うためのプラグイン。これが一番人気。いや、Vimのエミューレーターは中途半端な感じだから使わないほうがいいかな。
書込はprintf。


=== Extension ===
head/tailの-cはPOSIXで使えたか?
CSS


Tailwind CSS IntelliSense
== cmd.exe ==


==== PHP ====
=== Control block ===
Laravel Blade Snippets


===== PHP Intelephense =====
==== for ====
Ref: [https://marketplace.visualstudio.com/items?itemName=bmewburn.vscode-intelephense-client PHP Intelephense - Visual Studio Marketplace].
あくまでコマンド。


VSCodeのPHPの補完拡張として人気が高い。
===== nest =====


====== Quick Start ======
* [https://chicagopile1-75.hatenablog.com/entry/2018/05/23/143502 バッチファイルで2重ループ - ハムスターに飼われる院生のブログ]
設置後、しておくべき設定がある。


* Go to <code>Extensions</code>.
* [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/]
* 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ファイルがあれば、関連付けを追加するとか。
=== bitsadmin ===
Windowsでのファイルダウンロードコマンド


====== Module ======
Windows 7以降ではbitsadminコマンドがあり、これがwget相当となる。
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] で追加するとよい。
書式:
bitsadmin /transfer <job name> <URL> <output path>
<job name>と<output path>は必須なので注意する。


====== Coding ======
=== certutil ===
Ref: [https://beyondjapan.com/blog/2020/02/intelephense-vscode-php/ VSCode で PHP 開発するならインテリセンス最強の intelephense を使おう | 株式会社ビヨンド].
Windowsでのハッシュの確認に使える。
certutil -hashfile file


intelephenseでコード補完を認識しやすい書き方というのがある。
SHA1 ハッシュ (対象 C:\moconavi\windows\Moconavi\ext\chromium\moconavium.exe):
e0da85b04b6970ac1f0c33db7a9ad607fdbd44eb
CertUtil: -hashfile コマンドは正常に完了しました。


まず、型をつけられるものはつける。<syntaxhighlight lang="php">
=== rlogin.cmd ===
function superMethod()
コマンドキーの送信を自動化できる?
{
rem rlogin.cmd
    /** @var AwesomeService $awesomeService */
    $awesomeService = $this->app->make(AwesomeService::class);
@Echo off
    $awesomeService->awesomeMethod();
Set SERVER=192.168.0.0
}
Set USERNAME=
</syntaxhighlight>ローカル変数も型名を指定する。これをしないと、インスタンスでコード補完が効かない。
Set PASSWORD=
Cmdkey /generic:TERMSRV/%SERVER% /user:%USERNAME% /pass:%PASSWORD%
Start mstsc /v:%SERVER%
Timeout 5
Cmdkey /delete:TERMSRV/%SERVER%


==E-mail==
=== 実行中プロセスのパスの確認 ===
出典: [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


===General===
=== 簡易編集モード/挿入モード ===


====Naming====
* [https://softantenna.com/blog/windows-10-command-prompt-no-stop/ 【Tips】Windows 10のコマンドプロンプトが意図せず止まってしまう問題を回避する方法 | ソフトアンテナ]
* [https://superuser.com/questions/419717/windows-command-prompt-freezing-randomly Windows command prompt freezing randomly - Super User]


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


*webmaster
cmd.exeを起動-左上のアイコンをクリック-[規定値]/[プロパティ]-[オプション]-[□簡易編集モード] を選ぶ。
*support
*info
*service
*pr
*billing
*氏名


[https://news.mynavi.jp/article/20120315-mailaddress/ 売上をアップするメールアドレス、商機を失うメールアドレス | マイナビニュース]
そのほか、 <code>git log</code> のような制御が移るコマンドを実行してしばらくすると、操作できなくなる。
 
[□挿入モード] にすると回避できる模様。


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


[https://rfc-jp.nic.ad.jp/rfc-jp/RFC2142-JP.txt rfc-jp.nic.ad.jp/rfc-jp/RFC2142-JP.txt]
=== URL ===


[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]
* [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]


公開用のメールアドレス。何にしようか考えていた。
やり方がいくつかある。


<nowiki>RFC 2142</nowiki>でいくつか推奨されている。
# 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


info@ support@ answer@ inquery@ contact@ pubic@
データが決まっているならcsvがシンプル。


contact@がやっぱり一番しっくりくる。info@ support@はRFC 2142にあるけど,これはビジネスより,サービスに紐付いたもの。個人でやる分にはサービス関係ないから,これは違う。publicも悪くはないのだけど,あまり一般的ではないか。
=== HTTP ===
[https://www.rfc-editor.org/rfc/rfc9110.html RFC 9110: HTTP Semantics]


=====develop=====
==== Content-Disposition ====
[https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Content-Disposition Content-Disposition - HTTP | MDN]


<html>
[https://datatracker.ietf.org/doc/html/rfc6266 RFC 6266 - Use of the Content-Disposition Header Field in the Hypertext Transfer Protocol (HTTP)]
<blockquote style="position: relative; padding-left: 55px;">
Content-Disposition: inline
                <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>
Content-Disposition: attachment
                <article>使用するメールアドレスに悩みます。GitのメールアドレスはGitのホスティングサービスに掲載され一般公開されます。<br>
Content-Disposition: attachment; filename="filename.jpg"
                  <br>
filenameでファイル名を指定する。ここの値は二重引用符で囲む。スペースを含む場合に必須になる。
                  メーリングリストのメールアドレスも、返信方法によって引用されアーカイブで一般公開されます。<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がいいと思う。
==== multipart/form-data ====
rfc7578


===== category =====
* [https://datatracker.ietf.org/doc/html/rfc7578 RFC 7578 - Returning Values from Forms: multipart/form-data]
目的に応じて使い分けたほうがよさそう。
* [https://qiita.com/sivertigo/items/14957200af5ad953d63b Multipart/form-dataの仕様メモ #HTTP - Qiita]


[https://upa-pc.blogspot.com/2014/06/mail-security.html メールアドレスを何個ぐらい使い分けたら安全・快適に過ごせるのか - Dr.ウーパのコンピュータ備忘録]
ファイルアップロード用の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を明記して、ボディーでデータを指定する。


不審なメールの検知
[https://weblabo.oscasierra.net/curl-post/ 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 <nowiki>https://xxxxx.net/xxxxxx</nowiki>
* ショッピングサイト
データとテキストを同時送信したい場合、-Fで複数指定する。
curl -X POST -F 'age=30' -F file1=@/var/tmp/sample.jpg <nowiki>https://xxxxx.net/xxxxxx</nowiki>
curlだと上記のboundaryなどをうまくやってくれるのだと思う。


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


* Webサイトなどの公開用
=== IP address ===
* 本名でのやり取り
出典: [https://glocalnet.jp/vpn/topix/archives/67#:~:text=%EF%BC%94%EF%BC%8E%E5%9B%BA%E5%AE%9AIP%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E3%81%AE%E5%8F%96%E5%BE%97%E6%96%B9%E6%B3%95%20%E5%8F%96%E5%BE%97%E6%96%B9%E6%B3%95%E3%81%AF%E4%B8%BB%E3%81%AB3%E3%81%A4%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82,%E3%83%BB%E5%A5%91%E7%B4%84%E3%81%97%E3%81%A6%E3%81%84%E3%82%8B%E3%83%97%E3%83%AD%E3%83%90%E3%82%A4%E3%83%80%E3%81%A7%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%A8%E3%81%97%E3%81%A6%E7%94%B3%E3%81%97%E8%BE%BC%E3%82%80%E6%96%B9%E6%B3%95%20%E3%83%BB%E5%9B%BA%E5%AE%9AIP%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E3%81%AB%E5%AF%BE%E5%BF%9C%E3%81%97%E3%81%A6%E3%81%84%E3%82%8BSIM%E3%82%92%E5%A5%91%E7%B4%84%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95%20%E3%83%BBVPN%E3%82%92%E5%88%A9%E7%94%A8%E3%81%97%E3%81%9F%E5%9B%BA%E5%AE%9AIP%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E3%81%AE%E6%8F%90%E4%BE%9B%E4%BC%9A%E7%A4%BE%E3%82%92%E5%88%A9%E7%94%A8%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95 固定IPアドレスの取得方法 ~実は簡単!フリーランスの方も必見です~|VPN活用日記|トピックス|グローカルネットの快適VPN【公式】| 株式会社グローカルネット]。
* ニックネーム
* 金銭のやり取りのないサービス登録
* 金銭のやり取りのあるサービス登録
* 登録にメールアドレスが必要だけど,そんなに使っていないメール


メールアドレスの種類
自宅サーバーを行う際、固定IPアドレスが必要になる。


* フリーメール
取得方法がいくつかある。
* プロバイダーメール
* 独自ドメイン


[https://afmasakun01.com/3373.html メールアドレスの種類とアフィリエイトにおける3つの使い分け方法 | アフィリエイト]
* 契約しているプロバイダでオプションとして申し込む方法
* 固定IPアドレスに対応しているSIMを契約する方法
* '''VPNを利用した固定IPアドレスの提供会社を利用する方法'''


* サービス登録用
VPNの固定IPアドレスが安いらしい。ryoかsuwakoが解説していた気がする。
* メルマガ購読用(捨てアド)
 
* メインアドレス
=== Authentication ===
認証方式がいくつかある。HTTPで定義される認証方式 (HTTP認証) が有名。
 
==== Basic認証 ====
出典: [https://ja.wikipedia.org/wiki/Basic%E8%AA%8D%E8%A8%BC Basic認証 - Wikipedia]。


[https://d.hatena.ne.jp/okmount/20080505/1209914528 メールアドレスの使い分けかた(前編) - 学習する機械、学習しない人間]
Authorization HTTPヘッダーにBasicのあとに [username:password] をBASE64でエンコードして送信する認証方式。
GET /private/index.html HTTP/1.1
Host: example.com
Authorization: Basic cm9vdDpwYXNzd29yZA{{=}}{{=}}
盗聴や改ざんが簡単だが、シンプルという利点がある。


[https://d.hatena.ne.jp/okmount/20080506/1210002001 メールアドレスの使い分けかた(後編) - 学習する機械、学習しない人間]
==== OAuth ====
Ref


これらを考えてどういう名前で何個用意するかを考える。
* [https://ja.wikipedia.org/wiki/OAuth OAuth - Wikipedia]


とりあえずメインで使うmainというアドレスを一つ用意する。残りをどうするか。
OAuth (オーオース) 権限の認可のための標準。OAuth 2.0が最新の標準。


Webサイト公開用にcontact
以下が登場人物。


* main: メインで使うメール。人に直接教えるときや,お金が絡む場合,ショッピングサイトなど実名が求められるような重要な内容にはこれ。こちらから送信するときもこれ。相手の顔が見えているとき。
* resource owner: あるサイトのユーザー。
* contact:受信専用,公開用。問い合わせ用。なんかフォーラムやブログのコメント欄やcontact usなどにこちらから問い合わせる時なども。相手の顔が見えないときなど。
* resource server: あるサイトのユーザーのデータの保有サーバー。
* clent: クライアントアプリ。リソースサーバーのデータを使用したい。
* authorization server: クライアントにサイトへのアクセスを認証するサーバー。アクセストークンを発行して行う。
 
アクセストークンが実質的なパスワードのようなものだが、resource serverのパスワードを直接渡していない点が重要な違い。パスワードを直接渡さないことで、機能別に権限を細かく利用可否を制御できる。
 
処理の流れ。
 
# 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。
 
Access Token: サイトにアクセスするためのパスワード。
 
=== API ===
 
==== 複数レコードの登録 ====
[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を作るしかなくないか?
 
[https://www.yamarkz.com/blog/rest-web-api-practice REST WebAPIのプラクティス | yamarkz.com]
 
delete_bulkなどのような一括処理用のAPIを作るしかない。内部的には単一処理のAPIを作る感じだったとしても。
 
==== パラメーター ====
[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種類ある。
 
# リクエストボディー
# クエリー
# パス
 
パスはIDなどを指定する場合だけわかりやすい。それ以外のオプションはクエリーのほうがいい。
 
ボディーは、通常サーバーのアップロード・ダウンロードデータとして使われる。クエリーはデータの指定に使う。
 
この原則に従うとシンプルだろう。
 
* URIには長さの制限がある。
* ボディー
** 引数が非常に多い場合。
** 画像などバイナリーデータ。
** キー・値構造を持たない場合。
* クエリー文字列
** 引数を簡単に確認できる。
** 共通の引数の場合。
 
==== 検索機能のGET/POST ====
 
* [https://stackoverflow.com/questions/20550514/post-or-get-in-a-search-form .net - POST or GET in a search form? - Stack Overflow]
 
検索機能にGETとPOSTのどちらを使うか?という議論がある。
 
データ登録するわけなじゃないのだから、GETがいいんじゃない?
 
POSTだと、JSONをそのまま送れるので、複雑なケースに対応できる。特に、配列の送信が重要。
 
GETのほうが検索条件をブックマークにできたり、URLを共有できるので、基本は便利。
 
ただし、検索などのパラメーターが長くなる場合、使用できない。そもそも検索でそんなに長いパラメーターというのがまずいかもしれない。2000文字あれば十分という説がある。
 
==== レート制限対策 ====
 
* [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 リクエスト数によるアクセス制限の対策方法 – 請求管理ロボ ヘルプ]
 
いろいろ方法がある。
 
* cronなどでデータをサーバー上 (DBなど) に定期保存して、保存データを表示させる。
* 配列を利用して、1回のリクエストでまとめて取得する。
* インターバルを設ける。
* HTTP 429/413を検知して、リトライする。
 
==== 指数関数的バックオフ ====
 
* [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://chatgpt.com/c/6747e923-6174-800b-8816-dd741721de45
 
SPA (Single Page Application) やJAMStackの影響で、バックエンドはデータを返すだけで、画面描画はフロントエンドが全部するというのが最近の流行。
 
SSR (Server Side Rendering) とCSR (Client Side Rendering) の違い。フロントエンドの高度化や分業などが理由とのこと。
 
SSRの利点。
 
* SEO
* 初期表示。
* 匿名。
 
SSRの課題。
 
* サーバー負荷: データとHTML作成を同時に行うから。
* 分散困難:
 
キャッシュの活用がポイントになるとのこと。
 
=== curl ===
HTTPの通信のコマンドラインでの確認でよく使う。
 
==== Basic ====
[https://curl.se/docs/tutorial.html curl - Tutorial]
* -X: メソッド指定
* -d/--data-urlencode: リクエストボディー (key=value)を指定。-X POSTも自動指定になる。
curl -H "Content-Type: application/json" -d '{"name":"佐藤", "mail":"sato@example.com"}' localhost:5000/api/v1/users
JSONで送信する場合、ヘッダー指定が必須。
 
<nowiki>*</nowiki>-F: multipart/formのform指定。
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を指定する。
 
==== curl: (60) SSL certificate problem: self-signed certificate ====
Ref: [https://linuxfan.info/curl-insecure curlで「自己署名証明書」を受け入れるには【curl: (60) SSL certificate problem: self signed certificate】 | LFI].
 
--insecureオプションを指定すると、localhostなどでの自己署名証明書を許可する。
 
==== 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]
 
以下のようにhead -n 1を指定するとcurlがエラーを出力する。
curl -H "Content-Type: application/json; charset=utf-8" -H "X-HD-apitoken:$TOKEN"        -d "{\"dbSchemaId\":$dbSchemaId, \"limit\":1, \"offset\":$offset}"        <nowiki>https://$DOMAIN/$ACCOUNT/api/csvexport/version/1.0</nowiki> | head -n 1
 
curl: Failed writing body
curlは標準出力に全部書き込めたかチェックしているようで、head -n 1で切り捨てたらcurlはエラーになる。
 
対策は、curl -sで出力を抑制するとのこと。これで解決。
 
=== Wireshark ===
 
==== TLS ====
Ref: [https://www.toyo.co.jp/onetech_blog/articles/detail/id=36994 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攻撃 ====
いくつか対策方法がある。
 
* [https://lite.ip2location.com/ip-address-ranges-by-country?lang=ja 国別のIPアドレス範囲]
* [https://rakko.tools/tools/11/ IPアドレスから住所検索:国、地域の特定 | ラッコツールズ🔧]
 
サーバーログにIPアドレスが残るから、それで攻撃元の国を特定して、該当国を一括アクセス拒否。これが効果あるかもしれない。
 
攻撃元の国は途上国とかが多いだろうから。IPアドレスは簡単に変更できるが、国を変えるのはたいへんだろう。
 
==== バリデーションの実装 ====
 
* [https://teratail.com/questions/81861 フロント側で入力チェックをしていればサーバー側では入力チェックは必要ない?]
* [https://qiita.com/mi2__user/items/f2f415ccbb0a625c8647 フロントエンドの"バリデーション"は最低限の方がいいらしい。 #TypeScript - Qiita]
 
基本的に、バックエンドで主にチェックして、フロントエンドはUXの向上目的で実装する。データの重複チェックはDBアクセスが必要だったりするから。また、API経由などフロントがそもそもないケースもある。
 
ただ、社内システムのような、画面経由でしか使わない。悪者がほぼいないと思われるケースは、フロントエンドでの検証だけでも十分に感じる。
 
==== 二重送信 ====
 
* [https://www.youfit.co.jp/archives/4545 フォームの二重送信を防止する方法 - 福岡・東京のシステム開発会社 (株)ユーフィット]
* [https://qiita.com/syobochim/items/120109315f671918f28d さいきょうの二重サブミット対策 #JavaScript - Qiita]
 
submitボタンのダブルクリック、リロード、ブラウザーバック・フォワードなど、フォーム周りで注意が必要な保安要素がある。
 
# ボタン連打
# ブラウザーバック
# リロード (PRG)
 
項目ごとにすべき対策が異なる。
 
===== 連打 =====
 
* [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]
 
基本は、ボタンの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系で愛用拡張機能を列挙する。
 
* [https://chromewebstore.google.com/detail/create-link/gcmghdmnkfdbncmnmlkkglmnnhagajbm Create Link]:
 
==== devtool/開発者ツール ====
 
===== イベントリスナー =====
[https://yuzu441.hateblo.jp/entry/2016/12/12/120000 要素に設定されているイベントを調べよう - ゆずめも]
 
[Elements]-[Event Listeners]-[handler]-右クリック-[Show function definition] でイベントリスナー関数の定義を確認できる。
 
===== イベント監視 =====
[https://stackoverflow.com/questions/3787555/how-to-find-out-which-javascript-events-fired How to find out which JavaScript events fired? - Stack Overflow]
 
monitorEvent関数で監視できるらしい。他に、FirefoxのFirebugのlog eventsでも監視できるらしい。
 
==== 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]
 
一応ある。2012-05-09のSafari 5.1.7までWindows版が提供されていた。DL1531。
 
=== Other ===
 
==== Tool ====
 
* [https://web-toolbox.dev/ Web ToolBox | 開発者向けのオンラインツール]
* [https://tm-webtools.com/ TM - WebTools]
 
いくつかWeb関係の開発で役立つツール集を公開しているサイトがある。
 
==== localhost ====
 
* [[wikipedia:Special-use_domain_name|Special-use domain name - Wikipedia]]
* [https://ja.wikipedia.org/wiki/.localhost .localhost - Wikipedia]
 
RFC 6761 で規定。RFC 2606<nowiki/>で予約。DNSに登録されることはないため、テスト目的で使用可能。ループバック (送信元にそのまま返す) インターフェイス。
 
IPv4=127.0.0.1/IPv6=::1とされている。
 
== Shared Host ==
 
=== Free ===
無料で使用可能な共用ホスティングサービスがある。
 
==== スタードメイン無料サーバー ====
ドメインをセットで利用する必要があるものの、スタードメインのスタードメイン無料サーバーがけっこういい。
 
[https://www.star-domain.jp/service/free_server.php 無料レンタルサーバー | スタードメイン - ドメイン取得 100円(税込)~]
 
jpドメインの金額が相場の中では安い方で、それに無料サーバーがついていくる点。
 
* ディスク容量 20GB
* DB 1GB
 
ただし、SSHやコマンドは使えないので、FTPでWordPressを展開して設置するとか、そういう簡単な使い方だけ。ただ、それでもWordPressで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://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の、できるかな?]
 
ルールが特殊なので注意する。
 
ゴミ箱に振り分ける場合。
 
順1 で[<code>./.Trash</code>] を指定
 
順2
 
* 条件:  [<code>.*</code>]
* 処理:  <code>./</code>、に振り分ける
 
条件部分には正規表現が使えるように見える。
 
破棄にしないといけない。転送する場合、カスタムフィルターの中に転送を入れる。条件を.*にする。
 
カスタムフィルターにくせがある。
 
* エスケープ(\を前置する)が必要な文字は「'」「"」「|」「`」「~」「?」「!」
 
==== 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]
* [https://httpd.apache.org/docs/2.4/en/howto/auth.html Authentication and Authorization - Apache HTTP Server Version 2.4]
* [https://httpd.apache.org/docs/2.4/ja/mod/mod_authz_core.html#logic mod_authz_core - 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サービス登録用。
* service: 基本的に受信専用,たまに返信。Webサービス登録用。
* recruit:就職活動用。就職サイトとか転職エージェント,企業とやりとりするときはけっこうメール来るから。
* 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>
<nowiki>https://www.tomtop.com/もだめ。</nowiki>
 
 
今まで使ってきたメールとはどうやりくりするか。
今まで使ってきたメールとはどうやりくりするか。
 
 
Thunderbirdでやる場合,Archiveするときに既読とメールのコピーを行う。
Thunderbirdでやる場合,Archiveするときに既読とメールのコピーを行う。
 
他のアドレスのメールはmainに転送するようにしておいて,mainのメールアドレスで確認。
 
最終的にThunderbirdでArchiveを実行したら,宛先のメールのフォルダーに同じ内容が既読状態でコピーされることにする。
 
このようなフィルターを作っておく。受信時にコピーしてしまうと,未読状態でコピーされてしまうか,受信した瞬間に既読状態になってしまい,見逃す可能性が高い。
 
Manage Identitiesで返信時に受信したアドレスで返信できるように登録しておく。


他のアドレスのメールはmainに転送するようにしておいて,mainのメールアドレスで確認。
==== 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]
Manage Identitiesで返信時に受信したアドレスで返信できるように登録しておく。


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

2024年12月3日 (火) 10:32時点における最新版

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

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で使用可能な絵文字の一覧。

Confluence

ページの中で、 [作成] を選んでページを作ると、階層が勝手にできて、子ページへのリンクもできる。

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程度くらいなら問題ない。

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

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

https://chatgpt.com/c/6745228f-8b20-800b-8a41-bdaece8c03f5

再帰関数とスタックの他に、JSONなどの文字列にシリアライズして、文字列処理で対応するという手もある。

JSONPath/XPathなどの方法もあるが、基本的には外部ライブラリーが必要。

シンプルなケース以外は、再帰関数で処理したほうが結局シンプルな感じがする。

Other

コメントの著者名

https://chatgpt.com/c/67469d8d-7e64-800b-b82d-8c74f4e13c08

GNU socialのソースコードのコメントに著者名が大量にあった鬱陶しい。

大規模プロジェクトになると、編集者が膨大になる。VCSに任せて、本文には記載しなくていいと思う。

git blameで行単位で編集者が分かる。

UML

Tool

https://chatgpt.com/c/67441feb-d004-800b-96fd-0d9b04ffc628

  • デスクトップ
    • StarUML
    • ArgoUML
    • UMLet
  • クラウド
    • Lucidchart: 有料。
    • Creately: 有料。
    • diagrams.net: モデルじゃない。

UmbrelloとModelioはそれらと比較して何がよかったのだっけ?

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] のような形式にすると、キーとバリューが何を意味するか分かってわかりやすい。

array/foreach

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

foreach (table as $row => $line)

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

いいえ。これは問題がある。ネストした場合などに命名規則を維持できない。

  • 配列、コレクション類: 複数形があるなら複数形。困ったらListの接尾辞。
  • 反復時。キーバリュー形式の場合、単数形_key/_value。valueだけの場合、単数形。また、_valueは単数形でもいいかもしれない。

上記の命名規則だとわかりやすい。

$rows = [[]];
foreach ($rows as $row_key => $row_value) {
  foreach ($row_value as $column_key => $column_value) {}
}


foreach ($row_list as $row_key => $row) {
   foreach ($row as $column_key => $column) {
   }
}


foreach ($rows as $row_index => $row_value) {
  foreach ($row_value as $column_index => $column_value) {
  }
}

value部分に単数形を使うと、検索時にkey部分もヒットして、作業しにくいかもしれない。基本はkey/valueの接尾辞がよいと感じる。

もっというなら、接尾辞の文字数が揃うので、keyよりindexのほうがよいかもしれない。ただ、indexは添え字の数字の意味合いが強いので、やっぱりkey/valueでいいか。

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[][]

Project

レガシープロジェクトの立て直し

https://chatgpt.com/c/67481a93-adc0-800b-81c4-20d763133002

1. 現状分析

(1) ソフトウェアの動作確認

現在の環境でアプリケーションを動作させる。

どの部分が機能していて、どこが問題かを確認する。

必要であればエラーログを確認する。

(2) 依存関係の調査

アプリケーションのライブラリやフレームワークのバージョンを調査。

サポートが終了しているもの、互換性が失われたものを特定。

(3) コードベースの状態評価

コードの品質 (可読性、設計、テストカバレッジ) を確認。

セキュリティリスクを特定する (例えば、脆弱性が放置されていないか)。

2. 計画立案

(1) ゴール設定

具体的な目標を設定 (例: パフォーマンス改善、保守性向上、セキュリティ強化)。

(2) 優先順位の決定

どの機能を維持し、どの機能を削除または置き換えるか決定。

ユーザーに直接影響を与える部分を優先。

(3) リスク評価とバックアップ

修正に伴うリスクを評価し、現行システムのバックアップを取得。

3. 環境整備

(1) 開発環境のモダナイズ

ローカル環境やコンテナ (Docker) を用意してテストを容易にする。

CI/CD パイプラインの整備。

(2) 依存関係の更新

サポートされていないライブラリやフレームワークをアップグレードまたは置き換える。

(3) セキュリティの確保

古いOSSの脆弱性を修正。

HTTPSの導入、認証強化、インプット検証など。

4. コードのモダナイズ

(1) リファクタリング

レガシーコードをよりモダンで可読性の高いコードに変換。

デザインパターンを適用して保守性を向上。

(2) テストの追加

ユニットテスト、統合テストを導入。

既存の機能が壊れないことを確認するための自動化されたテスト。

(3) フロントエンド/バックエンドの分離

必要に応じてモノリシック構造を分離し、モダンなアーキテクチャ (SPA、Microservices など) に移行。

5. 機能拡張とデプロイ

(1) 新しい機能の追加

必要に応じて、現代のニーズに合った新機能を実装。

(2) 運用環境でのテスト

新しい環境で徹底的にテストし、問題がないことを確認。

(3) 本番環境にデプロイ

ロールバック計画を準備しつつ、安全にデプロイ。

6. 継続的改善

(1) モニタリングの導入

エラーログやパフォーマンスを監視し、迅速に対応できる仕組みを導入。

(2) 定期的なアップデート

フレームワークやライブラリを継続的に更新し、レガシー化を防ぐ。

(3) コミュニティへの貢献

OSSとしての性質を活かし、変更内容をコミュニティに共有することでフィードバックを得る。

このプロセスを通じて、安定した動作を保ちながら徐々に近代化することが可能です。特に、「現状分析」と「環境整備」をしっかり行うことで、後続の作業がスムーズになります。

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製の以下がよさそう。

  • Tuleap
  • Phabricator/Phorge: 共用サーバー不能。
  • MantisBT
  • FusionForge
  • GLPI
  • Faveo Helpdesk
  • sourcehut - the hacker's forge: Python製。FSF推奨。
  • Fossil

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

phorgeがダメだったので、Mantis/Fossil/sourcehutあたりが共用サーバーで検討可能か。

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

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"

後は開くだけ。

実操作。

こういうディレクトリー構成想定。

public_html
+ phorge.gnusocial.jp 公開ディレクトリー。
+ phorge phorge関係の格納場所。
  + phorge
  + arcanist

取得。

TAG=2024.35
mkdir phorge
cd phorge
PKG=phorge
git clone --depth 1 https://we.phorge.it/source/$PKG.git
cd $PKG; git fetch --depth 1 origin tag $TAG; git checkout $TAG; cd ..
PKG=arcanist
git clone --depth 1 https://we.phorge.it/source/$PKG.git
cd $PKG; git fetch --depth 1 origin tag $TAG; git checkout $TAG; cd ..
git config --add safe.directory arcanist
git config --add safe.directory phorge

phorge/webrootが公開ディレクトリーになるので、これをシンボリックリンクで公開ディレクトリーにリンクする。

DOMAIN=phorge.gnusocial.jp
ln -fns phorge/phorge/webroot ../$DOMAIN

◉ Configuration Guide」に記載のあるリダイレクト設定をする。

以下相当の設定を行う。

<VirtualHost *>
  # Change this to the domain which points to your host.
  ServerName phorge.example.com

  # Change this to the path where you put 'phorge' when you checked it
  # out from the upstream when following the Installation Guide.
  #
  # Make sure you include "/webroot" at the end!
  DocumentRoot /path/to/phorge/webroot

  RewriteEngine on
  RewriteRule ^(.*)$          /index.php?__path__=$1  [B,L,QSA]
</VirtualHost>


<Directory "/path/to/phorge/webroot">
  Require all granted
</Directory>

具体的には、phorge/webroot/.htaccessに以下を記載して、ファイルがなければ作成する。

cat >phorge/webroot/.htaccess <<-'EOT'
RewriteEngine on
RewriteRule ^(.*)$ /index.php?__path__=$1 [B,L,QSA]
EOT

上記設定後phorge.gnusocial.jpにアクセスすると以下のエラーになる。

Request parameter '__path__' is not set. Your rewrite rules are not configured correctly.

上記が少し参考になる。require指令を指定していないのが問題。

うーん。この問題を解決できない。調べても解決例が出てこない。断念する。他のソフトにする。

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を共有できるので、基本は便利。

ただし、検索などのパラメーターが長くなる場合、使用できない。そもそも検索でそんなに長いパラメーターというのがまずいかもしれない。2000文字あれば十分という説がある。

レート制限対策

いろいろ方法がある。

  • 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 の合計に加算するか減算するか、ランダムで選択してください。

バックエンドとフロントエンドの分離

https://chatgpt.com/c/6747e923-6174-800b-8816-dd741721de45

SPA (Single Page Application) やJAMStackの影響で、バックエンドはデータを返すだけで、画面描画はフロントエンドが全部するというのが最近の流行。

SSR (Server Side Rendering) とCSR (Client Side Rendering) の違い。フロントエンドの高度化や分業などが理由とのこと。

SSRの利点。

  • SEO
  • 初期表示。
  • 匿名。

SSRの課題。

  • サーバー負荷: データとHTML作成を同時に行うから。
  • 分散困難:

キャッシュの活用がポイントになるとのこと。

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

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ファイルをドラッグドロップで取り込むこともできる。