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

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

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

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

Q&A

解決済

2回答

2929閲覧

PHPのゲッターとセッターについて

myksgo

総合スコア21

PHP

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

0グッド

0クリップ

投稿2019/08/23 09:30

編集2019/08/25 05:23

PHP

1//drink.php 2 <?php 3require_once('menu.php'); 4 5class Drink extends Menu { 6 private $type; 7 8 public function __construct($name, $price, $image, $type) { 9 parent::__construct($name, $price, $image); 10 $this->type = $type; 11 } 12 13 public function getType() { 14 return $this->type; 15 } 16 17 public function setType($type) { 18 $this->type = $type; 19 } 20 21} 22 23?>

PHP

1//food.php 2<?php 3require_once('menu.php'); 4 5class Food extends Menu { 6 7 private $spiciness; 8 9 public function __construct($name,$price,$image,$spiciness){ 10 parent::__construct($name,$price,$image); 11 $this->spiciness = $spiciness; 12 } 13 14 public function getSpiciness(){ 15 return $this->spiciness; 16 } 17} 18 19?>

php

1//index.php 2<?php 3require_once('data.php'); 4require_once('menu.php'); 5?> 6 7<!DOCTYPE html> 8<html> 9<head> 10 <meta charset="utf-8"> 11 <title>Café Progate</title> 12 <link rel="stylesheet" type="text/css" href="stylesheet.css"> 13 <link href='https://fonts.googleapis.com/css?family=Pacifico|Lato' rel='stylesheet' type='text/css'> 14</head> 15<body> 16 <div class="menu-wrapper container"> 17 <h1 class="logo">Café Progate</h1> 18 <h3>メニュー<?php echo Menu::getCount() ?></h3> 19 <form method="post" action="confirm.php"> 20 <div class="menu-items"> 21 <?php foreach ($menus as $menu): ?> 22 <div class="menu-item"> 23 <img src="<?php echo $menu->getImage() ?>" class="menu-item-image"> 24 <h3 class="menu-item-name"><?php echo $menu->getName() ?></h3> 25 <?php if ($menu instanceof Drink): ?> 26 <p class="menu-item-type"><?php echo $menu->getType() ?></p> 27 <?php else: ?> 28 <?php for($i=0;$i<$menu->getSpiciness();$i++):?> 29 <img class="icon-spiciness" src="https://s3-ap-northeast-1.amazonaws.com/progate/shared/images/lesson/php/chilli.png"> 30 <?php endfor ?> 31 <?php endif ?> 32 <p class="price">¥<?php echo $menu->getTaxIncludedPrice() ?>(税込)</p> 33 <input type="text" value="0" name="<?php echo $menu->getName() ?>"> 34 <span></span> 35 </div> 36 <?php endforeach ?> 37 </div> 38 <input type="submit" value="注文する"> 39 </form> 40 </div> 41</body> 42</html> 43

php

1//data.php 2<?php 3require_once('drink.php'); 4require_once('food.php'); 5 6$juice = new Drink('JUICE', 600, 'https://s3-ap-northeast-1.amazonaws.com/progate/shared/images/lesson/php/juice.png', 'アイス'); 7$coffee = new Drink('COFFEE', 500, 'https://s3-ap-northeast-1.amazonaws.com/progate/shared/images/lesson/php/coffee.png', 'ホット'); 8$curry = new Food('CURRY', 900, 'https://s3-ap-northeast-1.amazonaws.com/progate/shared/images/lesson/php/curry.png', 3); 9$pasta = new Food('PASTA', 1200, 'https://s3-ap-northeast-1.amazonaws.com/progate/shared/images/lesson/php/pasta.png', 1); 10 11$menus = array($juice, $coffee, $curry, $pasta); 12 13?>

php

1//menu.php 2<?php 3class Menu { 4 protected $name; 5 protected $price; 6 protected $image; 7 private $orderCount = 0; 8 protected static $count = 0; 9 10 public function __construct($name, $price, $image) { 11 $this->name = $name; 12 $this->price = $price; 13 $this->image = $image; 14 self::$count++; 15 } 16 17 public function hello() { 18 echo '私は'.$this->name.'です'; 19 } 20 21 public function getName() { 22 return $this->name; 23 } 24 25 public function getImage() { 26 return $this->image; 27 } 28 29 public function getOrderCount() { 30 return $this->orderCount; 31 } 32 33 public function setOrderCount($orderCount) { 34 $this->orderCount = $orderCount; 35 } 36 37 public function getTaxIncludedPrice() { 38 return floor($this->price * 1.08); 39 } 40 41 public function getTotalPrice() { 42 return $this->getTaxIncludedPrice() * $this->orderCount; 43 } 44 45 public static function getCount() { 46 return self::$count; 47 } 48 49} 50?>

