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

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

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

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

Q&A

解決済

1回答

2521閲覧

列挙型(enum)を使ってユーザー入力値の検証

mipopon

総合スコア38

PHP

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

0グッド

0クリップ

投稿2019/08/10 16:11

編集2019/08/11 08:54

ユーザー入力値を検証したい。

現在作ったものがこちら

php

1namespace app\model\data; 2use app\model\enum; 3class paramType extends enum{ 4 const STRING = 0; 5 const NUMERIC = 1; 6 const BOOL = 2; 7}

php

1namespace app\model\data; 2use app\model\data\paramType; 3 4/** 5 * 入力値検証 6 * Class paramModel 7 * @package app\model\data\paramModel 8 */ 9class paramModel { 10 11 const STRING = 0; 12 const NUMERIC = 1; 13 const BOOL = 2; 14 private static $instance; 15 16 private function __construct() { 17 } 18 19 public static function getInstance() { 20 if (!isset(self::$instance)) { 21 self::$instance = new paramModel(); 22 } 23 return self::$instance; 24 } 25 26 public function get(string $key, paramType $mode) { 27 if(!isset($_GET[$key])) { 28 self::_exception('Param ' . $key . 'not defined'); 29 } 30 switch($mode) { 31 case paramType::BOOL: 32 return $this->_bool($_GET[$key]); 33 case paramType::NUMERIC: 34 return $this->_numeric($_GET[$key]); 35 case paramType::STRING: 36 return $this->_string($key); 37 } 38 } 39 40 /** 41 * @param string $key 42 * @param \app\model\data\paramType $mode 43 * @return int|mixed|null 44 * @throws \Exception 45 */ 46 public function post(string $key, paramType $mode) { 47 if(!isset($_POST[$key])) { 48 self::_exception('Param ' . $key . 'not defined'); 49 } 50 switch($mode) { 51 case paramType::BOOL: 52 return $this->_bool($_POST[$key]); 53 case paramType::NUMERIC: 54 return $this->_numeric($_POST[$key]); 55 case paramType::STRING: 56 return $this->_string(POST_[$key]); 57 } 58 } 59 60 private function _bool($val){ 61 if(is_bool($val)) { 62 return $val; 63 } 64 self::_exception('not bool ' . $val); 65 } 66 67 private function _numeric($var) { 68 if(is_numeric($var)) { 69 return (int)$var; 70 } 71 self::_exception('not numeric ' . $var); 72 } 73 74 /** 75 * バイナリの削除 76 * @param $var 77 * @return mixed 78 * @throws \Exception 79 */ 80 private function _string($var) { 81 if(is_array($var)) { 82 foreach($var as $str) { 83 self::_string($str); 84 } 85 } elseif (is_string($var)) { 86 return preg_replace('/[\x00-\x1F\x7F]/ug', '', strtrim($var)); 87 } 88 $this->_exception('param is not correct'); 89 } 90 91 private function _exception($msg){ 92 throw new \Exception($msg); 93 } 94} 95var_dump(paramModel::getInstance()->post('token', paramType::STRING));

こちらのenum クラスを参考にして受け取る $mode をnumber, string, bool に制御したいと思うのですが上手くいきません。enum クラスは記事のものをそのまま使わせていただいています。
https://qiita.com/Hiraku/items/71e385b56dcaa37629fe

エラー

Fatal error: Uncaught TypeError: Argument 2 passed to app\model\data\paramModel::post() must be an instance of app\model\data\paramType, int given,

エラーを見る限り2つ目のパラメータで渡してる paraType::STRING がint なのが問題なのでメソッドのget, post を変えなければいけないと思うのですがどうやって目標の あらかじめ定義した値のいずれかしか取らない パラメータを設定できますか?
また$_REQUEST系統のパラメータの取得はこの方式で問題無いでしょうか。

この様に

php

1 paramModel::getIntance()->post('[キー]', [paramType::])

で上手くいけば取得したいと思っています。
よろしくお願いします。

最終的にどうなったか

php

