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ということを知った。

まとめ

今日も脱線し放題でした。

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です


reCaptcha の認証期間が終了しました。ページを再読み込みしてください。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください