はじめに
PHP・WEB開発を独学中アラフィフ主婦の忘備録です。
定数とは
変数と同様の性質を持っているが、再代入できない値のこと。
- システム固有の番号など一度定めたら原則として変更しない値を保存します。
- クラス内で定義された定数のことをオブジェクト定数といいます。
サンプルコード
class Item
{
// const キーワードを用いてオブジェクト定数を定義
const VAT = 1.2; // 定数名は全て大文字
// 複数の単語はアンダースコア _ で繋ぐ(コンスタントケース または アッパースネークケース)
public $cost = 200;
public function displayCost()
{
// クラス内からオブジェクト定数へのアクセス
// self::オブジェクト定数
echo (int)($this->cost * self::VAT), "円\n";
}
}
// クラス外からオブジェクト定数へのアクセス方法は2つ
// 1. インスタンス生成なしで出力
echo Item::VAT . "\n"; // クラス名::定数名
// 2. インスタンス生成してから出力
$item = new Item();
echo $item::VAT . "\n"; // オブジェクト変数::定数名
$item->displayCost(); // `displayCost()`メソッド(関数)を実行
出力結果
1.2
1.2
240円
定数を使うことによって、消費税の変更が無いのに誤ったプログラムにより値が再代入され、本来表示したい金額よりも高い金額・税率が表示されてしまうという不具合を回避することができます。
【疑問点1】オブジェクト定数はなぜ大文字?
他のコードとの一貫性
- 定数の名前をすべて大文字にするのは、広く使われている慣習です(PHPに限らず、C、Java、Pythonなどの言語でも同様)。
- 一貫性のあるルールがあれば、他のプログラマや自分自身がコードを見たときに、変数と定数を瞬時に区別できるため、メンテナンス性が向上します。
定数と変数の区別がつきやすい
- 定数は再代入できない固定値ですが、変数は変更が可能です。大文字で書くことで「この値は不変である」という意図を明示します。
- 大文字にすることで、定数と他の変数やプロパティを明確に区別できます。
const vat = 1.2; // これも実行できるが...
public $vat = 0.8; // 変数も似た名前にすると混乱の原因に
読みやすい命名(複数単語の区切り)
- アッパースネークケース(例: TAX_RATE)では、複数の単語をアンダースコアで区切るため、読みやすくミスが少なくなります。
const TAXRATE = 1.2; // 読みにくい
const TAX_RATE = 1.2; // 読みやすい
公式ドキュメントやコミュニティの推奨事項
PHPの公式ドキュメントやコミュニティのスタイルガイドでも、定数名には大文字を使用することが推奨されています。これに従うことで、他の開発者と協調して作業する際に混乱が起きにくくなります。
【疑問点2】$this->cost
と self::VAT
でアクセス方法が異なるのはなぜ?
同じクラスの中の関数に書かれているのに、$this->cost
と self::VAT
ではアクセスの仕方が違うはどうして?
プロパティと定数の違い
それぞれが持つ性質の違いにより、アクセスの仕方が異なります。
プロパティ($this->cost)の性質とアクセス
- プロパティは、インスタンスごとに異なる値を持つことができます。
- そのため、プロパティにアクセスする際は、
$this
キーワードを使ってそのインスタンス(オブジェクト)自身に紐づけてアクセスします。
$this->cost // `$this`は、現在使っているインスタンス自身を指す
例えば、2つの Item
オブジェクトがあれば、それぞれで異なる cost
を持たせることができます。
class Item
{
const VAT = 1.2;
public $cost = 200;
public function displayCost()
{
echo (int)($this->cost * self::VAT), "円\n";
}
}
// 実行してみよう
$item = new Item();
$item->displayCost(); // $costを指定しないとクラス内で定義した200で計算される
$item->cost = 3000; // $costに3000を代入
$item->displayCost(); // 3000でメソッド(関数)が実行される
$item->cost = 25000; // $costに25000を代入
$item->displayCost(); // 25000でメソッド(関数)が実行される
出力結果
240円
3600円
30000円
定数(self::VAT)の性質とアクセス
- 定数は、クラス全体で共通の値を表します。つまり、全てのインスタンスで共有され変更できません。
- 定数にアクセスする際は、
self::
を使ってクラス自身に紐づけます。self::
は「このクラス自身に定義された定数」を指します。
self::VAT
定数はインスタンスではなくクラスに属するため、$this
(インスタンス)ではなく、self::
を使います。
アクセスの違い "まとめ"
プロパティと定数の性質の違いが、$this->
と self::
の使い分けを生んでいます。
項目 | プロパティ | 定数 |
---|---|---|
所属 | インスタンス | クラス |
アクセス方法 | $this->プロパティ名 |
self:: 定数名 |
値の変化 | 各インスタンスで異なることが可能 | すべてのインスタンスで共通 |
変更 | 可能 | 不可能 |
オブジェクト定数 ”まとめ”
- オブジェクト定数とはクラス内で定義された定数のこと
- const をつけて定義する
- 変更しない値を保存する
- 定数名は自由につけられるが全て大文字にする
- クラス内からアクセスするには
self::定数名
- クラス外からアクセスするには
クラス名::定数名