setとgetについてよく分からなくなってしまいましたので、ご教授よろしくお願いいたします。

現在progateでPHPの勉強をしているのですが、上記のコードのgetType()+setType()を指定するパターンと
getSpiciness()のみでsetを指定していないパターンがありました。

どういったときに、setとgetが必要なのか、またgetのみの指定でよいのかご教授お願いいたします。

どうやって説明したら良いのか分からずわかりにくい質問になり申し訳ございません。

追記
「ホット」や「アイス」を指定するときにget+setで定義し、「辛さ」を表すspicinessではgetのみの定義となっております。
例えばフォームなどの入力してもらう項目に対してはsetを使い項目をsetしその項目をgetで取得しているのかなと思っておりましたが、違うようで混乱しております。
よろしくお願いいたします。

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

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

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

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

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

m.ts10806

2019/08/23 11:58

それぞれどのように使われるものなのでしょうか。 定義だけでは何とも言えない部分があります。
myksgo

2019/08/25 05:10

m.ts10806様 ありがとうございます。 修正いたしました。 よろしくお願いいたします。
kasa0

2019/08/26 00:15

追記の理解であっていると思います。 なお、カレーの辛さを選べるお店だと、setが必要になりますね。
myksgo

2019/08/26 00:21

kasa0様 回答ありがとうございます。 作成者側から指定する項目(imageや名前など)はgetのみで項目を取得し、閲覧者側(お客さん)から個数など入力する項目はsetが必要と認識しておいてよろしそうでしょうか? よろしくお願い致します。
m.ts10806

2019/08/26 00:23

初期値から同一インスタンスにおいて「変更があるか、ないか」でしょうね。
myksgo

2019/08/26 00:31

今回こちらの例で行きますと、`ホット`、`アイス`はconstructと同時に設定している項目でその後の項目変更がないものとなりますが、setを指定しているのはなぜなのでしょうか? 辛さの項目は先ほどご教授いただきました、辛さの指定はないのでsetは利用していないというのは理解いたしました。 初歩的な質問で申し訳ございませんが、よろしくお願い致します。
m.ts10806

2019/08/26 00:37

こちらで書くと意図が使用用途(質問への追記修正依頼)にあわなくなってしまうの回答にうつしますね。少々お待ちを。
azuapricot

2019/08/26 00:55

progateってここらへんが不親切ですよねー
azuapricot

2019/08/26 00:58

今回の例だと飲み物も別にgetter / setter なくて良さそうに見えますけど、progateって同じコードにちょこちょこ足して説明していくことが多いので、 今使われてなくても後に使ったり、前に使ってたものをそのまま置いておいたりしていることがあります。 とりあえず変更が必要なときは setterがいるんだなー程度で理解しておいて、章がまだ残っているなら先に進んでみるのも一つの手かもしれません
azuapricot

2019/08/26 01:08

progate = 必ず正解であるわけではないですし、 progateが完璧にできるようになったからといって、自分でPHPのサイトが一からすべて作れるかと言われるとそうではありません。 あくまでも基礎知識を勉強して、今回のように getter / setter がわからない、という疑問が出てきたらteratail などで適宜質問し、理解を深めていけばよいんじゃないかなーと思います。 なのでprogateの演習で正解するぞーを目標にするのではなくて、基礎知識が理解できたかな、身についてきたかな、というのを演習で確認するようにするといいですね⚪
myksgo

2019/08/26 01:25

azuapricot様 ご回答ありがとうございます。 ある程度学習したら一度サイト等を作ってより理解を深めていこうと思います。 とても参考になりました。 ありがとうございました。
guest

回答2

0

インスタンスを作成した後に値を変更しないのであれば、setメソッドは必要ないというだけの話では?

取得する必要もなければ、getメソッドも必要ないですね。

ようは必要か否か。

投稿2019/08/23 09:49

kasa0

総合スコア578

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

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

myksgo

2019/08/25 05:14

kasa0様 ありがとうございます。 私自身ゲッターとセッターについて理解が追いついていないところがあり、もう少し理解力を高める必要がありそうです。 もう少し学習してみます。 ありがとうございました。
guest

