質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

2回答

294閲覧

どうして、真になるのか

aaaaaaaa

総合スコア501

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2018/03/27 10:44

下記のようにシングルトンパターンでインスタンスを作ると

php

1class single { 2 private static $singleton; 3 4 public static function kansu() { 5 if(!isset(self::$singleton)) { 6 self::$singleton=new single(); 7 } 8 return self::$singleton; 9 } 10} 11$hensu1 = single::kansu(); 12$hensu2 = single::kansu(); 13 14if($hensu1 === $hensu2) { 15 print "hensu1とhensu22は、一致する";//一致する 16} else { 17 print "hensuとhensu2は、一致しない"; 18}

作成された二つのインスタンスは、trueとなりますがシングルトンパターンではない方法で作るとfalseになります。
シングルトンパターンがインスタンスを一つにしたいときに利用するもの、「インスタンスは、一つまで」とソース内で書いても間違って二つ以上のインスタンスを作ってしまわないようにするさいに利用するのだろうということはわかるのですが、なぜ、上記のようにソースを記述するとtrueになるのかがわかりません。
つまりシングルトンパターンではないときのクラスを二つ以上実体化したとき(そのときは、falseとなる)と何が違って、このような差がでるのだろうという疑問であります。
上記のように記述するとインスタンスが同じメモリのアドレス?に保存されるのでしょうが、上記のソースを見つめていても答えが出ません。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

キーになっているのは static によるものです

静的変数の使用

変数のスコープに関する別の重要な機能は、静的 (static) 変数です。静的変数はローカル関数スコープのみに 存在しますが、プログラム実行がこのスコープの外で行われるようになってもその値を失わない(ママ)ません。次の例を見てください。

まず、静的(static)メソッドkansu()に対する最初のコール

PHP

1$hensu1 = single::kansu();

で、

PHP

1public static function kansu() 2{ 3 if(!isset(self::$singleton)) // ←ここではまだ静的変数$singletonはセットされていなので 4 { 5 self::$singleton=new single(); // ←ここに入ってsingleクラスのインスタンスが生成され、静的変数$singletonに代入されます。 6 } 7 return self::$singleton; // ←そして、それをreturnします 8}

ここで、いったんこのスコープを抜けるわけですが、前述のとおり static 宣言してある変数$singletonはスコープを抜けても破棄されず、保持され続けます。

そして次の

PHP

1$hensu2 = single::kansu();

で再び静的(static)メソッドkansu()に対するコールが行われ

PHP

1public static function kansu() 2{ 3 if(!isset(self::$singleton)) // ←ここで、先ほどの静的変数$singletonが保持されているので 4 { 5 self::$singleton=new single(); // ←ここには入らない為 6 } 7 return self::$singleton; // ←先ほどの静的変数$singletonをreturnします 8}

結果、最初の静的コールで得たインスタンスと、二回目の性的コールで得たインスタンスは同じメモリ上のインスタンスを指し示すことになり、比較結果がマッチしてtrueとなるわけです。

これが、static というものの挙動です。

投稿2018/03/27 12:31

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/03/27 12:37

微妙に説明が悪いかもな…
guest

0

ベストアンサー

PHPはほとんど判らんけれど, こういうことではないですか?

PHP

1class single { 2 private static $singleton;//←シングルトンインスタンスを保管しておく変数 3 //private・・・singleクラス外部からのアクセスが出来ない 4 //static・・・クラスに属する変数(インスタンスごとに作られない) 5 6 //インスタンスを取得するための関数 7 public static function kansu() { 8 if(!isset(self::$singleton)) {//←シングルトンインスタンスが無ければ・・・ 9 self::$singleton=new single();//←シングルトンインスタンスを作って・・・ 10 } 11 return self::$singleton;//←そのシングルトンインスタンスを返す 12 } 13} 14//見た目上, 二つのインスタンスを生成しているように見えるが・・・ 15$hensu1 = single::kansu();//←シングルトンインスタンスを取得 16$hensu2 = single::kansu();//←シングルトンインスタンスを取得 17 18//実際には二つの変数は同一のインスタンスを参照しているので・・・ 19if($hensu1 === $hensu2) { 20 print "hensu1とhensu2は、一致する";//一致するのです 21} else { 22 print "hensuとhensu2は、一致しない"; 23}

NOTE:
このままですとクラスsingleのコンストラクタが外部に公開されたままになっていますからnew single()を使ってしまうと・・・

PHP

1$hensu1 = single::kansu();//←シングルトンインスタンスを取得 2$hensu2 = new single();//←別のインスタンスを生成 3 4//二つの変数はそれぞれ異なるインスタンスを参照しているので・・・ 5if($hensu1 === $hensu2) { 6 print "hensu1とhensu2は、一致する"; 7} else { 8 print "hensuとhensu2は、一致しない";//一致しません 9}

singleクラスのコンストラクタをprivate化(外部からのnewによるインスタンス生成が出来なくなる)したほうがよりシングルトンらしくなります.

PHP

1class single { 2 private static $singleton; 3 4 //コンストラクタをプライベート化してしまう. 5 private function __construct(){} 6 7 //インスタンスを取得するための関数 8 public static function kansu() { 9 if(!isset(self::$singleton)) { 10 //ここはsingleクラス内のコードなのでコンストラクタを呼び出せる 11 self::$singleton=new single(); 12 } 13 return self::$singleton; 14 } 15} 16 17$hensu1 = single::kansu(); 18$hensu2 = new single();//プライベートなコンストラクタを呼び出そうとしているのでエラーとなります. 19/* 20つまり, インスタンスを入手するには, single::kansu()を呼び出さねばならず, 21single::kansuの内部ではたった一つのインスタンスしか作りませんから, 22singleクラスがシングルトンであることが保証されるのです. 23*/

投稿2018/03/27 10:52

編集2018/03/27 11:58
defghi1977

総合スコア4756

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/03/27 11:07

多分、staticって何か、どういう挙動するものなのかがわからないんですよね。 PHPだと、ワザと使わないとあんまり利用する機会がないから。 そこに絞って説明してあげたほうが良いんじゃないかな。
defghi1977

2018/03/27 11:16

Javaと同じ感覚で回答しちまったけれど, 「クラスに属する静的なprivate変数」の役割についてまだ見えていないってのは感じますね. > 作成された二つのインスタンスは、trueとなりますがシングルトンパターンではない方法で作るとfalseになります。 よーくこの文面から見ると, シングルトンの正確な意味がまだ理解できていないような気もするし
退会済みユーザー

退会済みユーザー

2018/03/27 11:22

phpは特殊でメソッドに紐づくstatic変数という楽しいものが作れる
退会済みユーザー

退会済みユーザー

2018/03/27 11:25

ちょっと今、HPが0なので普段のように書き起こす気力がわかないのです…。
退会済みユーザー

退会済みユーザー

2018/03/27 12:17

ちなみにPHPのSingleton作成方法はこちら https://ideone.com/C6vDkM メソッド内 static 変数により Java の static final と同様の扱いをする。
defghi1977

2018/03/27 12:21

> phpは特殊でメソッドに紐づくstatic変数という楽しいものが作れる > メソッド内 static 変数により Java の static final と同様の扱いをする。 なるほど
aaaaaaaa

2018/03/30 10:28

ご回答ありがとうございます。 >>シングルトンの正確な意味がまだ理解できていないような気もするし もしよろしければ、シングルトンについて教えて頂けるとさいわいです。
defghi1977

2018/03/30 10:36

> 作成された二つのインスタンスは、trueとなりますがシングルトンパターンではない方法で作るとfalseになります。 がおかしく、正しくは 「二つの変数が指し示すインスタンスはシングルトンパターンでは一致し, そうでない場合は一致しない」 (※これでもまだ曖昧ではある) です. あなたの説明では「最初からインスタンスが二つ作られる」前提での議論となっていて, 「===演算子を使って比較した結果true/falseとなる」論法になっています.
aaaaaaaa

2018/04/02 10:17

ご返信ありがとうございます。 間違っておったら申し訳ないですが、つまりシングルトンパターンでは一つしかインスタンスが作れないので、「作成された二つのインスタンスは、」というのが間違っておったということでしょうか。
defghi1977

2018/04/02 10:20

そうそう、シングルトンは「インスタンスが一個しか作られないことを保証する」パターンです.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問