【PHP】static・const・defineの挙動の違いと、呼び出し方$this・self::の意味

変数や定数を定義するときに使うstatic、const、defineについて、挙動を試してみたのでメモ。

またstatic、const、defineそれぞれの特徴と、$this、self::の呼び出し方の意味についてまとめる。

## それぞれの特徴
### staicとは

> クラスプロパティもしくはメソッドを static として宣言することで、 クラスのインスタンス化の必要なしにアクセスすることができます。
> 

[PHP: static キーワード - Manual](https://www.php.net/manual/ja/language.oop5.static.php)

staticが付いていない通常のメンバ変数は、生成したインスタンス毎に管理される。

一方staticが付いていると、インスタンスに関係なくメンバ変数の実体は1つのみとなる。

### constとは

> 値が変更できない [定数](https://www.php.net/manual/ja/language.constants.php)をクラス内に定義することができます。 クラス定数のデフォルトのアクセス範囲は `public`
 です。
> 

> クラス定数はクラス単位で割り当てられるものです。インスタンス単位ではないことに注意しましょう。
> 

[PHP: クラス定数 - Manual](https://www.php.net/manual/ja/language.oop5.constants.php)

・値が変更できない
・クラス内で定義する

というのがポイント。

### defineとは

> 実行時に、名前を指定して定数を定義します。
> 

[define](https://www.php.net/manual/ja/function.define.php)

 

`define($name, $value);`のように、名前を指定して定数を定義する。

constと違って、プログラム内のどこからでも呼び出せるグローバルな定数を宣言するもの。

## 色々な挙動を試してみる

### クラス内で値を再代入する

```php
class classA
{
    public $myVal = 'my val';
    public static $myStatic = 'my static';
    public const MYCONST = 'my const';
    define('MYDEFINE', 'my define');    // エラー

    public function assign()
    {
        $this->myVal = 'change my val';
        self::$myStatic = 'change my static';
        self::MYCONST = 'change my const';    // エラー
    }
```

- 通常のメンバ変数　→代入できる
- static　→代入できる
- const　→代入できずエラーになる
- define　→定義できずエラーになる
    
    グローバルな定数を宣言するものなので、クラス内で定義しようとするとエラーになる。
    
    defineは下記のようにクラス外で使用する。
    
```php
define('MYDEFINE', 'my define');
    
class parent
{
      // 省略
```
    

### defineで定義した定数と同じ名前の定数をconstで定義する

```php
define('MYDEFINE', 'my define');

class classA
{
    public const MYCONST = 'my const';

    public function assign()
    {
		MYDEFINE;
        self::MYDEFINE;
    }
```

 `MYDEFINE` と呼び出せばdefineで定義した値、 `self::MYDEFINE` と呼び出せばクラス内でconstで定義した値を呼び出せる。

### 親クラスで定義したstatic変数を子クラスで書き換える

```php
// 親クラス
class Parent
{
	public static $myStatic = 'parent static';
}

// 子クラス1で親クラスのstatic変数を書き換える
class Child1 extends Parent
{
	public function __construct($companyid)
    {
		parent::$myStatic = 'change child1';
    }
}

// 子クラス2で親クラスのstatic変数を呼び出す
class Child2 extends Parent
{
	public function __construct($companyid)
    {
    	echo(parent::$myStatic);
    }
}
```

子クラス1をnewしてコンストラクタを実行してから、子クラス2をnewしてコンストラクタを実行したとする。

すると子クラス1で親クラスのstatic変数を書き換えているので、子クラス2で親クラスのstatic変数を使用するときには `'change child1'` が中に入っている。

## 変数や定数を呼び出す際の$thisとself::について

### $thisとは

> $thisは、呼び出し元オブジェクトの値です。
> 

[PHP: クラスの基礎 - Manual](https://www.php.net/manual/ja/language.oop5.basic.php)

$thisはインスタンスを指す。

通常PHPではローカル変数のスコープは関数内のみだが、$thisを使えばスコープ外で定義された変数も使えるということ。

### $thisの後ろにつける「->」とは

「->」はアロー演算子というもので、インスタンスのプロパティやメソッドにアクセスするときに用いる。

 `$インスタンスを代入した変数名->呼び出したいインスタンスのプロパティまたはメソッド名` のようにして使う。

### self::とは

self:: は自クラスを示す。

クラス定数やstatic変数は、インスタンス毎に管理されるものではなくクラスで共通であり、インスタンス化せずに使用することができる。

よって$thisは使わずself::を使用する。

### selfの後ろにつける「::」とは

> スコープ定義演算子 (またの名を Paamayim Nekudotayim)、 平たく言うと「ダブルコロン」は、トークンのひとつです。 [static](https://www.php.net/manual/ja/language.oop5.static.php), [定数](https://www.php.net/manual/ja/language.oop5.constants.php) およびオーバーライドされたクラスのプロパティやメソッドにアクセスすることができます。
> 
> 
> これらの要素をクラス定義の外から参照する際には、 クラスの名前を使用してください。
> 

[PHP: スコープ定義演算子 (::) - Manual](https://www.php.net/manual/ja/language.oop5.paamayim-nekudotayim.php)

「::」はスコープ定義演算子というもので、クラスの定数や静的なメソッドにアクセスするときに用いる。

 `クラス名::呼び出したいクラスのプロパティまたはメソッド名` のようにして使う。