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

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

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

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

Q&A

解決済

3回答

2130閲覧

PHPでの電卓再現(表示部分の処理)

ruka02141

総合スコア15

PHP

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

0グッド

0クリップ

投稿2019/04/18 01:35

編集2019/04/18 01:43

前提・実現したいこと

phpのみで動く電卓を作成しています。
機能としては、一般的な電卓の計算機能と、演算子を入力したら、その演算子を表示させる(例:5+10=15の時なら、+を入力したら次の10の1を入力するまで、表示したままにする。)

ソースコード

<?php //変数設定 $f_num = $_POST['f_num']; $s_num = $_POST['s_num']; $input_num = $_POST['input_num']; $ope = $_POST['ope']; $button = $_POST['button']; $s_button = $_POST['s_button']; if (isNumBtn($button) || empty($button)) { if (isOpeBtn($s_button)) { $s_num = $f_num; if (preg_match('/./', $button)) { $f_num = '0.'; } else { $f_num = $button; } } else { $f_num = $f_num . $button; } $input_num = $f_num; } else { switch ($button) { case 'C': $f_num = ''; $s_num = ''; $input_num = ''; $ope = ''; break; case '+/-': $f_num = -$f_num; break; case '%': $f_num = $f_num / 100; break; default: if (!empty($s_num) && (preg_match('/=/', $button) || (isOpeBtn($button) && isNumBtn($s_button)))) { switch ($ope) { case '+': $f_num = $s_num + $f_num; break; case '−': $f_num = $s_num - $f_num; break; case '✕': $f_num = $s_num * $f_num; break; case '÷': $f_num = $s_num / $f_num; break; default: break; } } $s_num = $input_num; $ope = $button == '=' ? $ope : $button; break; } } $s_button = $button; function convertDispNum($num) { preg_match('/(-?)(\d+)(.?\d*)/', $num, $matches); return $matches[1] . number_format($matches[2]) . $matches[3]; } function isOpeBtn($btn) { return preg_match('/(+|−|✕|÷)/', $btn); } function isNumBtn($btn) { return preg_match('/(\d|.)/', $btn); } ?> <!DOCTYPE html> <meta charset="UTF-8"> <html> <head> <title>電卓</title> </head> <body> <h2>Calculator</h2> </p><?php echo $f_num, $ope ?></p> <form action="?" method="post"> <input type="hidden" name="f_num" value="<?php echo $f_num; ?>" /> <input type="hidden" name="s_num" value="<?php echo $s_num; ?>" /> <input type="hidden" name="input_num" value="<?php echo $input_num; ?>" /> <input type="hidden" name="s_button" value="<?php echo $s_button; ?>" /> <input type="hidden" name="ope" value="<?php echo $ope; ?>" /> <table> <tr> <td><button type="submit" name="button" value="C">C</button></td> <td><button type="submit" name="button" value="+/-">+/-</button></td> <td><button type="submit" name="button" value="%">%</button></td> <td><button type="submit" name="button" value="÷">÷</button></td> </tr> <tr> <td><button type="submit" name="button" value="7">7</button></td> <td><button type="submit" name="button" value="8">8</button></td> <td><button type="submit" name="button" value="9">9</button></td> <td><button type="submit" name="button" value="✕">✕</button></td> </tr> <tr> <td><button type="submit" name="button" value="4">4</button></td> <td><button type="submit" name="button" value="5">5</button></td> <td><button type="submit" name="button" value="6">6</button></td> <td><button type="submit" name="button" value="−">−</button></td> </tr> <tr> <td><button type="submit" name="button" value="1">1</button></td> <td><button type="submit" name="button" value="2">2</button></td> <td><button type="submit" name="button" value="3">3</button></td> <td><button type="submit" name="button" value="+">+</button></td> </tr> <tr> <td colspan="2"><button type="submit" name="button" value="0">0</button></td> <td><button type="submit" name="button" value=".">.</button></td> <td><button type="submit" name="button" value="=">=</button></td> </tr> </form> </body> </html> ``````````````````````````````````````````````````````````````````````````` ### 質問内容 以上のソースコードだと、演算子がずっと残ったままになってしまいますが、上記の処理をさせたい場合、どのようにすればよろしいでしょうか。

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

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

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

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

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

m.ts10806

2019/04/18 01:37

電卓くらいならJavaScriptだけのほうが簡潔にできると思いますが、何かしらの課題でしょうか。
ruka02141

2019/04/18 01:40

新人研修用のphpの課題で、phpのみの使用になります。
m.ts10806

2019/04/18 01:43

なるほど。ではコードのマークダウン対応はしてもらうとして、デバッグについては教えてもらってますか? おそらく答えだけ渡してもためになりませんので解決のプロセスのみのアドバイスの方が良さそうです
m.ts10806

2019/04/18 01:44

あ、念のためphpのバージョンも追記してもらえますか?
stdio

2019/04/18 01:45

新人研修用なら担当の人に質問すればいいのではないですか? 本番の仕事に答えなんてありませんよ。
ruka02141

2019/04/18 01:45

