PHPでのオブジェクト指向プログラミング

クラス

クラスの定義
<?php
class クラス名{
    //クラスの定義
}
インスタンスの生成と使い方
<?php
class Employee{
    public function work(){
        //メソッドの中身
    }
}
?>
<?php
//インスタンスの生成
$yamada = new Employee();
//メソッドの呼び出し
$yamada->work();
アクセス修飾子

メソッドやプロパティがどこからアクセス可能かを表す修飾子

public クラスの外側から参照・呼び出しができる
private 自分のクラスの内側からのみ参照・呼び出しができる
protected 自分のクラスの内側または、自分のクラスを継承したクラスの内側からのみ参照・呼び出しができる
プロパティ

アクセス修飾子のあとに変数名を付けて定義する。

<?php
class Employee{
    public $name;
}
$yamada = new Employee();
$yamada->$name = '山田';
$this

オブジェクトのインスタンス化を行うとクラスのメソッドで利用できる$thisという変数が自動的に定義される。
$thisは自分自身のオブジェクトの参照。

staticプロパティ

プロパティの宣言時にstaticを付けるとそのプロパティはクラスがインスタンス化されなくても読み書きすることができる。
staticプロパティはへクラス名にダブルコロン(::)をつけてアクセスする。

<?php
class Employee{
    public static $company = 'aaa';
}
echo Employee::$company,PHP_EOL;
self

クラスコンテキストの内部ではそのクラス自身を指し示すキーワード。
selfはダブルコロンと一緒に持ちい、メソッド、定数、プロパティにアクセスすることができる。

定数

クラス定数はクラス内に定義することができる定数。
constキーワードを用いて定義する。変数名ではないので$をつける必要はない。
定数に出kkるのはスカラー値のみ。
アクセスするにはクラス名にダブルコロンと定数名を記述する。

メソッド

メソッドはクラスに属する関数のようなもの。関数と同じようにfunctionキーワードを用いて定義する。
プロパティ同様アクセス修飾子を指定する。

<?php
class クラス名{
    アクセス修飾子 [final] [static] function [&] メソッド名 ([引数,...]){
        //メソッドの定義
    }
}
staticメソッド

staticプロパティ同様にインスタンス化されていなくても外部から直接呼び出すことができる。
staticメソッドの中では$thisを使用することはできない。

コンストラクタとデストラク

クラスのインスタンスが作られたり消されたりするタイミングで自動的に呼ばれるメソッド。
省略することができ定義しなければ呼び出されない。

<?php
class クラス名{
    public [final] function __construct([引数,...]){
        //メソッドの定義
    }
    public [final] function __destruct([引数,..]){
        //メソッドの定義
    }
}

コンストラクタはオブジェクトを生成するうえで必要なパラメータや、そのクラスのオプションなどを引数として受け取り、プロパティにセットするという役割がある。

継承

継承とは、あるクラスのメソッドやプロパティを引き継いで新しいクラスを定義すること。
継承されたクラスを親クラス(スーパークラス)継承したクラスを子クラス(サブクラス、派生クラス)と呼ぶ。
PHPでは多重継承は許されておらず、継承することのできる親クラスは1つ。
子クラスでは親クラスで定義されたプロパティやメソッドにアクセスできる。

<?php
class クラス名 extend 親クラス{
    //クラスの定義
}
オーバーライド

オーバーライドとは、親クラスに定義されたプロパティやメソッドを子クラスに同じ名前で定義すると、子クラスではそのメソッドの実装などが上書きされること。
オーバーライドメソッドは、親クラスで定義されたメソッドと引数が違ってはいけない。
ただしデフォルト値の引数に追加されることは許される。
またコンストラクタは親クラスに定義されたコンストラクタと引数が違ってもよい。

parent

クラスコンテキストの中で、parentキーワードは親クラスを表すキーワードになる。
使い方はselfキーワードと同じ。

final

finalキーワードを付けてメソッドを宣言すると、そのメソッドは継承された派生クラスでオーバーライドできなくなる。

抽象クラス

抽象クラスは、共通の機能を抽象的な親クラスで定義して、特有の機能は個々の子クラスでそれぞれ実装させたい場合に定義する。
abstractメソッドはメソッドの実装は定義せず、宣言のみを行う。
抽象クラスはそれ自体をインスタンス化することはできない。必ず抽象クラスを継承したクラスをインスタンス化する。
抽象クラスを使うには、抽象クラスで継承した子クラスで定義し、全てのabstructメソッドを実装する必要がある。

