# ch06 — static プロパティ・メソッド

Source: https://php-school.pages.dev/topics/class-advanced/ch06-static/
Site: AIと学ぶPHPの学校 (https://php-school.pages.dev)
Lesson: クラスの応用
Level: L3

Reference (official): https://www.php.net/manual/ja/language.oop5.inheritance.php

## 本文

# ch06 — static プロパティ・メソッド

## 概要

`static` プロパティは **インスタンスごとに別々に持つのではなく、クラス全体で 1 つだけ共有される値** だ。通常のプロパティ (`public $name`) は `$a` と `$b` を作ると別々の `name` を持つが、`public static $count` は `$a` も `$b` も同じ `$count` を共有する。インスタンスを何個作ったかを数えるカウンタや、クラス全体で使う設定値など「インスタンス間で共通の記録」を持たせる用途で使われる。

参照の書き方は **クラス内からは `self::$name`、クラス外からは `ClassName::$name`** で、いずれも `->` ではなく `::` (スコープ解決演算子) を使う。`static` メソッドも同様に `ClassName::method()` の形で呼び出せて、インスタンスを作らずに呼べる。これは「ユーティリティ関数の集まり」のようなクラス (`Math::sqrt(2)` 的なもの) を作るときに便利だが、状態を持つ static は **テストが書きにくい / 副作用が追いにくい** という弱点もある。

補足として PHP には `self::` と `static::` の違いがあり、これは **遅延静的束縛 (late static binding)** という機能。`self::` は「書かれているクラス」を、`static::` は「呼び出されたクラス」を指すので、継承して使うときに挙動が変わる。本章では `self::` を使う基本パターンに留め、`static::` は必要になったときに調べる程度の認識でよい。

## 学習目標

- `static` プロパティはインスタンスごとではなく **クラス全体で 1 つ** 共有される
- `self::$name` でクラス内から、`ClassName::$name` で外から参照できる
- インスタンス数カウンタなど「クラスの記録」を持たせられる

## 所要時間

スライド 5 分 + ドリル 1 問 = **12 分**

## ドリル

| no | 内容 |
|---|---|
| 01 | `User::$count` をインスタンス生成ごとにインクリメントする |

## 採点

```bash
php scripts/grade.php topics/class-advanced/ch06-static/drill/01-counter/
```

## 関連チャプター

- [`ch07-const`](../ch07-const/) — 変更不可のクラス定数との対比
- [`../../08-class/ch06-constructor`](../../08-class/ch06-constructor/) — コンストラクタでカウントを増やす
- [`../../08-class/ch07-visibility`](../../08-class/ch07-visibility/) — `public static` / `private static` の修飾

## スライド

---
marp: true
theme: dojo
paginate: true
size: 16:9
---

<!--
LLM_CONTEXT:
  Lesson 9 / Chapter 6
  目的: static プロパティ・メソッドでインスタンスをまたいで共有される値・機能を扱う
  扱わない: const (ch07) / final (ch08) / late static binding (static::) は範囲外
  読み上げ時間目安: 4 分半〜5 分
-->

# static プロパティ・メソッド

Lesson 9 / Chapter 6

---

## 普通のプロパティはインスタンスごとに別

```php
<?php
class User {
    public string $name;
}

$a = new User();
$a->name = "A";

$b = new User();
$b->name = "B";

echo $a->name . "\n";  // A
echo $b->name . "\n";  // B
```

- インスタンスを 2 つ作れば、`$name` も 2 つ存在する
- でも「全インスタンスで共有する値」が欲しいときがある

---

## `static` プロパティはクラスで 1 つだけ

```php
<?php
class User {
    public static int $count = 0;
}

User::$count = 5;
echo User::$count . "\n";  // 5
```

- `static` を付けると **クラス全体で 1 つ** だけ存在する
- インスタンスを作らなくても使える
- 外からは `ClassName::$プロパティ名` で参照

---

## クラス内からは `self::` で参照

```php
<?php
class User {
    public static int $count = 0;

    public function __construct() {
        self::$count++;
    }
}

new User();
new User();
new User();
echo User::$count . "\n";  // 3
```

- クラスの中では `self::$count` と書く
- インスタンスを作るたびにコンストラクタで `++` する
- `User::$count` は全インスタンスで共有されているので「合計人数」になる

---

## static メソッドも書ける

```php
<?php
class Calc {
    public static function add(int $a, int $b): int {
        return $a + $b;
    }
}

echo Calc::add(2, 3) . "\n";  // 5
```

- `static function` で定義
- 呼び出しは `ClassName::method()`
- インスタンスを作らずに使える (ユーティリティ向き)

---

## このチャプターでできるようになること

✅ `static` プロパティはクラスで 1 つだけ
✅ `self::$name` (中) / `Class::$name` (外) で参照できる
✅ `static function` でインスタンス不要のメソッドを定義できる
✅ インスタンス数カウンタなどに使える

→ ドリルへ
