[PHP]オブジェクト指向プログラミング

初心者な自分用メモ、みたいなもんです…。
把握までの過程をメモってるので同じく初心者には分かりやすいかも?
考え方はJavacriptも同じだと思う。

名称

とりあえず呼び方がややこしい。初心者はまずここが覚えられない。

  • メソッド(method)
    クラス内にある関数(function)のこと
  • プロパティ(property)
    クラス内の変数(variable)のこと。メンバ変数も同じ意味
  • コンストラクタ(Constructor)
    初期化用のメソッド。オブジェクト生成時にやりたいことを入れる
  • 継承(Inheritance)
    クラスを元に新しいクラスを作る。上手いこと作らないとかえって面倒なことになるらしい

$this->hoge

簡単なクラスのサンプルを見る。

class Test{
var $hoge = "hoge";
	function Foo(){
		echo $this->hoge;
	}
}
$obj = new Test();
$obj -> Foo();

「なんでわざわざ$thisなんて書くの?$hogeでよくね?」

で実際に「$hogeって書いたらいいじゃない」というものを書くと何も表示されない。

class Test{
var $hoge = "hoge";
	function Foo(){
		echo $hoge;
	}
}
$obj = new Test();
$obj -> Foo();

$objの前に$hoge = “hoge”;と書いても何も出ない。

疑似変数thisの意味はjavascriptと同じ。
▼たとえば今使ってるテーマの検索フォーム

<input type="text" value="Keyword(s)" onfocus="if (this.value == 'Keyword(s)') this.value = '';"  value="Keyword(s)" />

onfocusがjavascriptだが、この指示の意味は「フォーカスされたらvalueを消す」
this.value=テキストエリア.値。
thisの直訳で「この」とか「これの」でもいいかも。つまり自分自身を指す。

Testというクラスの中に$hogeもFoo()も入ってるのに…と思うけども、
もともとPHPが$hogeとか書くだけで簡単に変数が出来るところに原因がある。
上のソースだと$obj -> Foo();で実行したときに、echoするための$hogeが新しく作成されてしまう。
新しく作成された変数hogeは空なので、何も表示されない結果になる。
$this->hogeとすると、「このクラス内にある変数hogeのこと」という指示が明確にされるので、結果を表示するようになる。

これはもうそういう風に出来てる、と捉えるしかないようだ。

カプセル化

そもそもオブジェクト指向プログラミングはカプセル化してなんぼ、らしい。

クラスで使われてるメソッドやプロパティはなるべく隠し、外部とやりとりするものだけを最低限の範囲で出しておく。
クラスとやり取りするときは極力メソッドを通すと、内部に使われてる変数名を気にしなくてもよくなるし、
間違ったアクセスは除外することができるようになる。

よくあるHelloWorldのクラスを作ってみる。

class Hello{
	var $name = "Taro";//メンバ変数(プロパティ)
	
	function hello_world(){//メソッド
		print "こんにちは".$this->name."さん";
	}

}

$hello = new Hello();//インスタンス作成
$hello->hello_world();

名前をKenに変えたい場合は$hello->name="Ken";すればいいが
「アクセスには極力メソッドを通す」というのに基づくと次のようになる。

class Hello{
	var $name = "Taro";
	
	function set_name($s){
		$this->name = $s;
	}
	function get_name(){
		return $this->name;
	}
	function hello_world(){
		print "こんにちは".$this->get_name()."さん";
	}

}

これで$hello->set_name("Ken")で名前を変えれるようになるが、
PHP4のクラスは、クラスの内部に対するアクセス制限ができないため、相変わらず$hello->name="Ken";でも変更出来てしまう。
これが間違ったアクセスならば、除外できてないということになる。
PHP4のクラスが不完全といわれるのはこの辺に理由があるらしい

PHP5だとメンバ変数のアクセス権(visibility)に制限が掛けれるようになる。
visibilityというとCSSのプロパティにもあるけど、外から見えるようにするかしないか、という意味にすれば同じだと思う。

  • public ・・・ どこからでもアクセス可能。varはこれ
  • protected  ・・・ 派生クラスや親クラス (とそれを定義するクラス自体) にアクセスを制限
  • private ・・・ それを定義するクラスのみにアクセス権を制限

varは後方互換のために使えてるだけらしい。

さっきのソースの$nameのところにアクセス制限をかけてみる。

class Hello{
	private $name = "Taro";
	
	function set_name($s){
		$this->name = $s;
	}
	function get_name(){
		return $this->name;
	}
	function hello_world(){
		print "こんにちは".$this->get_name()."さん";
	}

}

$hello = new Hello();
$hello->name="Ken";
$hello->hello_world();

「Cannot access private property Hello::$name」というエラーが出て、メンバ変数の値を直接変更出来なくなり、
名前を変更するには必ずメソッド$hello->set_name("Ken");を通らなければならなくなる。
でもまだget_name()にはアクセスできるので、さらにメソッドにも制限をつける。

class Hello{
	private $name = "Taro";
	
	public function set_name($s){
		$this->name = $s;
	}
	private function get_name(){
		return $this->name;
	}
	public function hello_world(){
		print "こんにちは".$this->get_name()."さん";
	}

}

これで完全にアクセス可能な場所が制限された。

確かにこれだけ限定されてれば、クラス内を変更したときの外への影響は少なくなる。

クラスを使うメリットが分かりづらい件

上に挙げたサンプルソースみたいな小さいものだと、「普通にfunctionのがよくね?」と思うわけだが、それは多分正しい。だって回りくどいんだもの。
クラスの恩恵が受けられるのはある程度規模のあるプログラムを扱う時。
たとえばアレだ、Wordpressのプラグインとか。

実装する機能が似てれば、プラグインの名前も似たようになりがちだが

  • 他の同じ機能を持つプラグインと関数名がダブりやすくなる
  • 関数間で使い回したい変数や定数もダブりやすくなる

結果、重複を避けるために名前がやたら長くなったりする。

クラスを使えば、クラスの中で作られる関数や変数名は外では無効になる。
さらにいちいち初期化しなければならない変数も、コンストラクタでおk。
インスタンスの変数名とクラス名の重複さえ気をつければいい。
プラグインでクラスを使わなくても、クラスが使われてるライブラリを使う機会はあるかも。

WordPressはphp4から動作サポートしてるから、プラグインもPHP4で動くように作られてるものの方が多い。
アクセス権みたいなPHP5の機能はWordpressのサポートが終わってから使った方がいいんだろうなあ…。

というわけで唐突にクラスとオブジェクトについて調べたのはプラグイン作成の為でした。

1件のコメント

  1. うまくまとめられてて、最近OOPを覚え始めた自分には非常によい確認事項となりました。
    ヽ(o’д’o)ノアリガ㌧♪。

    Reply
  2. 日付見たら2年前でびっくり 😮
    覚え始めならPHPでOOPってwikiが参考になりますよ~

    Reply

Leave a Comment.