<?php
abstruct クラス名{
    abstruct アクセス権 function メソッド名 ([引数,...]);
}
インターフェイス

インターフェイスとは、複数の異なるクラスに共通の機能を実装するためにその実態を定義することなく指定する仕組み。
インターフェイスを用いると特定のオブジェクトが特定の機能を有することが保障される。
インターフェイスのメソッドはpublicでなければならない。
インターフェイスの定義には実態のあるメソッドを定義できない。
このインターフェイスを実装するクラスで定義しなければいけないメソッドを定義する。

<?php
interface インターフェイス名{
    //インターフェイスの定義
}

インターフェイスをクラスに実装する場合はimplementsキーワードを使う。

<?php
class クラス名 implements インターフェイス名 [,インターフェイス名...]{
    //クラスの定義
}

PHPは変数の型宣言がないため、普通に引数のリストを定義すると渡された変数が正しくそのインターフェイスの実装かどうか保障されず、インターフェイスを定義することのメリットが半減される。
そこで渡された変数が特定のインターフェイスを実装しているかチェックする方法がある。
1つ目はタイプヒンティング、2つ目は型演算子(instanceof)。

マジックメソッド

マジックメソッドとは特定の条件で自動的に呼び出されるメソッド。
PHPにはコンストラクタとデストラクタを含め14のマジックメソッドがある。
マジックメソッドはオブジェクトに対する特定の操作に対するフック。
オブジェクトがどう扱われたときにどのような挙動を示すかを1つずつ実装して決めることができる。

遅延静的拘束

継承されたクラスのメソッドなどを親クラスで解決するための機能。

オーバーロード

クラスを必要なときに読み込むための仕組み。
定義されていないクラスを使おうとしたときに指定されたオートロード関数が呼び出される。

名前空間

名前空間とはクラスや関数の使える名前の集合を限定し、関数名やクラス名の衝突を防いだり、機能の参照をわかりやすくするための機能。
名前空間を利用するときのポイント。

  • 名前空間の区切りにはバックスラッシュ(\)を使う
  • 名前空間を定義した場合、グローバルな関数やクラスには先頭にバックスラッシュを付け、グローバルな名前空間から参照しなければならない

名前空間における言葉の定義

名前空間の定義
<?php
namespace 名前空間;
namespace 名前空間\サブ名前空間;

名前空間の影響受けるのは

  • クラス
  • 関数
  • 定数
<?php
namespace Project/Module;
class Directory{}   //Project/Moduleクラス
function file () {} //Project/Module関数

別の名前空間から参照される場合は、完全修飾名を指定する。

<?php
namespace Other;
require_once 'Project\Module\Directory.php';
$dir1 = new \Project\Module\Directory();
1つのファイルに複数の名前空間を定義する

1つ目はnamespace宣言を複数する方法。

<?php
namespace Project\Module;
namespace Profect\Module1;

2つ目は{}で囲う方法。

<?php
namespace Project\Module{

}
namespace Project\Module1{

}
インポートルール

名前空間を使う際、別の名前空間やそれに属するクラスをuseキーワードを使ってインポートしたり、asキーワードにより別名をつけることができる。

<?php
use \クラス名;
use 名前空間;
use 名前空間 as 別名;
use 名前空間\クラス名;
名前解決

名前空間の影響を受ける、クラス、関数、定数の定義が読み込まれそれが実際に呼び出されるまでには、コンパイル時の変換と、実行時の名前解決という2つのフェーズがある。
コンパイル時には、useキーワードによってインポートされた名前空間やクラス名でスクリプト内で使われているクラスや定数を変換する。

動的な名前空間の利用

可変変数や可変関数や動的なクラス名など、変数に文字列を代入して動的に利用できたように、名前空間でも同じように動的な名前空間の利用ができる。
文字列の定義にダブルクォートを用いると、\はエスケープ文字とみなされてしまうため、\\とする必要がある。
シングルクォートで囲う場合で末尾に名前空間区切りが来る場合、末尾のシングルクォートのエスケープと判断されないために\\とする必要がある。

例外

<?php
//例外の送出
throw new 例外クラス名([メッセージ,[エラーコード,[前の例外オブジェクト]]]);
//例外の捕捉
try{
    //処理
} catch(例外クラス名 変数名){
    //例外処理
}

全ての例外の基底となるのがExceptionクラス。
Exceptionクラスにはエラーメッセージやエラーコードを取得するメソッドなどが定義されている。
例外を拡張する場合でも全ての例外クラスはExceptionクラスを継承しなければならない。