続・お正月はPHPと格闘
高木です。こんばんは。
昨日に引き続き、お正月に帰省中ですがPHPと格闘しています。
前回は長くなりすぎて中断してしまいましたので、その続きを今回書くことにします。
前回書き切れなかった内容は次の3つです。
- 名前空間
- 関数の引数や返り値の型指定
- eval
PHPに名前空間が導入されたのはバージョン5.3.0からのようなので、かなり新しい仕様の部類に入ります。
私も名前空間の存在は知っていましたが、本格的に取り組んだのは今回が初めてでした。
名前空間そのものはC++やC#なんかでも馴染みがあるため、それほど難しいものではありませんでした。
しかし、PHP特有の問題があってかなり苦戦しました。
たとえば、C++やC#ではusingを使うことで名前空間の指定を省略することができました。
しかし、PHPのuseでは名前空間に別名を付けるだけで、いったん(グローバルではない)名前空間の中で定義してしまうと、その名前空間の外では必ず名前空間を指定しなければならないようです。
また、グローバル変数はあくまでも名前空間内のもので、異なる名前空間のグローバル変数に直接アクセスする方法はないようです。
一方で、定義済みのグローバル変数である$argcや$argvなどは、どこからでもアクセスできるようです。
スーパーグローバルも然りです。
includeやrequireでスクリプトを取りこんだとき、ドキュメントでは
ファイルが読み込まれるとそのファイルに含まれるコードは、 includeもしくはrequireが実行された 行の変数スコープを継承します。 呼び出し側の行で利用可能である全ての変数は、読み込まれたファイル内で利用可能です。 しかし、読み込まれたファイル内で定義されている関数やクラスはすべて グローバルスコープとなります。
と記述されています。
これを言葉通りに解釈すると、特定の名前空間からincludeやrequireで取りこんだ場合は名前空間が継承されそうに思いますが、そうではないようです。
この辺りはまだよく分かっていないところでもありますので、もう少し調査が必要です。
次に、関数の引数や返り値の型指定についてです。
引数の型指定は「型宣言」というらしいですね。
この仕様は「タイプヒンティング」という名前で、限定的ではありますがバージョン5.0.0から導入されていたようです。
現在の「型宣言」になったのはバージョン7.0.0からですのでかなり新しい仕様ということになります。
一方、返り値の型指定はバージョン7.0.0から導入されました。
これは最新の仕様といってよいでしょう。
なぜか、ドキュメントでは、ページの見出しは「返り値」なのに、その項目は「戻り値の型宣言」となっており訳語に一貫性がありません。
私はずっと「型指定」といっていましたが、PHP的には「型宣言」が正しいのかもしれませんね。
さて、この「型宣言」ですが、そんなに難しい概念でもなく、容易に導入できる仕様だと思います。
しかし、今回は私の無知が原因で少しはまってしまいました。
PHPでは普段型名を使う機会がそんなにないので、型名に関する理解が乏しかったのが原因です。
私は型宣言にbooleanと書こうとしていたのですが、boolを使うのが正しいようです。
キャストだとどっちでもいいのに、型宣言でbooleanを使うとbooleanクラスと解釈されるようでうまくいきません。
他にも似たような落とし穴があるのかもしれませんね。
最後はevalです。
Webアプリケーションではevalは使うべきではないのでしょうが、コマンドラインツールであれば気にせず使っています。
evalそのものは以前から使っていました。
今回よく分からなかったのは、evalで評価したコードの名前空間についてです。
ドキュメントにも何も書いていないと思っていたのですが、こんなところにコッソリ書かれていました。
evalで評価したコードはグローバル空間になるようです。
今回はこれが自分のやりたいことにうまく合致したので助かりました。
けれども、そうではない場合もあるはずなので、その場合は明示的に名前空間を指定するコードを先頭に付加してあげないといけないでしょうね。
このようにざっと見てきましたが、PHPの言語仕様は結構大きく、しかもよく変わります。
私のようにときどきしかPHPを触らないものにとっては、なかなか難しい言語のひとつです。
まあ、それでもPHPは嫌いではないので、今後も積極的に関わっていきたいと考えています。