phpの勉強(スコープとOOP)
スコープについて調べようとしたんですが、基本的にグローバル変数と関数内ローカル変数しかないようなので、
OOPも含めて弄っていました。
http://www.thinkit.co.jp/cert/marugoto/1/1/1/2.htm を参考にしました。
アクセス指定子(変数)
<?php class PhpClass { private $private_var = "privateで定義"; protected $protected_var = "protectedで定義"; var $var_var = "varで定義"; public $public_var = "publicで定義"; } class PhpSubClass extends PhpClass { } $subClass = new PhpSubClass(); $subClass->private_var; $phpClass = new PhpClass(); $phpClass->private_var; ?> |
実行結果
$ php class.php PHP Notice: Undefined property: PhpSubClass::$private_var in C:\xxx\php.php on line 11 PHP Fatal error: Cannot access private property PhpClass::$private_var in C:\xxx\php.php on line 13
サブクラスの継承されたprivate変数にアクセスしたときは、Noticeだけど、スーパークラスのprivate変数にアクセスした時は、Fatal errorになるのか。どうでもいいんですが、この一貫性の無さは、いろいろ背景(後付けOOPの経緯など)を物語っているようです。
追記:$subClass->Private_var;(Pが大文字)になってたので小文字に修正したが、メッセージは変わらなかった。
メソッド
<?php class PhpClass { private $private_var = 100; public function getVar() { // return $private_var; これじゃ参照できないみたい return $this->private_var; } } class PhpSubClass extends PhpClass { } $subClass = new PhpSubClass(); print "subclass var: " . $subClass->getVar() . "\n"; $phpClass = new PhpClass(); print "superclass var: " . $phpClass->getVar() . "\n"; ?> |
実行結果
$ php class.php subclass var: 100 superclass var: 100
変数が定義されているクラス内でもthis経由じゃないと参照できないみたいでした。
クラス、メソッドにfinal、abstractもできる。
interfaceもある。
javaのOOPのための機能が用意されている感じでした。
perlのOOP対応と比べるとエライ違いですね。
__call
存在しないクラスのメソッドを呼んだときには、通常「Fatal error: Call to undefined method *****::****()」のようなエラーが出力されますが、__callメソッドを定義しておくと、存在しないクラスのメソッドの代わりに __callメソッドが呼び出されます。これにより、存在しないクラスのメソッドが呼ばれたときの補完を行うことが可能になります。
http://www.thinkit.co.jp/free/marugoto/1/1/3/1.html
おお、AUTOLOADですね。
でも、動的にメソッドを定義することはできないと思うので、perlのAUTOLOADで可能になることよりはメリットは少なそう。
遊んじゃった。タグ生成メソッドを持つクラス
<?php class Tag { public function __call($tag_name, $arguments) { $html = "<$tag_name "; foreach ($arguments[0] as $key => $val) { $html .= "$key='$val' "; } $html .= ">\n" . $arguments[1] . "\n</$tag_name>\n"; return $html; } } $tag = new Tag(); echo $tag->html(array(), $tag->body(array(), $tag->h1(array(), "PHPのお勉強") . $tag->div(array("style" => "font-weight: bold;"), "PHPのお勉強をしていますよ。") . $tag->address(array(), "2007/05/25 smeghead."))); ?> |
実行結果
<html > <body > <h1 > PHPのお勉強 </h1> <div style='font-weight: bold;' > PHPのお勉強をしていますよ。 </div> <address > 2007/05/25 smeghead. </address> </body> </html>
new Tag()->h1(array(), “title”);
みたいな記述ができないなんて。残念! シンタックスエラーになりました。
これ経由で、javaでいうところのtoStringメソッドは、__toStringということを知った。
まとめ
今日も脱線し放題でした。