PHP: the Hypertext Processor の特性を別言語屋視点で見たメモ

以前、ちょろっとPHPを軽く勉強した時のメモがあったので残しておく。PHPは知らんが他の言語はわかる人(どんなやつだ？)向け。
なお、筆者は業務においては主にJava、次いでJavaScriptやPython、滅多にないがVB、更に稀だがC++、一応Scala、Ruby、Perl、Shellあたりもまあどうしても必要ならなんとか読み書きできる、という(ついでにJSPやJSXのようなのが嫌いな)人種であることに留意されたし。

(アセンブラ？ C？ いや嗜み程度には……でもマジでやるの？ って感じ。このあたりになるともうKernelの実装調べたりドライバ書いたりはごくごく稀にする、程度)

# どんな言語なの？ (概ね偏見)
* **Script版JSP**
  * 専用タグを直接HTMLに埋め込んで書く。元はテンプレートエンジンのようなもの
* かつてのCGI全盛期はPerlと人気を二分していた気がする(2000年前後あたりの話では……？)
* 初登場は95年、キャリア長め
  * 現在の文法が確立された(この表現の正当性には疑問が残る)のはバージョン3以降らしい。
  * キャリア長め+お手軽+Web向けということで**古かったり間違ってたり不適切だったりな記事がごまんとある**。
     * この点で某正規表現記事はPHPerを思いっきりDisっていた。いや、別に悪いのはPHPではないが。~~JavaScriptというかjQueryだって似たような状態だ~~

# なんとなく漂うC++感(Better-C的な意味で)
* 行終端は; ブロックは{}
* コメントはC系単/多行とShell/Perl型単行(つまり // , /* */ , # )
* classあり、継承(単一継承のみ)あり。
* namespaceあり。
* 演算子もそっくり。
  * ただし文字列結合は.でやる。"hoge"."fuga"で"hogefuga"。
  * アクセス修飾は\。つまりtop.mid.btmでなくtop\mid\btm。Winのディレクトリか何か？
* 0はfalse。NULLも。
  * というか後述するがもっといろいろfalse。

# JSっぽいとこもある
* 関数はfunctionで作る。戻すのはreturn。
* 等値比較に==と===がある。機能も一緒。
* 配列はすべてdict。
* 未定義(未初期化？)はNULLとして扱われる。
  * undefinedとはちょっと異なるが、まあある意味JSっぽい？
  * 触る際Noticeなるものを送出する。Noticeはログ吐き出しだけが行われる例外的なサムシング。
     * **要するに遅くなる**。配列の扱いには気をつけろってこと。
* いろいろfalse。
  * FALSE
  * 0
  * 0.0
  * ""
  * "0"
  * []
  * NULL
  * 空タグSimpleXML (いまいちピンとこないが、XML版DOMオブジェクト的なアレか？)

# 他
* for, while, foreachあたりはそろっている。
* **elseifでもelse ifでもいい**。
  * ちょっと気持ち悪い。パーサーがややこしそうに思えるが、そうでもないんだろうか。確かに elseif を else if とプリプロセッサ的な置換処理するとかそういうことすれば困らないだろうけど。
* yieldでジェネレータが作れる。
  * こっちはPythonっぽい。どっちが先かは知らないが。
* **変数宣言はない**。

# 他であんまり見ないところ
* **変数には$がつく**。
  * この手の接頭辞はどうにも受け付けなかったが、後述の諸々と合わせてシンボルhogeはアドレス"hoge"を指すポインタである、と考えるとすんなり飲み込めた。
     * 確かRubyがちょうどそんなんだったはず(アレは内部的に整数値のオブジェクトID的なものを指してるんだったな)がある。Perlもそんな感じなんだろうか？ すると頭に記号つける組はだいたいそんなノリなんだろうか。
* 変数はいろいろな用途に使える。
  * コード内: 変数へのアクセス。普通のやつ。
  * リテラル等: 変数のインライン展開。テンプレートストリング的なアレ。
  * \$\$にすると変数の内容物を変数名と認識して展開する。  
    * \$AAA = "BBB" なら \$\$AAA = \$BBB である。
    * もっとつけても展開するらしい。やっぱこれポインタだろ。
    * 曖昧になる場合、{}で囲うことで明確にする。
      * 配列CCCの[1]によって変数に触るなら \${\$CCC[1]}となる。
      * 慣れてる人にとっても闇。そうでしょうとも。
      * なおさらJSPっぽくなった気がするが、元がHTML埋め込み前提なのでむしろこっちが先なのか？
    * たぶんParlとかRubyとかしっかりやってる勢からすると違和感ないんだと思う(偏見)
* 変数名はCase-Sensitiveだが、クラス名、関数名、組み込みキーワードは違う。~~めんどくさい~~
  * 組み込みキーワードはまだしもクラス名と関数名と変数名で食い違うあたり事故の予感しかしない。当たり前だがCase-Sensitiveには期待しないほうがよかろう。
* try-catchはあるがfinallyはない……とよく言われるが**ある**。
  * 昔はなかったらしい。こんな感じでバージョン間の機能差が激しい上、ちょっと差が出るとすぐ動かなくなるとよく聞く。気をつけたほうがよさそうだ。
* 記述開始は <?php , 記述終了は ?>
  * 先述の通りHTML埋め込みでJSPみたいなことする前提の言語だからか。
  * タグの外はすべて吐き出す仕様(そりゃそうだ)なので、**フルPHPのコードで ?> の後に変に改行が入ったりすると死ぬらしい**。ライブラリ書くときは ?> を略すこともあるとか。
* 文字列が4種類ある。
  * シングルクォート: そのまま表示。**\${hoge}が効かない方の普通の文字列**。
  * ダブルクォート: 変数展開、特殊文字列変換を行う。**/${hoge}が効く方の普通の文字列**。
  * ヒアドキュメントheredoc : 複数行ダブルクォート。 <<<hoge ～ hoge; で括る。改行は改行として解釈され、変数展開等も行われる。該当のheredocな文字列自体には**括るのに使った識別子**(例の場合hoge)**で触れる**。
  * ナウドックnowdoc: 複数行版シングルクォート。 <<<'hoge' ～ hoge; 改行は改行として解釈され、変数展開等は行われない。該当のnowdocな文字列自体には**括るのに使った識別子**(例の場合hoge)**で触れる**。
* const/staticアクセスは :: でやる。
* スコープが独特。
  * ローカル(関数), グローバル, スーパーグローバル(!?)の三種。
     * ローカルは普通の関数スコープ。
     * グローバルはグローバルなのだが、**使う側でglobalキーワードを付けて宣言する必要がある**。グローバルとは一体何だったのか。
     * スーパーグローバルはglobalキーワードのいらないグローバルであり、いわゆるグローバル変数。ただし定義済み変数用。いつでもどこでもそこにいる。