目次
1. 本記事のポイント
- PHPのstaticメソッド・プロパティの基本構文と動作原理を解説
- インスタンス不要で利用できる場面と設計上の注意点を紹介
- self/parent/staticによる参照の違いと活用例を提示
2. PHPのstaticメソッド・プロパティとは?
PHPにおけるstatic
は、クラスに属するメソッドやプロパティをインスタンスを生成せずに利用可能にするためのキーワードです。JavaやC#などの他言語と同様、共通的な処理や定数的な値を定義する場面で使われます。
主な用途としては以下が挙げられます:
- ログ出力やユーティリティ関数など、状態を持たない処理の提供
- オブジェクト生成前の設定値の保持
- クラスごとの共有リソース(例:接続数カウントなど)の管理
実務では、ユーティリティクラスや定数管理クラスなどに多用されます。ただし、staticな設計はオブジェクト指向の柔軟性を損なう可能性もあるため、使用には注意が必要です。
3. 詳細解説
基本構文:staticメソッドとプロパティの定義と呼び出し
静的メソッド・プロパティはstatic
キーワードを付けて定義し、クラス名またはselfキーワードでアクセスします。
PHP
class MathUtil {
public static int $count = 0; // 静的プロパティ
public static function add(int $a, int $b): int {
self::$count++;
return $a + $b;
}
}
// 呼び出し例
$result = MathUtil::add(3, 5);
echo $result; // 8
echo MathUtil::$count; // 1
静的プロパティは、全インスタンスで共通の値を持ちます。インスタンスごとの状態を扱いたい場合には不適です。
self / static / parent の違いと使い分け
継承時にstaticな要素を参照する際、self::
とstatic::
で挙動が異なります。
PHP
class Base {
public static function who() {
echo "Base\n";
}
public static function callSelf() {
self::who();
}
public static function callStatic() {
static::who();
}
}
class Child extends Base {
public static function who() {
echo "Child\n";
}
}
Child::callSelf(); // Base
Child::callStatic(); // Child
self::
は定義元のクラス(この場合はBase)を基準に、static::
は実行時のクラス(この場合はChild)を基準に解決されます。これをLate Static Binding(遅延静的束縛)と呼びます。
static変数との混同に注意
static
はメソッド・プロパティ以外にも、関数内変数に使うことができます。用途とスコープが異なるため混同しないようにしましょう。
PHP
function counter() {
static $i = 0; // 初回のみ初期化
$i++;
return $i;
}
echo counter(); // 1
echo counter(); // 2
関数内のstatic
変数は呼び出し間で状態を保持し続けます。クラス外での状態保持に利用されるケースもあります。
4. よくあるミス・誤解・落とし穴
- 静的プロパティをインスタンス経由で操作してしまう
インスタンスからでもアクセスは可能ですが、可読性・設計上の観点から非推奨です。 - オーバーライドがself参照で効かない
継承を意識した設計では、self::
よりもstatic::
を使うほうが動的な挙動になります。 - 状態を持つ処理にstaticを使ってしまう
staticにすると依存関係を隠蔽しやすく、テストや拡張性が損なわれます。状態を持つ処理はインスタンス側に持たせるのが基本です。 - クラスプロパティの初期化順に注意
PHP 8.1以降、初期化順・型制約が厳密になっており、未初期化のstaticプロパティへのアクセスはエラーになります。
5. まとめ
PHPのstaticメソッド・プロパティは、共通処理の整理や効率的なリソース管理に役立ちますが、柔軟性とのトレードオフがあります。
- クラス名またはself/staticでアクセスする点を正しく理解すること
- 継承を意識する場合は
static::
を活用すること - 状態を持たせる用途では安易に使わないこと
設計意図に合わせて適切に使い分けることで、保守性の高いコードを実現できます。