現在IntelliJのデバッグ機能は教えていただいていて、それを使いながらという形になります
m.ts10806

2019/04/18 01:48

では起きている問題に対してデバッグした結果も記載してもらえればと。 地道ですがvar_dump()なども一般的で有効なデバッグ手段です。 https://junpeko.com/debug/
ruka02141

2019/04/18 02:16

mts10806様 今回質問したのが、バグが発生しているためではなく、単純に機能改善のための質問のため、処理自体は現在はうまく行われております。
ruka02141

2019/04/18 02:19

stdio様 ここは質問できる場所ですよね? 質問に対する有益な回答をぜひお願いしますね。
stdio

2019/04/18 02:31

少しは考えて下さい。どこかに答えのあるような質問にまともに答える意味が果たしてあるのだろうかと?機能の改善したいならまず思い当るところをすべてやってから質問して来て下さい。 描画のしているであろう部分の更新を演算子が入力された時は更新しないようにするとか、方法はいくらでもあるはずです。
ruka02141

2019/04/18 02:34

stdio様 あなたがまともに答える意味がないと思うなら、無視されて結構ですよ 私があなたに直接お願いしてるわけではないので、どうぞお引取りください。
m.ts10806

2019/04/18 03:21 編集

stdioさんの言い方はあれですけど「どこまで考えて何を試したかこの内容では伝わらないよ」ということだと思います。 それはそれで前向きに捉えて受け取っても良いのではないでしょうか。 現在の内容だと的確なアドバイスが得られにくいのは確かですし、機能改善のためおっしゃってはいますが、実際に「演算子が出続ける」という仕様、設計ではないのでしたら、それは一般的な電卓からすると期待する挙動ではないのでバグです。
guest

回答3

0

そういった課題を出してもらえるなんていい会社だ(小声)
~~回答ではないのでこちらに失礼します。~~ちょっと長くなったので、やっぱり回答欄に。

mts10806さんが記載されている通り、課題であれば答えを教えるのは違うかなと思います。
ぶち当たった壁から問題発生の事象を推測し、問題に対する課題を立て、課題を解決するための思考をするための思考ロジックを養うようにしてください。

本題でもないんですが、課題ということは研修担当の方がいらっしゃるんですよね?
ということは、研修担当はruka02141さんが書かれたコードをレビューするはずです。
ruka02141さんがどういう意図で、この処理を書いたのか、命名規則は何を基準につけたのか等々ソースから読み取らないといけません。
しかし研修担当の方も本来の業務の傍らruka02141さんの新人研修を担当されているはずで、時間がいくらあっても足りない状況かと思います。

はい。長々と書きましたが、コメントを残しましょう。(たったこれだけ)

ソースを見る限りだと、変数や処理がパッと見、なんの役割を担っているかわかりずらいです。(もちろん読めばわかる)
ご自身が数日後にこのソースを見返した時に、覚えていられますか?
おそらく綺麗サッパリ忘れているでしょう。
これはあくまで私が気をつけていることですが、数日後ないし明日の自分が見返しても、わかるor思い出せるように、備忘録程度のコメントはつけるべきかと思います。(コメントを付けすぎると可読性が落ちそうとかあるので、ケースバイケースですが)
そういったDOCは、第三者がruka02141さんが書かれたソースを読み解く時に、理解の助けになります。
是非、コメントを残してあげるように、ヤサシサニウムをしょほうして

※ここまで書きましたが、teratail掲載のためコメントを消されているようでしたら恐縮です。

後、改修する要件は、明確にかつ明示的にしましょう。
何をどうしなければならないのかの前に、今の電卓の処理がどういったフローで実行されているのか。を整理するだけでも、どのように改修したら良いか。が、見えてくるはずです。

投稿2019/04/18 02:23

Bernadotte

総合スコア310

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

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

ruka02141

2019/04/18 02:32

コメントありがとうございます。 専門以外の一般大学出身ため、プログラミングの知識がなく、質問の仕方もまだわからない状況なので、Bernadotte様の指摘は本当にありがたいものです。 以降は指摘してくださったことを念頭に勉強していきたいとい思います。
guest

0

大前提:
質問するときのヒント」にあるように「課題や仕事を無償でやってもらえる場ではありません」

「課題だろうな」と回答者に印象付けた時点で有益なアドバイスを得らえる機会を失することにもなりかねません。
特に新人研修課題であれば上司なり先輩なりが本来の確認先です。
もし、「考える力をつけさせるための課題」だとしたら、質問サイトでその課題を解決しようとする行為が良いかどうかは一考の必要があります。

「思考するエンジニアの為のQ&Aコミュニティ」「具体的にプログラミングで困っている質問をする場所」であって「宿題・課題代行サイト」ではないからです。

もちろん、「宿題・課題について質問するな」というわけではありません。
サイトの大前提となる部分を理解したうえで、「課題代行依頼ではない」というところが伝わるように気を付ける必要があります。

良い使い方は「9割できててあと1割がどうしても手が届かない」というときの1割を埋める使い方です。あくまで理想論なので参考まで。
(自身の質問の仕方を見直す指標になると思います)