1/** 2 public static function get(string $key, paramType $mode) { 3 if(!isset($_GET[$key])) { 4 self::_exception('Param ' . $key . 'not defined'); 5 } 6 switch($mode->valueOf()) { 7 case paramType::BOOL: 8 return self::_bool($_GET[$key]); 9 case paramType::NUMERIC: 10 return self::_numeric($_GET[$key]); 11 case paramType::STRING: 12 return self::_string($key); 13 } 14 } 15 16 public static function post(string $key, paramType $mode) { 17 if(!isset($_POST[$key])) { 18 self::_exception('Param ' . $key . ' not defined'); 19 } 20 switch($mode->valueOf()) { 21 case paramType::BOOL: 22 return self::_bool($_POST[$key]); 23 case paramType::NUMERIC: 24 return self::_numeric($_POST[$key]); 25 case paramType::STRING: 26 return self::_string(POST_[$key]); 27 } 28 }

paramTypeは特に変える必要性が無く呼び方を修正すれば大丈夫と教えていただいたので paramType::String() でparamTypeのインスタンス作成
paramModelは直接質問と関係ないけど修正したので一応上げました。
paramTypeのセットされた変数は valueOf() で呼ぶ必要があるみたいです。

php

1$_GET['someVar'] = true; 2var_dump(paramModel::get('someVar',paramType::BOOL()));

こんな感じで使えるようになりました。ありがとうございました。

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

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

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

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

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

guest

回答1

0

ベストアンサー

ちゃんと全体を見たわけではないですけど、使い方が間違っていると思います。

PHPで列挙型(enum)を作る

#使い方

//インスタンス化

$suit = new Suit(Suit::SPADE);
echo $suit; //toString実装済みなので文字列キャスト可能

echo $suit->valueOf(); //生の値を取り出す。intやfloat等の場合に。

// 適当な値を突っ込もうとすると、InvalidArgumentExceptionが発生して停止

//$suit = new Suit('uso800');

//__callStaticを定義してあるのでnewを使わずこんな感じでも書ける(PHP5.3以降)

$suit = Suit::SPADE();

つまり、

php

1paramType::STRING()

として使用する必要があるかと。

投稿2019/08/10 21:41

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

退会済みユーザー

退会済みユーザー

2019/08/10 23:05 編集

PHPには列挙型なんてねぇと、おら、思うぞ。 おめぇが貼ったリンクのは列挙型「みてぇな物」の作り方だ。 7年か8年くれぇ前にt_wadaさんがやったのが確か、最初だったな。 te2ji は本当に何年やっても言葉の定義すらわかってねぇな。
退会済みユーザー

退会済みユーザー

2019/08/10 23:09

リンク先はt_wadaさんがプレゼンしたときに「参照」した元記事ですね。 質問者もそれを参照して実装しようとしているようです。 *質問読めばわかるかと。 ちょっと何が指摘したいのかよく分からないですが。まぁそういうことです。
退会済みユーザー

退会済みユーザー

2019/08/10 23:12

>ちょっと何が指摘したいのかよく分からないですが ははは、すげぇな。本当にわかんねぇんだ。
退会済みユーザー

退会済みユーザー

2019/08/10 23:13

何回もいってんだけど、「言葉の定義はしっかりしろ」 質問者に回答するならな。 te2ji は本当に何年プログラム書いて飯くってんだよ。
退会済みユーザー

退会済みユーザー

2019/08/10 23:19

>リンク先はt_wadaさんがプレゼンしたときに「参照」した元記事ですね。 はぁ? おめぇ、頭でぇじょうぶか? 7年か8年前に2017年の記事を参照したっていってんのか? te2ji おめぇ、ほんとうのアホだろ。 「ビートルズはミスチルのパクリだ」って言ってる奴みてぇだw
退会済みユーザー

退会済みユーザー

2019/08/10 23:19

te2ji は、頭がやばすぎんぞ、マジで。
退会済みユーザー

退会済みユーザー

2019/08/10 23:42

ぐぐったんだけんど、見つからねぇ。 >リンク先記事の履歴ぐらい見ろよ^^; 2019年の7年か8年前って何年になると思ってるんだ? おめぇ。 2013年だと微妙なラインだけんど、 あんときの和田さんはリンクなんか紹介してなかったはずだ。
退会済みユーザー

退会済みユーザー

2019/08/10 23:49

ずっと枝葉。本質を俯瞰で見ようよ。。。 wadaさんの話は、今回はどーでも良い。 いい記事なんでリンク張ったけどw
退会済みユーザー

退会済みユーザー

2019/08/11 00:04

>本質を俯瞰で見ようよ なら、もう一回言うぞ。 PHPには列挙型なんて、ねぇ。 それを、ちゃんと、質問者に、教えろ。 おめぇらが話してるのは列挙型とは別の物だ。
退会済みユーザー

退会済みユーザー

2019/08/11 00:09

質問のリンク先読もうよ^^; 別モンだってちゃんと書いてるよ。。。
退会済みユーザー

退会済みユーザー

2019/08/11 00:12

おめぇは、教えてねぇな。
退会済みユーザー

退会済みユーザー

2019/08/11 00:14

ずっと屁理屈だな。 そろそろ付き合いきれんわ。。。
退会済みユーザー

退会済みユーザー

2019/08/11 00:22 編集

そりゃ、こっちのセリフだぞ。 おめぇは論理が破綻してっから話が全く前にすすまねぇ。 おらが「7、8年くれぇ前ぇに見た」って言ってんのに、「それはこの記事を参照したものだ」って2013年の記事の事を言い出すし、 向こうは向こうで延々と同じこと言わせるし https://teratail.com/questions/205407 ----------------------------------------- 何回おんなじこといわせんだ? 質問と関係ない話すんな。 >だったら各 DB のワイルドカードでエスケープが必要な文字羅列してみ。 何回言ったら分かるんだ? 関係ない話すんなって。 >$statement = 'SELECT * FROM t_sale_den WHERE holiday=false and business_day like $hani%'; >$haniの変数には日付が入っており、他の個所で下記のようにしたら正常に表示されます。 >$sql = "SELECT * FROM t_sale_den WHERE holiday=false and business_day like '$hani%'"; >上記コードのシングルクォートをダブルクォートにするとエラーが出る こういう話で、「ワイルドカードがどうした」とか「LIKEがどうした」とか、関係あるわけねーだろ。 本当におめぇは論理性も問題解決能力もゼロだな。te2ji >$haniの変数には日付が入っており、他の個所で下記のようにしたら正常に表示されます。 >(〇年〇月が取得され一覧で表示されます。) >LIKE はチョットめんどいですよ >だったら各 DB のワイルドカードでエスケープが必要な文字羅列してみ。 te2ji の世界じゃ、日付に%とかアンダースコアとか使ってんのか。 おもしれぇ世界だなw ------------------------------------------------- te2ji はさ、口先だけでなんとか言い逃れしようとすんの、いい加減にやめろ。
退会済みユーザー

退会済みユーザー

2019/08/11 00:32

ずっと枝葉。本質を俯瞰で見ようよ。。。 wadaさんの話は、今回はどーでも良い。 どうしても気になるならソース提示してくれ。 まぁ提示されても意味ないけど。。。
mipopon

2019/08/11 08:44

すみません。まだこのサイトに登録して新しいものでコメント機能を見逃していました。@te2ji さんが言う通りwadaさんのプレゼンの資料を読んで参考にさせて頂いています。 今回は入力値検証を例にクラスインスタンス作成時の引数を制限して生成できるクラスを制限するという書き方に対する質問でした。最終的に自分の var_dump が間違っていたのでそもそもそこから問題でした。 var_dump(paramModel::get('someVar',paramType::STRING())); そもそもparamModelをインスタンス化させる必要が無い気がしたので書き換えてみました。 goku59さんは身内なのかガチなのか判別がつかないので放置ですかね? te2jiさん 返信ありがとうございました。
退会済みユーザー

退会済みユーザー

2019/08/11 08:47

>goku59さんは身内なのかガチなのか判別がつかないので放置ですかね? いや、おめぇの力量だと、まだ何言ってるか全く理解出来ねぇだろうから放置でいいぞ。 >@te2ji さんが言う通りwadaさんのプレゼンの資料を読んで参考にさせて頂いています。 全然話の内容わかってねぇみてぇだからな。 あと、PHPにはEnum(列挙型)なんて、ねぇぞ。よく覚えておいた方がいいと、おら、思うぞ。 この質問は、タイトルからしておかしいからな。 だから、te2ji 程度の奴にはちょうど良かったんだと、おら、思ってる。
退会済みユーザー

退会済みユーザー

2019/08/11 08:50

>wadaさんの話は、今回はどーでも良い。 >@te2ji さんが言う通りwadaさんのプレゼンの資料を読んで参考にさせて頂いています。 もぅ、おめぇらの会話、わっけわかんねぇぞw 知能レベルが似たもの同士なんだろうな。スカウターで見たら数字いっしょだろ、きっと。
mipopon

2019/08/11 08:53

そうですね 実際に列挙型がどのようなものか 触った事が無いので。。
退会済みユーザー

退会済みユーザー

2019/08/11 08:57

そうだと思ってっけどよ、別物だからな。 PHPに慣れてからでいいけど、C/C++をちょっとだけやってみろ。 随分勉強になんぞ。
退会済みユーザー

退会済みユーザー

2019/08/11 08:59

5年後くらいに、Zend extensionの何かのコードあたりを見てみるとPHPがどうやって動いているのかわかっていいかもな。
mipopon

2019/08/11 09:04

5年後は遠いですね。。。 でもベースとなるc言語を見るのは勉強になりそうなのでみてみます。 アドバイスありがとうございます、
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問