インスタンス(オブジェクト)生成時に自動実行される、クラスと同名の特殊なメンバ関数
※オブジェクト生成時に、自動的に、初めにコールされるだけの、メンバ関数(メソッド)の1つ
▼定義方法
・PHP5方式 - 「__construct()(アンダーライン2本で始まる)」
・PHP4方式 - 関数名をクラス名と同名(大文字小文字は区別されない)にする
ex.)クラス名 - 「AIR」、メンバ関数名(コンストラクタ) - 「AIR()」
※PHP4方式とPHP5方式の両方のコンストラクタが定義されていた場合は、PHP5方式がコールされる。
なお、PHP5より導入された「デストラクタ」定義方法は、「__destruct()(アンダーライン2本で始まる)」。
▼コールされるタイミング
・「コンストラクタ」 - 「new演算子」でオブジェクトが生成された時
・「デストラクタ」 - 生成されたオブジェクトが、どの変数からも参照されなくなった時
▼PHP4方式 例
▼結果
/demo/constructor1.html
▼コンストラクタの意義
クラス定義の際、メンバ変数に初期設定出来ない値でも、設定可能にする
※「var」を使ったメンバ変数の定義でセットできるのは定数のみで、定数以外のものをセットしたい場合は、コンストラクタ内でセットする。
クラス定義時におけるメンバ変数・設定可否値
・設定可能な値 - 定数「var $air = "AIR";」「var $signal = array("red", "blue", "yellow");」はセット可能。※「array()」は関数ではなく、言語構造
・設定不能な値 - 関数や演算子を利用しての値。「day $hode = date("Y/m/d H:i:s");」はセット不可。「var $time = 60 * 60 * 24;」といったものも(関数や演算子を使っているので)エラーとなる。また、「var $tokyo[] = "JAPAN";」のような書き方も不可。
▼コンストラクタに引数を渡す PHP4方式
▼結果
/demo/constructor_argument.html
▼PHP5 コンストラクタの定義。メソッド名を「__construct()」とするだけ。コンストラクタのアクセス修飾子は基本「public」に
<pre class="brush: php; collapse: true;">
<?php
class Product{
public function __construct(){//コンストラクタの定義。メソッド名を「__construct()」とするだけ。コンストラクタのアクセス修飾子は基本「public」に
}
}
?>
[/code]
▼結果(単にコンストラクタを定義しただけなので、結果には何も表示されない)
/demo/constructor5_0_1.html
▼PHP5 一般的なコンストラクタ使用例
<pre class="brush: php; collapse: true;">
class Book{
private $name; // 商品名
private $publicationDate; // 出版日
// コンストラクタ(この例の場合、インスタンス生成時にただ一度だけ、値をセットする特殊なセッターのような使い方をしている。理由 ⇒ 出版日は、出版された時点で日付が決まり、後で変更されることがないため。例えば出版日を設定するためにpupublicなsetPublicationDateメソッドを作成してしまうと、いつでも自由に出版日を変更できてしまうことになる。また、プロパティ宣言時に初期値として「private $publicationDate = '20100608'」などと設定してしまうと全ての本の出版日が同じになってしまう)。要件を満たすクラスを実現するためには、外側よりの変更を一切出来なくしなければならないので、プロパティをprivateにし、設定用のメソッドも設定せず、コンストラクタを活用する。
public function __construct($name, $publicationDate){
$this->name= $name;
$this->publicationDate = $publicationDate;
}
// 商品名を取得(ゲッター)
public function getName(){
return $this->name;
}
// 出版日を取得(ゲッター)
public function getPublicationDate(){
return $this->publicationDate;
}
}
$book1 = new Book('PHPStyle', '2010/06/08');
$book2 = new Book('JavaScriptStyle', '2009/01/02');
$name1 = $book1->getName();
$date1 = $book1->getPublicationDate();
$name2 = $book2->getName();
$date2 = $book2->getPublicationDate();
print $name1 . 'は' . $date1 . 'に出版されました。';
print $name2 . 'は' . $date2 . 'に出版されました。';
[/code]
▼結果
/demo/constructor5_0_2.html
▼その他
・オブジェクト生成時の、クラス名の後の「(丸括弧)」は省略出来る。コンストラクタに引数を渡す必要がない場合は書く必要がない。
・クラスを継承した場合、派生クラスのオブジェクトを生成・削除しても、基底クラスの「コンストラクタ」と「デストラクタ」は自動的にコールされないので、「parent::__construct()」や「parent::__destruct()」のように手動でコールする。
▼「コンストラクタ」&「デストラクタ」 PHP5方式
▼結果
/demo/constructor5.html
▼「デストラクタ」内の処理によってスクリプトが終了する場合、それ以降、別の「デストラクタ」はコールされない例
▼結果
/demo/constructor5_1.html
※オブジェクト生成時に、自動的に、初めにコールされるだけの、メンバ関数(メソッド)の1つ
▼定義方法
・PHP5方式 - 「__construct()(アンダーライン2本で始まる)」
・PHP4方式 - 関数名をクラス名と同名(大文字小文字は区別されない)にする
ex.)クラス名 - 「AIR」、メンバ関数名(コンストラクタ) - 「AIR()」
※PHP4方式とPHP5方式の両方のコンストラクタが定義されていた場合は、PHP5方式がコールされる。
なお、PHP5より導入された「デストラクタ」定義方法は、「__destruct()(アンダーライン2本で始まる)」。
▼コールされるタイミング
・「コンストラクタ」 - 「new演算子」でオブジェクトが生成された時
・「デストラクタ」 - 生成されたオブジェクトが、どの変数からも参照されなくなった時
▼PHP4方式 例
class AIRPORT{
var $default;//メンバ変数は、必ずしも値を初期設定(値をセット)する必要はない
function AIRPORT(){//コンストラクタ
$this->default = "NARITA";//「メンバ変数$default」に「"NARITA"」がセット
}
function abroad(){//メンバ関数
echo $this->default;
}
}
$air = new AIRPORT;//オブジェクトを生成する際、殆どの場合「AIRPORT」後ろの「()(丸括弧)」を省略可能
$air->abroad();//メンバ関数の「abroad()」のみを実行
▼結果
/demo/constructor1.html
▼コンストラクタの意義
クラス定義の際、メンバ変数に初期設定出来ない値でも、設定可能にする
※「var」を使ったメンバ変数の定義でセットできるのは定数のみで、定数以外のものをセットしたい場合は、コンストラクタ内でセットする。
クラス定義時におけるメンバ変数・設定可否値
・設定可能な値 - 定数「var $air = "AIR";」「var $signal = array("red", "blue", "yellow");」はセット可能。※「array()」は関数ではなく、言語構造
・設定不能な値 - 関数や演算子を利用しての値。「day $hode = date("Y/m/d H:i:s");」はセット不可。「var $time = 60 * 60 * 24;」といったものも(関数や演算子を使っているので)エラーとなる。また、「var $tokyo[] = "JAPAN";」のような書き方も不可。
▼コンストラクタに引数を渡す PHP4方式
class SIGNAL{
var $signal;//メンバ変数
function SIGNAL($arg = array()){//②引数1のコンストラクタ。受け取った配列を$argへ格納
$this->signal = $arg;//③$argへ格納した配列を、メンバ変数$signalへ格納
}
function check(){//⑤メンバ関数(メソッド)
echo "<pre>";
print_r($this->signal);//⑥メンバ変数$signalを、print_rする
echo "</pre>";
}
}
$signal = new SIGNAL(array("red", "blue", "yellow"));//①インスタンス作成。と同時にコンストラクタ実行。コンストラクタへ配列の引数を渡す
$signal->check();//④メンバ関数check実行
▼結果
/demo/constructor_argument.html
▼PHP5 コンストラクタの定義。メソッド名を「__construct()」とするだけ。コンストラクタのアクセス修飾子は基本「public」に
<pre class="brush: php; collapse: true;">
<?php
class Product{
public function __construct(){//コンストラクタの定義。メソッド名を「__construct()」とするだけ。コンストラクタのアクセス修飾子は基本「public」に
}
}
?>
[/code]
▼結果(単にコンストラクタを定義しただけなので、結果には何も表示されない)
/demo/constructor5_0_1.html
▼PHP5 一般的なコンストラクタ使用例
<pre class="brush: php; collapse: true;">
class Book{
private $name; // 商品名
private $publicationDate; // 出版日
// コンストラクタ(この例の場合、インスタンス生成時にただ一度だけ、値をセットする特殊なセッターのような使い方をしている。理由 ⇒ 出版日は、出版された時点で日付が決まり、後で変更されることがないため。例えば出版日を設定するためにpupublicなsetPublicationDateメソッドを作成してしまうと、いつでも自由に出版日を変更できてしまうことになる。また、プロパティ宣言時に初期値として「private $publicationDate = '20100608'」などと設定してしまうと全ての本の出版日が同じになってしまう)。要件を満たすクラスを実現するためには、外側よりの変更を一切出来なくしなければならないので、プロパティをprivateにし、設定用のメソッドも設定せず、コンストラクタを活用する。
public function __construct($name, $publicationDate){
$this->name= $name;
$this->publicationDate = $publicationDate;
}
// 商品名を取得(ゲッター)
public function getName(){
return $this->name;
}
// 出版日を取得(ゲッター)
public function getPublicationDate(){
return $this->publicationDate;
}
}
$book1 = new Book('PHPStyle', '2010/06/08');
$book2 = new Book('JavaScriptStyle', '2009/01/02');
$name1 = $book1->getName();
$date1 = $book1->getPublicationDate();
$name2 = $book2->getName();
$date2 = $book2->getPublicationDate();
print $name1 . 'は' . $date1 . 'に出版されました。';
print $name2 . 'は' . $date2 . 'に出版されました。';
[/code]
▼結果
/demo/constructor5_0_2.html
▼その他
・オブジェクト生成時の、クラス名の後の「(丸括弧)」は省略出来る。コンストラクタに引数を渡す必要がない場合は書く必要がない。
・クラスを継承した場合、派生クラスのオブジェクトを生成・削除しても、基底クラスの「コンストラクタ」と「デストラクタ」は自動的にコールされないので、「parent::__construct()」や「parent::__destruct()」のように手動でコールする。
▼「コンストラクタ」&「デストラクタ」 PHP5方式
<pre>
<?php
class BASE{
protected function __construct(){//④
echo "○○ 基底クラスコンストラクタ BASE constructor 開始 ○○\n";
echo "○○ 基底クラスコンストラクタ BASE constructor 終了 ○○\n";
}
protected function __destruct(){//⑧
echo "×× 基底クラスデストラクタ BASE destructor 開始 ××\n";
echo "×× 基底クラスデストラクタ BASE destructor 終了 ××\n";
}
}
class SUB extends BASE{
public function __construct(){//②「コンストラクタ」がコールされる
echo "○○○ 派生クラスコンストラクタ SUB constructor 開始 ○○○\n";
parent::__construct();//③
echo "○○○ 派生クラスコンストラクタ SUB constructor 終了 ○○○\n\n";//⑤
}
public function __destruct(){//⑥
echo "××× 派生クラスデストラクタ SUB destructor 開始 ×××\n";
parent::__destruct();//⑦
echo "××× 派生クラスデストラクタ SUB destructor 終了 ×××\n\n";//⑨
}
}
class AIR{
private $id;
public function __construct($id){//⑪⑬⑯⑱⑳
$this->id = $id;
echo "→→→ AIR({$this->id}) constructor →→→\n\n";
}
public function __destruct(){//⑭
echo "←←← AIR({$this->id}) destructor ←←←\n\n";
}
}
echo 'new SUB;', "①オブジェクト生成(変数に代入しない)\n\n";
new SUB;//①オブジェクト生成(変数に代入しない)
$i = 0;
echo 'new AIR(0);', "⑩オブジェクト生成(変数へ代入)\n\n";
$air = new AIR($i++);//⑩オブジェクト生成(変数へ代入)
#オブジェクト生成
echo '>$air = new AIR(1);', "\n",//⑫
'>$air2 = new AIR(2);', "\n",
'>$air3 = new AIR(3);', "\n",
'>$air4 = new AIR(4);', "\n\n";
$air = new AIR($i++);//⑫
$air2 = new AIR($i++);//⑮
$air3 = new AIR($i++);//⑰
$air4 = new AIR($i++);//⑲
#アンセットする
echo '>unset($air3);', "\n\n";
unset($air3);//指定した変数を破棄
#「die()」でスクリプト終了。
die("************ Called die() ************\n\n");
?>
</pre>
▼結果
/demo/constructor5.html
▼「デストラクタ」内の処理によってスクリプトが終了する場合、それ以降、別の「デストラクタ」はコールされない例
<pre>
<?php
class AIR{
private $id;
public function __construct($id){
$this->id = $id;
echo "○○○ AIR({$this->id}) constructor ○○○\n\n";
}
public function __destruct(){
echo "××× AIR({$this->id}) destructor ×××\n\n";
#未定義のメソッドをコールしてエラーを発生させる。
//$this->air();//Fatal error: Call to undefined method AIR::air()
}
}
$air1 = new AIR(1);
$air2 = new AIR(2);
$air3 = new AIR(3);
#未定義の関数をコールしてエラーを発生させる。
//air();// Fatal error: Call to undefined function air()
?>
</pre>
▼結果
/demo/constructor5_1.html