おそらく本問題とは関係ないですが、actionに?は意味がないです。
「自身に送信」なのでしたらaction=""とするかaction属性自体なくても良いと思います。

ユーザー入力を画面出力時にはhtmlエスケープ必須。
参考記事:サニタイズ/入力値検証/エスケープの考え方

本題

まず、画面を表示したときには$_POSTは送られていません。
ゆえに、画面アクセスした際には下記のようにNoticeが出ます。

Notice: Undefined index: f_num in XXXX.php on line 3 Notice: Undefined index: s_num in XXXX.php on line 4 Notice: Undefined index: input_num in XXXX.php on line 5 Notice: Undefined index: ope in XXXX.php on line 6 Notice: Undefined index: button in XXXX.php on line 7 Notice: Undefined index: s_button in XXXX.php on line 8

意味は調べてください。珍しいものではないです。
表示されていないのでしたらエラー表示をOnにして確認してください。

いずれにしても「POST送信されていたら処理を行う」のが前提なので、
画面表示に使うREQUEST METHODを確認するか、$_POSTの存在チェックで分岐させましょう。

php

1$f_num = ''; 2//以下略 画面表示に利用している変数は全て初期化しておくこと 3 4if($_SERVER $_SERVER ['REQUEST_METHOD'] === 'POST'){ 5 $f_num = $_POST['f_num']; 6//中略 7 8} 9//今のコードだとfunctionの手前がいいかなと 10 11または 12 13if(count($_POST)>0){ 14 $f_num = $_POST['f_num']; 15//中略 16 17}

あと、特に機能改善のためであればリファクタリング兼ねてるようにも思いますので、
functionは外だししましょう。別のphpに書いてincludeです。
※本来はcomposer導入してnamespaceで管理すべきですが、最初の段階として。

コード的な順序で後に書いてあるfunctionを使うような流れは私からするとちょっと違和感強いです。
「定義してあるものを使う」という流れにする必要がありますので、別ファイルにしないにしてもできればプログラムの冒頭に書きましょう。

あと、きちんとコメントを書くことですね。

もう1つ結構忘れられがちなのが「html”ソース”を確認すること」です。
「画面に出てるのでわかるだろ」って?思うかもしれませんが、そうではないです。
hiddenに設定している値が想定している値が入ってるかどうか、画面から分かりますか?
「デベロッパーツールから確認すればわかるだろ」って?思うかもしれませんが、そうではないです。
デベロッパーツールはブラウザ側が結構いい感じに補完してくれてます。
実際に出力されているコードとは異なり、ブラウザが勝手にstyle入れて微調整してくれていることもあります。

なので「ソースを表示」からきちんと出力内容を確認するようにしてください。
phpはあくまで出力を行うだけでどのような手段で出力内容を確認されるか知りません。
ブラウザかもしれない、コマンドラインかもしれない、その他etc.

なので「出力内容そのまま」を確認できるブラウザの「ソースの表示」による確認は必須です。


あとは地道なデバッグです。

「ずっと残っている」ということは、演算子が不要になるタイミングできちんと空文字化がされていないということになりますよね。
ではどこで演算子が不要となるでしょうか?

そこは「仕様」部分になります。
「こうなると不要となる」という条件はあくまで設計段階で決められるべきところです。
「どう書いたら演算子を消せるか」というコードベースで考えるのではなく「どこで演算子表示をなくすべきか」という設計ベースで考えましょう。

演算子が不要となるタイミングはいつですか?

決まっていないのでしたら、それを決めて(設計に組み込んで)、その通りに組むだけです。

プログラムは組んだ通りにしか動きません。
導入されていない機能を忖度してうまいことやってくれるなんてことは絶対にありません。
「ここ!」というのを見極めて適切な設計を行い、それにそった適切なコードを入れてください。


IntelliJ IDEA は使ったことないですがhtmlの構文チェック機能は入ってるのでしょうか?
本筋とは関係ないですが列挙しておきます。

  • metaタグがhead内に入ってない
  • table閉じられてない
  • </p> ~ </p> ←開始してない?
  • <!DOCTYPE html>より前に空行はないほうがいい(ほぼ私見ですけど)

IDEに機能がないのでしたらWeb上のサービスを利用するのも有用です。

正しいhtmlを組まないと今後JavaScriptなど利用する際に正しく動かない要因になりますし、CSSも含めたレイアウトの際には問題の切り分けを困難にします。


蛇足:
非常に細かいですが、行末にほぼ必ずある' '←この半角スペース2つは何でしょう?
特に何もないのでしたら削られたほうが良いです。動作に影響はないですが、ファイルサイズに多少影響があります(ちりも積もれば・・・)

投稿2019/04/18 02:47

編集2019/04/18 04:50
m.ts10806

総合スコア80850

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

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

0

ベストアンサー

87行目を以下にするといかがでしょうか

<p><?php echo $f_num; if (isOpeBtn($button)){echo $ope;} ?></p>

投稿2019/04/18 02:14

kokemomo.sour

総合スコア330

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

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

ruka02141

2019/04/18 02:35

kokemomo.sour様 回答ありがとうございます。きちんと処理されました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問