singletonの使い方とは?

このQ&Aのポイント
  • singletonの使い方について相談です。
  • singletonはオブジェクトのインスタンスを一つに制限するため、負荷軽減に役立ちます。
  • ただし、空欄チェックなどの機能を持つ場合は、newでインスタンスを生成する必要があります。
回答を見る
  • ベストアンサー

singletonの使い方

はじめまして。 singleton(GoF)で少し疑問に思ったところがありましたので、 アドバイスをいただけたらと思い質問させていただきます。 たとえば以下のようなプログラムですが、 ==form.html== <html> <body> <form action="./Main.php" method="post"> name:<br /> <input type="text" size="20" name="name" /><br /> text:<br /> <textarea rows="8" cols="40" name="text"></textarea><br /> <br /> <input type="submit" value="submit!" /> <input type="reset" value="reset!" /> </form> </body> </html> ==Main.php== <?php require_once "Data.php"; require_once "NullCheck.php"; $data =& Data::getInstance(); $data->setName($_POST["name"]); $data->setText($_POST["text"]); $nc = new NullCheck($data); $result = $nc->check(); if(!$result == ""){ echo $result; }else{ echo "ok"; } ?> ==Data.php== <?php class Data{ var $name; var $text; function &getInstance(){ static $instance; if(!isset($instance)){ $instance = new Data(); } return $instance; } function setName($name){ $this->name = $name; } function setText($text){ $this->text = $text; } function getName(){ return $this->name; } function getText(){ return $this->text; } } ?> ==NullCheck.php== <?php class NullCheck{ var $data; var $err = ""; function NullCheck($data){ $this->data = $data; } function check(){ if($this->data->getName() == ""){ $err .= "nameが空欄です。<br>"; } if($this->data->getText() == ""){ $err .= "textが空欄です。<br>"; } return $err; } } ?> 上記を作る際、 submitを押すたびにオブジェクトが作られるのは無駄だと思い、 singletonを使いました。 しかし、空欄チェックのときはnewでインスタンスを生成しています。 やはりこの場合もsingletonを使用したほうがいいのでしょうか? 仮にもっと複雑な問い合わせフォームを作成し、 利用者が多くなった場合、 いろいろとインスタンス化(空欄チェックや文字列チェック等)すると オブジェクトがたくさんできてしまい負荷がかかるで、 できる限り不必要なインスタンス化は避けたいと思っています。 長々と書いてしまい申し訳ありませんが、 なにとぞよろしくお願いします。

  • PHP
  • 回答数1
  • ありがとう数1

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

ソースを見る限り、 >submitを押すたびにオブジェクトが作られるのは無駄 これを解決する手法にはならないと思います。 PHPの特性上、オブジェクトの数はsubmitが押された数だけ生成されます。 singletonを使うのはPHP上でマルチスレッドを実現する時や、一度のプロセスで複数回インスタンスをするようなクラスに適用されるんじゃないかな?と思います。

RedPiyoyo
質問者

お礼

早速のアドバイスありがとうございます。 アドバイスの中で、少し気になった部分があるのですが、 >オブジェクトの数はsubmitが押された数だけ生成されます。 submitが押された数だけ生成されるのは理解できたのですが、 同じ人がある程度処理を行い、 ブラウザ等の「戻る」ボタンで入力画面に戻ってsubmitを押した場合、 オブジェクトは新しいものとして生成されるのでしょうか?

