6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

phpでクラスと関数の名前がかぶった時の挙動|バグの原因になるかも?

Last updated at Posted at 2018-02-07

#経緯
オブジェクト指向を再入門中に以下のコードを書いていたところ
予想していた結果と違っていた。
自分的に忘れそうなのでメモします。

php.php

class TestObject {
	public $subject;
	private $message = "オブジェクト";

	public function testobject() {
		echo $this->message;
	}
}

$instans = new TestObject();
$instans->testobject();

実際の結果.php
オブジェクトオブジェクト
予想していた結果.php
オブジェクト

#原因
色々とテストし、調査してみて結論としてはクラス名と関数名が
かぶっているときに発動する挙動でした。
こちらの記事が参考になりました。

どうやらphp4のころはコンストラクタを指定するときに
クラス名と同じ名前の関数を定義していたらしい。

だからコンストラクタとして認識され2回出力されていたんですね。

そういえばphpstormからConvert constructor new styleなんてメッセージがでていて
最初「関数を一つしか定義しないとコンストラクタとして認識されるのか?」と思いました。

しかし、いろいろテストしているとどうもそうでもないらしい。
そこで以下のようにしてみると

テスト1.php

class TestObject {
	public $subject;
	private $message = "オブジェクト";

	public function testobject() {
		echo $this->message;
	}
}

$instans = new TestObject();
//$instans->testobject();

テスト1結果.php
オブジェクト

やはりコンストラクタとして認識されるっぽい。

しかし上記のソースを以下のように変えると

関数を2つ定義した時.php
class Test_object {
	public $subject = "サブジェクト";
	private $message = "オブジェクト";

	public function test_object() {
		echo $this->message;
	}
	public function test_subject() {
		echo $this->subject;
	}

}

$instans = new Test_object();
$instans->test_object();
$instans->test_subject();
関数を2つ定義した時ー結果.php
オブジェクトオブジェクトオブジェクト

2つあっても発動している。
「関数を一つしか定義しないとコンストラクタとして認識されるのか?」説は間違いと判明。

ここでもしやと思い「PHP クラス名 関数名 同じ」で検索して
こちらの記事にたどり着きました。

クラス名と関数名を違うものに設定.php
class Test_Object {
	public $subject = "サブジェクト";
	private $message = "メッセージ";

	public function testmessage() {
		echo $this->message;
	}
	
}

$instans = new Test_Object();
$instans->testmessage();
クラス名と関数名を違うものに設定ー結果.php
メッセージ

やはり名前がかぶったことが原因のよう。。。
確認のため

クラス名と関数名を同じに設定.php
class Test_Object {
	public $subject = "サブジェクト";
	private $message = "メッセージ";

	public function test_object() {
		echo $this->message;
	}
	
}

$instans = new Test_Object();
$instans->test_object();
クラス名と関数名を同じに設定ー結果.php
メッセージメッセージ

#結論
phpでクラスと関数の名前がかぶった時にコンストラクタとして認識される。
参考記事

また改めて検索してみて以下の記事も参考にさせていただきましたので張り付けておきます。
関数名とクラス名が被っても大丈夫
__construct()があると、クラス名と同じメソッドはコンストラクタとはならないみたい

ちなみにphpのバージョンは5.6、7.0共に同じ挙動でした。

6
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?