PHPのクラスの第4弾です。第5弾まであります。クラスは多機能で、理解するべき内容がたくさんありますが、その分使いこなせると便利なので、がんばりましょう。 今回は静的メンバー・静的メソッドについて扱います。

PHPのクラス その4

1年以内に更新されました。
更新日 : 2019年05月08日

PHPのクラスの第4弾です。第5弾まであります。クラスは多機能で、理解するべき内容がたくさんありますが、その分使いこなせると便利なので、がんばりましょう。

今回は静的メンバー・静的メソッドについて扱います。

静的メンバー・静的メソッドとは

通常のメンバーやメソッドは動的

PHPのクラスその2その3ではメンバーとメソッドを扱っていきました。

これらのメンバーやメソッドは、インスタンス化をした時点で利用することができました
逆に言えば、インスタンス化しなければ使用することができませんでした。今まで使用してきたメソッドやメンバーは、動的メソッドと言われることがあります。

まず動的の意味を考えていきましょう。

インスタンス化すると、クラスという設計図から実体が生成され、それぞれのインスタンスごとにメンバーが持つデータやメンバーを扱うメソッドを実行することができました。

つまりインスタンスごとにメンバーに格納されているデータや、メソッドの挙動が変化するのです。この変化する様をIT用語で動的と表すことが多いです。

では逆に静的とは?

変化するものを動的と呼ぶのであれば、逆に変化しないもの静的と言います。

動的メンバー・動的メソッドが、インスタンス化をしなければ扱えなかったのに対し、静的メンバー・静的メソッドでは、インスタンス化しなくても利用できます。静的なメンバーやメソッドで一番大切なのは、インスタンス化しなくても利用できることです。

今回はその静的な機能を作っていきます。

静的メンバーや静的メソッドの概念

以下の図を見てください。

静的メンバーや静的メソッドは、インスタンスに属するのではなく、クラス自身に属します。そのため、インスタンスを作っても作らなくてもアクセスや実行ができ、いくらインスタンスを作成しても、実行できる静的なメンバーやメソッドは1つずつしかありません。

静的メンバーと静的メソッドの作り方

静的メソッドの作り方

まずは下記のコードを見ていきましょう。

<?php

class Calculator {

	// 足し算
	public static function add($x, $y) {
		return $x + $y;
	}

	// 引き算
	public static function sub($x, $y) {
		return $x - $y;
	}

	//平均 エラーの場合は0を返す
	public static function average($numbers) {
		if(!is_array($numbers)) {
			return 0;
		}
		// ローカルスコープ変数count、total
		$count = count($numbers);
		$total = 0;

		foreach ($numbers as $value) {
			if(!is_numeric($value)) {
				return 0;
			}
			$total += $value;
		}

		$average = $total / $count;
		return $average;
	}
}

echo Calculator::add(5, 7) . '<br>';

echo Calculator::sub(10, 5) . '<br>';

echo Calculator::average(array(20, 30)) . '<br>';

静的メソッドはstatic修飾子をつけるだけです。アクセス修飾子 static functionのように記述します。

今回作成したCalculatorクラスは静的なメソッドが3つ存在するため、この3つのメソッドはインスタンス化しなくても利用可能です。

実際にインスタンス化せずにメソッドを実行しているのがCalculator::add(5, 7)などの記述部分です。

静的メソッドを利用する際には、クラス名::メソッドの用に記述します。

今回はクラス内に静的メソッドだけが実装されていますが、動的メソッドと静的メソッドが混在していても問題ありません。先の説明の通り、動的メソッドはインスタンス化しないと実行できません。

静的メンバーの作り方

静的メンバーもほとんど作り方は変わりません。今回はデザインパターンの1つであるシングルトンと呼ばれる実装方法で見ていきます。

<?php

class SingletonSample {

	private static $instance;

	public $number;

	private function __construct() {
	}

	public static function getInstance() {
		if(is_null(SingletonSample::$instance)) {
			SingletonSample::$instance = new SingletonSample();
		}
		return SingletonSample::$instance;
	}
}

// コンストラクタがprivateなので以下はできません
//$sample1 = new SingletonSample();

$sample1 = SingletonSample::getInstance();
$sample2 = SingletonSample::getInstance();

if($sample1 === $sample2) {
	echo "同一インスタンス<br>";
} else {
	echo "異なるインスタンス<br>";
}

$sample1->number = 20;

echo $sample1->number . '<br>';

echo $sample2->number . '<br>';

$sample2->number = 50;

echo $sample1->number . '<br>';

echo $sample2->number . '<br>';

private static $instance;ここが静的メンバーの宣言です。
静的メソッドと同様にアクセス修飾子 static メンバー変数のように宣言します。

アクセスする際も、静的メソッドと同様にクラス名::メンバー変数のように利用しますが、動的メンバーの利用のときと違い、$が必要になりますSingletonSample::$instanceが実際に静的メンバーにアクセスしている部分です。

シングルトン実装について

シングルトンという実装では、コンストラクタをprivateにします。つまり外部からインスタンス生成ができません

インスタンスをどのように生成するかというと、インスタンスの生成をgetInstanceメソッドにまかせています。このメソッドはpublicかつ静的メソッドなので、外部からSingletonSample::getInstance()というふうに実行できます。

getInstanceメソッドでは、静的なメンバーである$instance変数の中身だけを返します。なのでインスタンスも1つしか作成されないことが保証されます。これがシングルトンと呼ばれる実装方法です。

インスタンスが1つしか生成されないため、$sample1$sample2には同じインスタンスが格納されています。そのため通常のメンバーである$numberを変更すると、どちらも同じ$numberを変更したり利用することになり、実行結果が以下のようになります。

まとめ

静的メンバーと静的メソッドについて説明しました。

追加でシングルトンの説明まで簡単に行いましたが、静的メンバーと静的メソッドの使用例の1つです。今回大切な内容は以下です。

  • 静的メソッドはアクセス修飾子 static function 〜〜で宣言
  • 静的メンバーはアクセス修飾子 static 変数名で宣言
  • 静的メソッドの実行時はクラス名::静的メソッド名で実行
  • 静的メンバーへのアクセスはクラス名::静的メンバー名で利用
  • 静的メンバーへのアクセス時に$を忘れずに!!