[PHP]フォームで送信された値から、それに応じてclass内のデータをブラウザへ表示させたい。
解決済
回答 2
投稿
- 評価
- クリップ 0
- VIEW 1,569
前提・実現したいこと
プログラミングを3日ほどしか勉強していない初心者です。おかしな質問をしていたらすみません。
classのプロパティに$name , $size , $priceを作り、
りんご、オレンジ、メロンのインスタンスを作りました。
htmlでは、
[りんご,オレンジ,メロン]の[大きさ,値段]
といった2つのドロップダウンリストを作り、
選ばれた2つの要素から、例えば、「りんごの値段は158円です」のような出力をしたいです。
発生している問題
$nameや$sizeなどの情報をそのまま文字列として出力する方法がわかりません。
該当のソースコード
<?php
class Fruit{
public $name;
public $size;
public $price;
public function __construct($name, $size, $price){
$this->name = $name;
$this->size = $size;
$this->price = $price;
}
public function fName(){
echo "$this->name";
}
public function fSize(){
echo "$this->size";
}
public function fPrice(){
echo "$this->price";
}
}
$apple = new Fruit ("りんご","中","158");
$orange = new Fruit ("オレンジ","中","128");
$melon = new Fruit ("メロン","大","1280");
<!DOCTYPE html>
<html lang="ja">
<body>
<form action="" method="post">
<p>果物:
<select name="kudamono">
<option value="apple">りんご</option>
<option value="orange">オレンジ</option>
<option value="melon">メロン</option>
</select>
の
<select name="joho">
<option value="size">大きさ</option>
<option value="price">値段</option>
</select>
</p>
<p><input type="submit" value="送信"></p>
</form>
<br>
<?php
$kudamono = $_POST["kudamono"];
$joho = $_POST["joho"];
//ここに$_POST["kudamono"]や$kudamono等を使ってclassFruit内の$nameを呼び出す(?);
echo "の";
if($joho == size){
echo "大きさは";
}else{
echo "値段は";
} ;
//ここに$_POST["joho"]や$joho等を使ってclassFruit内の$sizeや$priceを呼び出す(?);
classの使い方を学び、事前にhtmlのformタグも勉強したところだったので、この2つを使って何か作れないかと考えて作ってみた物なので、一般的にこのような使い方はしないのかも知れませんが、後学のために教えて頂きたいです。
また、本質問のような処理をする場合に適した方法などありましたら、後ほど勉強させて頂きたいので簡単にご紹介して頂ければ幸いです。
ifを使用している箇所も、ifならとりあえず思ったように表示できるのでifで書いておりますが、
項目数が多くなった場合現実的では無いのかも・・・という事と、
もっと適した書き方があるのではないかと思っております。よろしければそちらも併せてご回答頂けると嬉しいです。
よろしくお願いします。
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
+4
以下のような感じでしょうか
<?php
class Fruit{
public $name;
public $size;
public $price;
public function __construct($name, $size, $price){
$this->name = $name;
$this->size = $size;
$this->price = $price;
}
public function fName(){
echo "$this->name";
}
public function fSize(){
echo "$this->size";
}
public function fPrice(){
echo "$this->price";
}
}
$apple = new Fruit ("りんご","中","158");
$orange = new Fruit ("オレンジ","中","128");
$melon = new Fruit ("メロン","大","1280");
?>
<!DOCTYPE html>
<html lang="ja">
<body>
<form action="" method="post">
<p>果物:
<select name="kudamono">
<option value="apple">りんご</option>
<option value="orange">オレンジ</option>
<option value="melon">メロン</option>
</select>
の
<select name="joho">
<option value="size">大きさ</option>
<option value="price">値段</option>
</select>
</p>
<p><input type="submit" value="送信"></p>
</form>
<br>
<?php
if($_SERVER["REQUEST_METHOD"] == "POST"){
$kudamono = $_POST["kudamono"];
$joho = $_POST["joho"];
echo $$kudamono->fName();
if($joho == 'size'){
echo "大きさは";
echo $$kudamono->fSize();
}else{
echo "値段は";
echo $$kudamono->fPrice();
}
}
- $kudamonoがappleの場合、$$kudamonoは$appleなので、$$kudamon->fName()で$apple->fName()ということになります。
- 関数名はfNameよりgetNameとかのほうが普通だと思います。
- $nameや$sizeなどはpublicではなく、privateにしたほうがいいかもしれません。
$apple->name = 'hoge';
で書き換えてほしくなければですが。 - GET時には$_POSTを参照するのはよくないので、
if($_SERVER["REQUEST_METHOD"] == "POST"){}
で囲いました。
(おまけ)
自分なりにコードをきれいにしてみましたので参考にしてください。フルーツを$fruits配列に持たせて、optionもそれをもとに生成するようにしています。なので$fruits配列だけにフルーツを追加すれば動きます。定義を一箇所にするとメンテしやすく読みやすいコードになると思います。また、メッセージを作る処理もクラスの関数にすると再利用もしやすくていいと思いました。
<?php
class Fruit{
private $name;
private $size;
private $price;
public function __construct($name, $size, $price){
$this->name = $name;
$this->size = $size;
$this->price = $price;
}
public function getName(){
return $this->name;
}
public function getSize(){
return $this->size;
}
public function getPrice(){
return $this->price;
}
public function getMessage($joho) {
echo $this->getName();
if($joho == 'size'){
echo "大きさは";
echo $this->getSize();
}else{
echo "値段は";
echo $this->getPrice();
echo "円";
}
}
}
$fruits = array(
'apple' => new Fruit ("りんご","中","158"),
'orange' => new Fruit ("オレンジ","中","128"),
'melon' => new Fruit ("メロン","大","1280"),
'grape' => new Fruit ("グレープ","大","580"),
);
?>
<!DOCTYPE html>
<html lang="ja">
<body>
<form action="" method="post">
<p>果物:
<select name="kudamono">
<?php
foreach($fruits as $key => $fruit) {
echo "<option value='{$key}'>".$fruit->getName()."</option>\n";
}
?>
</select>
の
<select name="joho">
<option value="size">大きさ</option>
<option value="price">値段</option>
</select>
</p>
<p><input type="submit" value="送信"></p>
</form>
<br>
<?php
if($_SERVER["REQUEST_METHOD"] == "POST"){
$kudamono = $_POST["kudamono"];
$joho = $_POST["joho"];
echo $fruits[$kudamono]->getMessage($joho);
}
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+3
以下のように行うのはどうでしょうか?
リクエストのメソッド名がPOSTのときのみ動作するようにしたいので、$_SERVER["REQUEST_METHOD"]を使っています。
<?php
class Fruit
{
public $name;
public $size;
public $price;
public function __construct($name, $size, $price)
{
$this->name = $name;
$this->size = $size;
$this->price = $price;
}
public function fName()
{
return "$this->name";
}
public function fSize()
{
return "$this->size";
}
public function fPrice()
{
return "$this->price";
}
}
?>
<!DOCTYPE html>
<html lang="ja">
<body>
<form action="" method="post">
<label>果物:
<select name="kudamono">
<option value="apple">りんご</option>
<option value="orange">オレンジ</option>
<option value="melon">メロン</option>
</select>
の
<select name="joho">
<option value="size">大きさ</option>
<option value="price">値段</option>
</select>
</label>
<p><input type="submit" value="送信"></p>
</form>
<?php
if ($_SERVER["REQUEST_METHOD"] === "POST") {//リクエストのメソッド名がPOSTのとき。
if (!empty($_POST["joho"]) && !empty($_POST["kudamono"])) {//情報が空でなければ。
$joho = $_POST["joho"];
$kudamono = $_POST["kudamono"];
$message = "";
if ($kudamono == "apple") {
$apple = new Fruit("りんご", "中", "158");
$message = $apple->fName() . "の";
if ($joho == "size") {
$message .= "大きさは" . $apple->fSize();
} elseif ($joho == "price") {
$message .= "値段は" . $apple->fPrice();
}
} elseif ($kudamono == "orange") {
$orange = new Fruit ("オレンジ", "中", "128");
$message = $orange->fName() . "の";
if ($joho == "size") {
$message .= "大きさは" . $orange->fSize();
} elseif ($joho == "price") {
$message .= "値段は" . $orange->fPrice();
}
} elseif ($kudamono == "melon") {
$melon = new Fruit ("メロン", "大", "1280");
$message = $melon->fName() . "の";
if ($joho == "size") {
$message .= "大きさは" . $melon->fSize();
} elseif ($joho == "price") {
$message .= "値段は" . $melon->fPrice();
}
}
echo $message;
}
}
?>
</body>
</html>
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.09%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2017/01/11 18:18
fNameはgetNameという書き方が一般的なのですね。こういう何とでも設定できてしまう所で変な癖が付きそうなので、このような指摘は大変ありがたいです。
$$kudamonoという書き方もできるのではと思って試してはいたのですが、他の部分でおかしな書き方をしていた様で、その辺りが解決できたので良かったです。
ドロップダウンリストも自動で組み込めないかとも思っていたので、こちらも参考にさせて頂きます。
また初歩的な質問で申し訳ないのですが、$name等に格納されている情報をprivateにするのは、クロスサイトスクリプティング(?)のような悪意のあるものから守るためという理解でよろしいのでしょうか。
2017/01/11 18:50 編集
クロスサイトスクリプティングとかではなく、プログラミングのテクニックの1つ(クラスによるメンバ変数の隠蔽)です。直接$nameを変更できてしまうと影響範囲が広くなってしまうので、必要ならgetName()と同じようにsetName()を実装するという考え方です。まぁ、PHPではそこまでやらないかもですが、javaとかだと必要最低限だけをpublicにするのがよいとされています。
ちなみにpublicにするのであれば、getName()も実はいらなくて、単に$apple->nameで値が取得できます。※「クラス 隠蔽」とかで検索すれば関連記事はたくさんありますよ
プログラミングは色々書いたり読んだりする経験で向上していくものなので、一つずつ理解していけばいいと思います! がんばってください。
2017/01/11 22:57
疑問点であろう所を的確に補足されるご回答に恐れ入ります。
なるほど、setName()という方法もあるのですね。大体想像がつくので引き続き掘り下げて勉強したいと思います。
がんばります!ありがとうございました。