関連するQ&A

  • 外部テファイルを使って未入力に対しての背景色を変える

    これが外部ファイル(CheckUtil.js)です。 //入力データ(テキストデータやテキストエリア)の必須チェック function requiredCheck(strVal,strErr) { var total = strVal.length; var flag = true; for (var i=0; i<total; i++) { if((strVal.type == 'text')||(strVal.type == 'password')){ strVal.style.backgroundColor = ''; if (strVal.value == "") { strVal.className = 'error_field'; flag = false; } if (strVal.value) { strVal.className = ''; } } } if (! flag)return strErr + "は必須入力です \r"; }else{ return ""; } } このファイルはPHPファイルです。外部ファイルで分けないでやったときは動いたのでそのままにしています。 <script language="JavaScript" src="CheckUtil.js" type="text/javascript" charset="EUC-JP"></script> <style //背景色は#FF8080に設定 type="text/css"><!--.error_field{background-color:#FF8080;}--></style> <script type="text/javascript"> <!-- function chk(part){ strErr = ""; strErr += requiredCheck(part.name.value,"なまえ"); strErr += requiredCheck(part.pass.value,"パス"); if(strErr == ""){ return true; }else{ window.alert(strErr); return false; } } //--> </script> </head> <body> <!-- {/literal} --> <br> <form action="<?php echo $PHP_SELF; ?>" method="POST" name="fm" onsubmit="return chk(this)"> <input type="text" name="name" size="40"> <br> <input type="password" name="pass" size="40"> <br> <br> <input type="submit" name="submit" value="ボタン"> <br> </form> <br> <br> <center></center>

  • C++ シングルトン マルチスレッド

    標準C++でシングルトンを実装したいのですが。 class Singleton{ public: static Singleton* getInstance(){ if (_instance == NULL){ //スレッドAがこの時点で、スレッドBがNULLチェックすると破綻する _instance = new Singleton(); } return _instance; } private: Singleton(); static Singleton* _instance; }; マルチスレッドになると上記のパターンで破綻するといわれどうしたものかと考えております。 static Singleton* _instance = new Singleton(); と出来れば解決なのですが 「static const int データメンバ以外をクラス内で初期化することはできません」 とのことでそれもできず。 どのようにすればよいでしょうか。

  • thisとvar ?

    javascript初心者です。 コンストラクタ(プロトタイプ)とクロージャを学んでいますが、 コンストラクタ(プロトタイプ)では、関数内にthisで変数宣言、クロージャはvarで宣言しています。 この違いの理由は何でしょうか?漠然とした質問ですみません。 thisとvarでの変数宣言の違いなど教えていただけないでしょうか? コンストラクタ-------------------- function Person(n){ this.name = n; } Person.prototype.city = 'Tokyo'; Person.prototype.moveTo = function(c){ document.write(this.name + ': Moving to... ' + c + '<br>'); Person.prototype.city = c; } クロージャ------------------- function Person(n, a){ var name = n; var age = a; return { getName: function() { return name; }, setAge: function(i){ if( 0<= i ){ age = i; } }, getAge: function(){ return age; } } }

  • 外部ファイルを読み込んで表示

    これが外部ファイル(CheckUtil.js)です。 //入力データ(テキストデータやテキストエリア)の必須チェック function requiredCheck(strVal,strErr) { if(strVal=="" || strVal==undefined){ return strErr + "は必須入力です \r"; }else{ return ""; } } これを読み込んで表示させたいです。 <HTML> <HEAD> <META HTTP-EQUIV="Content-type" CONTENT="text/html; charset=sjis"> <TITLE>ファイル操作</TITLE> <!-- {literal} --> <script language="JavaScript" src="CheckUtil.js"></script> <script language="JavaScript"> </HEAD> <BODY> <!-- function chk(part){ strErr = ""; strErr+ = requiredCheck(part.value,"なまえ"); if(strErr == ""){ return true; }else{ window.alert(strErr); return false; } } //--> </script> <!-- {/literal} --> <BR> <FORM ACTION="<?php echo $PHP_SELF; ?>" METHOD="POST" name="fm" onsubmit="return chk()> <INPUT TYPE="text" NAME="name" SIZE="40"><BR> <INPUT TYPE="text" NAME="comment" SIZE="40"><BR><BR> <INPUT TYPE="submit" NAME="submit" VALUE="ボタン" onsubmit="return chk()"><BR> </FORM> <BR><BR> </CENTER> </BODY> </HTML>

  • チェックボックスが選択されたらファイルを読み込む

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script> <script type="text/javascript"> function getChecked(name) { var AllVals = $('input[name="' + name + '"]:checked').map(function() { return this.value; }); AllVals = $.makeArray(AllVals).join('|'); return AllVals; } function getContents(){ var colorId = getChecked('color_id'); var categoryId = getChecked('category_id'); var serviceId = getChecked('service_id'); var http = $.get ( "http://localhost/eigazuki/results/title:/time:0~300/country_id:" + categoryId + "/genre_id:" + serviceId, null, function ( data ) { $("#serviceListSection").html(data); } ) }; $(function(){ $('input[name]:checkbox').change(function(){getContents();}); }); </script> </head> <body> <input type="checkbox" name="color_id" value="1" />赤 <input type="checkbox" name="color_id" value="2" />黒 <br> <input type="checkbox" name="category_id" value="1">男物 <input type="checkbox" name="category_id" value="2">女物 <br> <input type="checkbox" name="service_id" value="1">季節 <input type="checkbox" name="service_id" value="2">お祝い </body> </html> <section id="serviceListSection"></section> というコードを書き、チェックボックスがチェックされるたびに、 http://localhost/eigazuki/results/title:/time:0~300/country_id:" + categoryId + "/genre_id:" + serviceId の外部ファイルを読み込みたいのですが、全く上手くいきませんなにがダメなのでしょうか? よろしくお願いします!

  • mb_regex_encodingでエンコードエラーが出ます

    お世話になります。 フォームから投稿された時に文字をチェックする物を作成しております ---------------- <?php function allHiragana($form_name, $err_name) { mb_regex_encoding("Shift_JIS"); if(!mbereg('^[あ-んが-ぼぁ-ょゎっー]+$', $_POST[$form_name])) { return $err_name. 'はひらがなで入力してください<br />'; } } ?> ------------------------------------------------ このようなソースなのですが 三行目にこのようなエラーが出ます Fatal error: Call to undefined function mb_regex_encoding() in グーグル先生に質問してみたのですがイマイチ欲しい情報を得られなかった為質問させていただきます。 よろしくお願いします。

    • ベストアンサー
    • PHP
  • PHP T_STRINGエラー?

    新しくPHPのサイトを作成しようとしたんですが、 syntax error, unexpected '{', expecting T_STRING in と表示されてどうにも使用がありません。 どこが原因でエラーが出てるのでしょうか? エラー行は7行と表示されていますが、いまいちわかりません スクリプトは以下の記述の通りです <?php require './Request.php'; require './Cookie.php'; final class SystemMain extends { private static $instance; private $modeName; public static function getInstance() { if (self::$instance === null) { self::$instance = new SytemMain(); } return self::$instance; } public function setMode() { if (file_exists('./maintenance')) { $this->modeName = 'Maintenance'; } else { $str = Request::both('mode'); if (!$str) { $this->modeName = 'Top'; } else if (file_exists('./script/mode/' . $str . '.php')) { $this->modeName = $str; } else { $this->modeName = 'NotFound'; } } require_once './script/mode/' . $this->modeName . '.php'; } public function getMode() { return $this->modeName; } } ?> Request.php <? class Request extends { public static function get($str) { return isset($_GET[$str]) ? $_GET[$str] : null; } public static function post($str) { return isset($_POST[$str]) ? $_POST[$str] : null; } public static function both($str) { $post = self::post($str); return $post ? $post : self::get($str); } } ?> Cookie.php <? class Cookie extends { public static function set($name, $value, $expire = 0) { return setcookie($name, $value, $expire); } public static function get($str) { return isset($_COOKIE[$str]) ? $_COOKIE[$str] : null; } public static function clear($str) { $_COOKIE[$str] = ""; return setcookie($str, ""); } } ?>

    • ベストアンサー
    • PHP
  • <?php

    <?php if (isset($_POST['reg']) && isset($_POST['reg'])) { $ErrFlg = false; // 氏名欄をチェック $first_name = $_REQUEST['first_name']; $last_name = $_REQUEST['last_name']; if (!trim($first_name) || trim($last_name) == '') { $_POST['err_name_req'] = '氏名が入力されておりません。<br />'; $error = TRUE; } else { unset($_POST['err_name_req']); } // 生年月日欄をチェック $b_year = $_REQUEST['b_year']; $b_month = $_REQUEST['b_month']; $b_day = $_REQUEST['b_day']; if (!trim($b_year) || trim($b_month) || trim($b_day) == '') { $_POST['err_birthday_req'] = '生年月日が入力されておりません。<br />'; $error = TRUE; } else { unset($_POST['err_birthday_req']); } if (checkdate($b_month, $b_day, $b_year) === false) { $_POST['err_birth_ereg'] = '生年月日が正しくありません。<br />'; $error = TRUE; } else { unset($_POST['err_birth_ereg']); } } ?> <html> <body> <form action="<?php $_SERVER["PHP_SELF"]; ?>" method="POST"> 氏名<br /> <?php print $_POST['err_name_req']; ?><br /> <input type="text" name="first_name" value="<?php print $first_name; ?>" /><input type="text" name="last_name" value="<?php print $last_name; ?>" /><br /> 生年月日<br /> <?php print $_POST['err_birth_req'].$_POST['err_birth_ereg']; ?><br /> <input type="text" name="b_year" value="<?php print $b_year; ?>" size="5" />年 <input type="text" name="b_month" value="<?php print $b_month; ?>" size="2" />月 <input type="text" name="b_day" value="<?php print $b_day; ?>" size="2" />日 <br /> <input type="submit" name="reg" value="登録" /> </form> </body> </html> としています。 登録ボタンを押した際に入力チェックされることがなければデータベースに登録したいのですが、どこに記述してよいのか困っています。 また、どのように記述したらよろしいでしょうか? イメージとしては登録ボタンを押したら、「登録しました。」というコメントだけが表示されるようにしたいのですが・・・ javascriptの使用は考えておりませんので、できればPHPでお願いいたします。 もしお分かりの方がいらっしゃいましたらご教授いただけないでしょうか? また上記の内容でおかしいところがありましたらご指摘いただけないでしょうか?

    • ベストアンサー
    • PHP
  • POSTすると配列の数がおかしくなる

    matとquaとhowtoをそれぞれ4つPOSTしているのですが、POSTされたデータを受け取るとmat4つ、qua5つ、howto5つと数がおかしくなります。 なぜかわかりません。とくにインクリメントしていないのに増えます。 教えて下さい。 <script type="text/javascript"> function myAdd(obj){ var max=15; var c=count("mat"); if(c>=max) return false; var oTR=document.createElement("tr"); var names=["mat","qua"]; for(var i in names){ var oTD = document.createElement("td"); var oTag = document.createElement("input"); oTag.setAttribute("type", "text"); oTag.setAttribute("name", names[i] + (c+1).toString()); oTD.appendChild(oTag); oTR.appendChild(oTD); } document.getElementById("t0").getElementsByTagName("tbody")[0].appendChild(oTR); if(c>=max-1) obj.disabled=true; } function count(name){ var tags=document.getElementsByTagName("input"); var ta=document.getElementsByTagName("textarea"); var c=0; var reg=RegExp("^"+name+"[0-9]+$"); if(tags){ for(var i=0;i<tags.length;i++){ if(tags[i].name.match(reg)){ c++; } } } if(ta){ for(var i=0;i<ta.length;i++){ if(ta[i].name.match(reg)){ c++; } } } return c; } function myTextAreaAdd(obj){ var max=15; var c=count("howto"); if(c>=max) return false; var oTag = document.createElement("textarea"); oTag.setAttribute("name", "howto" + tag_num++); var oDiv = document.getElementById("area"); oDiv.appendChild(oTag); if(c>=max-1) obj.disabled=true; } </script> </head> <body> <form method="post" enctype="multipart/form-data" action="check.php"> <textarea name="explain"></textarea> <table id="t0" border> <tbody> <tr> <td><input type="text" name="mat1" /></td> <td><input type="text" name="qua1" /></td> </tr> <tr> <td><input type="text" name="mat2" /></td> <td><input type="text" name="qua2" /></td> </tr> <tr> <td><input type="text" name="mat3" /></td> <td><input type="text" name="qua3" /></td> </tr> <tr> <td><input type="text" name="mat4" /></td> <td><input type="text" name="qua4" /></td> </tr> </tbody> </table> <input type="button" value="追加する" onClick="myAdd(this)"> <br /> <span id="area"> <textarea name="howto1"></textarea> <textarea name="howto2"></textarea> <textarea name="howto3"></textarea> <textarea name="howto4"></textarea> </span><br /> <input type="button" value="追加する" onClick="myTextAreaAdd(this)"> <input type="submit" value="送る"> </form>

  • フォームに入力した値の制御について

    フォームに入力した値の制御について いろいろと調べてみたのですが、 どうすれば良いか分からないので、 質問をさせて頂きました。 【概要】 フォームの[text]と[textarea]に入力をしてもらいたい 入力値のサンプルを表示されるようにしました。 カーソルを[text]と[textarea]に入れると、 入力値のサンプルの表示が消えて入力出来るようにしました。 【やりたい事】 [text]と[textarea]に入力をしてもらった値を、 最終的にtextareaに出力させるようになっています。 何も入力せず出力をさせると、サンプル値は出力されてしまいます。 [text]と[textarea]に入力をした値のみ出力させることは可能でしょうか。 ご教授頂ければと思います。 よろしくお願いいたします。 【ソース】 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN Frameset" "http://www.w3.org/TR/html4/frameset.dtd"> <html> <head> <script type="text/javascript"> <!--ログ生成スクリプトを取得--> function textoutput(formObj) { <!--text01を取得--> var text01 = formObj.elements["text01"].value; <!--text02を取得--> var text02 = formObj.elements["text02"].value; <!--textarea01を取得--> var textarea01 = formObj.elements["textarea01"].value; <!--textarea02を取得--> var textarea02 = formObj.elements["textarea02"].value; <!--出力データを作成--> var text = ''; <!--text3データを作成--> if(text01!==""){ text += '質問1:' + '\n'+ text01 + '\n'; } <!--text2データを作成--> if(text02!==""){ text += '質問2:' + '\n'+ text02 + '\n'; } <!--textarea01データを作成--> if(textarea01!==""){ text += '質問3:' + '\n'+ textarea01 + '\n'; } <!--textarea02データを作成--> if(textarea02!==""){ text += '質問4:' + '\n'+ textarea02 + '\n'; } <!--出力データを作成--> formObj.elements["output"].value=text; } </script> </head> <body> <form name="form01"> <strong>・諮問1:</strong><br> <input type="text" name="text01" value="1入力してください" id="p1" size="30" class="disabled" onfocus="if (this.value == defaultValue) this.value = '';" onblur="if (!this.value) this.value = defaultValue;"><br> <strong>・諮問2:</strong><br> <input type="text" name="text02" value="2入力してください" id="p2" size="30" class="disabled" onfocus="if (this.value == defaultValue) this.value = '';" onblur="if (!this.value) this.value = defaultValue;"><br> <strong>・諮問3:</strong><br> <textarea name="textarea01" id="textarea01" cols="60" rows="5" onfocus="if(this.value == this.defaultValue) this.value=''" onblur="if(this.value == '') this.value=this.defaultValue"> 3入力してください </textarea><br> <strong>・諮問4:</strong><br> <textarea name="textarea02" id="textarea02" cols="60" rows="5" onfocus="if(this.value == this.defaultValue) this.value=''" onblur="if(this.value == '') this.value=this.defaultValue"> 4入力してください </textarea><br> <strong>・出力結果:</strong><br> <input type="button" value="ログ出力" onClick="textoutput(this.form);">&nbsp;<br> <textarea cols=60 rows=20 name="output" ></textarea> </form> </body> </html>

専門家に質問してみよう