#はじめに
最近、static
がインスタンス化したものにも影響を及ぼすということを知らずに使ってしまい、その挙動に戸惑ったことがあるのでそのことについて書きたいと思います。
この記事を読めばstatic
の理解が少し深まります。
まず、以下のような課題があったとします。
Q. 以下の仕様を満たし、次の出力結果が出るようにコードを追記せよ。※環境はPHP7.4
とします。
出力結果
田中さんは日本人です。
ジュリーさんはアメリカ人です。
黄さんは中国人です。
ミュラーさんはドイツ人です。
<?php
class Person
{
/* コードを記述 */
}
$person1 = new Person("田中", "日本");
$person2 = new Person("ジュリー","アメリカ");
$person3 = new Person("黄","中国");
$person4 = new Person("ミュラー","ドイツ");
$persons = [ $person1, $person2, $person3, $person4 ];
foreach ($persons as $person) {
echo /* コードを記述 */ . "さんは" . /* コードを記述 */ . "人です。\n";
}
さて皆さんは無事に書けましたかね
コード例は以下になります。
<?php
class Person
{
public $name;
public $country;
public function __construct($name,$country) {
$this->name = $name;
$this->country = $country;
}
}
$person1 = new Person("田中", "日本");
$person2 = new Person("ジュリー","アメリカ");
$person3 = new Person("黄","中国");
$person4 = new Person("ミュラー","ドイツ");
$persons = [ $person1, $person2, $person3, $person4 ];
foreach ($persons as $person) {
echo $person->name . "さんは" . $person->country . "人です。\n";
}
田中さんは日本人です。
ジュリーさんはアメリカ人です。
黄さんは中国人です。
ミュラーさんはドイツ人です。
本来はこれで問題ないのですが、当初私は、スコープ演算子を使って、どこからでもアクセスができるstatic
を使うのもいいんじゃない?いけるんじゃね?と考えた結果、以下のようにコードを考えました。
<?php
class Person
{
public static $name;
public static $country;
public function __construct($name,$country) {
self::$name = $name;
self::$country = $country;
}
}
$person1 = new Person("田中", "日本");
$person2 = new Person("ジュリー","アメリカ");
$person3 = new Person("黄","中国");
$person4 = new Person("ミュラー","ドイツ");
$persons = [ $person1, $person2, $person3, $person4 ];
foreach ($persons as $person) {
echo Person::$name . "さんは" . Person::$country . "人です。\n";
}
```
すると
出力結果は
```
ミュラーさんはドイツ人です。
ミュラーさんはドイツ人です。
ミュラーさんはドイツ人です。
ミュラーさんはドイツ人です。
```
となり、あれ?ミュラーさんが4人も出てきたぞ!なんでやねんおかしいやろ!?
ってことで知人エンジニアに質問をしたり調べたりでこうなる理由が解明できました。
要はstatic変数はクラスレベルの変数のため、static変数を変更すると、そのクラスのすべてのインスタンスに影響するとのことです。
以下の記事の```なぜstaticを乱用してはいけないのか```が特に参考になりました。
https://qiita.com/ue_knnk/items/fa84b8bc30ba319e5744
なので今回のコードに関しては、コンストラクタで、```$name```、```$country```を代入してそれらがstatic変数になるという仕組みになってしまった結果、
一番最後に代入された```ミュラー```、```ドイツ```がstatic変数となってしまい既にインスタンス化された他の3つにも影響し、このような出力結果になってしまったという訳です。(なるほど)
#最後に
今回は```static```についての記載をしましたが、私を含めこれを知らなかった初学者もいると思いますので(いなかったらすみません)少しでも役立って貰えれば幸いです。