0

ベストアンサー

既に回答にある通りではあるのですが、
セッタ、ゲッタを設置する基準はおおよそ「初期値から同一インスタンスにおいて変更があるか、ないか」だと考えます
つまりnewのときに設定するのであればそこから変更があるかどうか。変更を許可する項目なのかどうか。
これは仕様次第となってきます。

今回こちらの例で行きますと、ホットアイスはconstructと同時に設定している項目でその後の項目変更がないものとなりますが、setを指定しているのはなぜなのでしょうか?

それは「(なぜあるのか)分からない」というのが正直なところです。
自販機と考えると買うときに「アイス」「ホット」が決まっていてそこから変化することはありません。
自宅に持って帰って冷やしたり、温めたりすれば「変化」と言えるかもしれませんが、元々購入するときに存在する概念ではなく購入者のさじ加減なので自販機の仕事ではありません。
購入者が「コーヒーのホット」を指定→自販機は指定通りに返す だけですしね。
progateはじめオンライン学習を使ったことがないのでどういう意図があって入れているものかは問い合わせるか解説を確認されたほうが良いかもしれません。

Menuクラスが抽象クラスでもなく、setXXXというメソッドが抽象メソッドでもないので「必ず実装しなければならないもの」ではないです。
必要に応じて実装する(用がなければ実装しない)、でも良いと思います。

投稿2019/08/26 00:46

m.ts10806

総合スコア80850

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

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

myksgo

2019/08/26 01:05

m.t10806様 回答ありがとうございます。 Progateの回答=必ず正解であると思い込みすぎていたのかもしれません。 同一インスタンスにおいて変更がある際にはsetを利用すると認識しておけばわかりやすかったです。 今回の'アイス''ホット'のような変化がないものに対してsetが利用されていたため「?」になっていましたが、今回の場合ですと、特にset指定しなかったとしても問題なく動作するということであれば納得できます。 ご回答いただいた皆様大変わかりやすい回答ありがとうございました。
m.ts10806

2019/08/26 01:16

kasa0さんの回答に補足した形となるのでできればそちらをベストアンサーにしてもらいたかったところではあるのですけど(最終的な判断は質問者さんに委ねられていますのでお任せします) >Progateの回答=必ず正解であると思い込みすぎていたのかもしれません。 あながち「間違いでもないかもしれない」のが難です。 type自体はDrinkのほうにしかない概念で、インスタンス化のときに「変更」が起きています。その後変更が起きるか起きないかでゲッタの必要性があるかないか決まるわけですが、私はあくまで「自販機」を例にしましたが、そうでない場合はtypeが変更になる可能性もあるかもしれない。 メニューからホットコーヒーを注文したが後でアイスコーヒーに変更してくれとなったときにどうなるかとかですね。 新しく作り直したとして客に提供されるのはアイスコーヒーだけなので、typeだけ変更されたものが提供されてもおかしくないと(店側の視点か消費者の視点かにもよりますね) 1点アドバイスすると「type」って「そもそも選択肢が限定されているもの」でもあると思うので、インスタンス化のときに自由に文言が送られるのは良くないと思います。 例えばクラス内で配列で定数を持っておき private $type_config = [1=>"ホット",2=>"アイス"]; private $type; private $type_name; newのときはこの1か2だけを渡す(それ以外はエラーとする)ほうが、作りとしては良いかもしれませんね。 $juice = new Drink('JUICE', 600, '***juice.png', 2); public function __construct($name, $price, $image, $type=1) { if(array_key_exists($type,$this->type_config )){ parent::__construct($name, $price, $image); $this->type = $type; } //exception投げる } public function getType() { return $this->type_config[$this->type]; }
myksgo

2019/08/26 04:05

m.ts10806様 ありがとうございます。 いろいろなやり方があるのですね。 もう少ししっかりと勉強して理解力を深めていければと思います。
m.ts10806

2019/08/26 04:22

1つの要件を満たすのに表現は1つではありません。 直近の例: https://teratail.com/questions/207341 上記は要件や実際の課題・制限事項が不明瞭なため「出力結果にのみ特化した」形で大喜利会場と化してしまった例です(あまり良い例ではないですね) でも結果はみんな同じ。 具体的であればあるほど実装もきちんとしてきます。 今回も「どのような使われ方をするのか」を突き詰めていくと良いかもしれませんね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問