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

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

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

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

セッション

Sessionはクライアントがサーバに送ったすべてのリクエストのことを指します。

Q&A

1回答

1270閲覧

PHPでマップの初期化について、対象物が設定されないことがあります。(フレームワーク無し、OSWindows)

ranerane0101

総合スコア70

PHP

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

セッション

Sessionはクライアントがサーバに送ったすべてのリクエストのことを指します。

0グッド

1クリップ

投稿2021/05/06 08:16

編集2021/05/06 13:23

宝探しゲームのようなものを作っています。

エラーは

Notice: Undefined index: m in C:\xampp\htdocs\HelloPHP\index.php on line 9 Notice: Undefined index: x in C:\xampp\htdocs\HelloPHP\index.php on line 68 Notice: Undefined index: y in C:\xampp\htdocs\HelloPHP\index.php on line 69

 これで、インデックスとあるので配列の要素が定義されていないことは分かっているのですが、市販のコード通りに書いているので間違いはないと思うのですが、、。

 やったことは Qiitaの方でempty()関数を使うなどが説明されていましたが、今回のプロジェクトの場合はセッションも絡んでおり、またintval()関数を用いて整数型に変換することもあり違うかなと思いました。

 

ただ、エラーもそうなのですが一番は「動けばいい」なので、せめて宝が初期化、または初めから存在しなくなる、という不具合を無くしたいです。

以下に全体を表示します

<?php //セッションの開始 session_start(); echo "<h1>宝探し</h1>"; echo "<p>マップ上の適当な場所をクリック!</p>"; //ゲーム状態を確認する $stat = $_SESSION['stat']; if(!$stat || $_GET['m'] == "reset") { init_game(); draw_map(); exit; } //パネルを開くとき if($_GET['m'] = 'click') { click_panel(); } //ゲームパラメーターの初期化 function init_game() { //ゲームの初期化 $_SESSION['stat'] = 'playing'; $_SESSION['turn'] = 0; //宝の位置を設定する $_SESSION['treasure_x'] = rand(0,8); $_SESSION['treasure_y'] = rand(0,8); //マップを初期化する for($y = 0; $y < 9; $y++){ for($x = 0; $x < 9; $x++){ $_SESSION['map'][$y][$x] ="*"; } } } //マップの描画、tableタグの表示 function draw_map() { $map = $_SESSION['map']; $s = "<table border='1'>"; for($y = 0; $y < 9; $y++) { $s .= "<tr>"; for($x = 0; $x < 9; $x++) { $v = $_SESSION["map"][$y][$x]; $color = "#FFFFFF"; if($v == "*") { $v = "<a href='?m=click&x=$x$y&y=$y'>*</a>"; $color = "#C0C0C0"; } $s .="<td width='24' aligh='center'bgcolor='$color'>"; $s .="$v</td>"; } $s .= "</tr>"; } $s .= "</table>"; echo $s; echo "<p>今は、{$_SESSION['turn']}手目です。</p>"; echo "<p><a href='?m=reset'>*Restart*</a></p>"; } //パネルをクリックしたときの処理 function click_panel() { $x = intval($_GET['x']); $y = intval($_GET['y']); $treasure_x = $_SESSION['treasure_x']; $treasure_y = $_SESSION['treasure_y']; $_SESSION['turn']++; //宝を見つけたか判定する if($treasure_x == $x && $treasure_y == $y){ //宝を見つけた場合 $_SESSION['map'][$y][$x] = '<font color="red">@</font>'; echo '<h1>大当たり!</h1>'; draw_map(); init_game(); exit; }else{ //間違えた場合宝までの距離を示す $dist = abs($treasure_x - $x) + abs($treasure_y - $y); $_SESSION['map'][$y][$x] = $dist; echo "<p>惜しい! あと$dist の距離のところ</p>"; draw_map(); exit; } } ?>

https://images-na.ssl-images-amazon.com/images/I/51J7+pCK0KL._SX380_BO1,204,203,200_.jpg(参照)

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

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

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

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

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

ockeghem

2021/05/06 08:45

「市販のコード通りに書いている」の出典を明記してください。コードを載せていますが、出典がないと引用要件を満たせず、違法な転載になります。
m.ts10806

2021/05/06 09:08

「通りに書いたので間違いない」と言っている人のほとんどが間違えてたり見落としたりしています。 環境、アクセスの仕方、URL 全て同じですか?
ranerane0101

2021/05/06 13:24

営利目的などでは無いのですがそれでも違法なのですか。すいません。浅薄でした。
ockeghem

2021/05/06 13:50

追記ありがとうございます。はい、営利目的でなくても著作権の侵害になります。
guest

回答1

0

市販の書籍を参考にされていますか?
PHPに限らず、出版されてから何年も経過していて情報が古くなっているものは、
逆に学習のじゃまになりかねないので、
PHP7対応ではない本は捨てたほうがいいです。

やったことは Qiitaの方でempty()関数を使うなどが説明されていましたが、今回のプロジェクトの場合はセッションも絡んでおり、またintval()関数を用いて整数型に変換することもあり違うかなと思いました。

empty()ではなくisset()の方をおすすめします。
empty()は0や空文字列やfalseを与えてもtrueを返してしまい、存在確認として不適切です。
詳しくは:
PHP isset, empty, is_null の違い早見表 - Qiita
【PHP】isset()とempty()の違いとは?【解説】|プログラミングを知るはプログラミングを行うに如かず

また、フォームを受信するときは必ず文字列として受信します。
0をフォーム受信したときは数字のゼロではなく文字列としてのゼロ「0」です。
なので、intval()するのは正しいですし、最近の言語仕様としては型キャストを使うのもありです。

$_GET['m']などと、
受信しているか存在しているかの確認もなく参照すると、
値が存在しないときに
「Notice: Undefined index」が出ます。

Noticeなので致命的な問題ではないので、
出ても回避できる吸収できるようなコードになっていればいいとも言えますが、
道路のガードレールにぶつかりながら進行するクルマのようでもあります。
(本に掲載されているコードだからといって、全くエラーメッセージを表示しないことを保証しているわけではないですし。)

考え方として、

1)filter_inputを駆使して、受信していないときには空文字列を詰める方法
→数値のつもりの変数に空文字列を詰めるのはあまりよろしくない。

2)参照する前にissetを駆使して存在確認をしてから参照する方法
→確実だけどどうしてもコードが増える。

とかですかね。

1)

php

1 $x = intval(filter_input(INPUT_GET, 'x', FILTER_VALIDATE_INT)); 2 $y = intval(filter_input(INPUT_GET, 'y', FILTER_VALIDATE_INT));

2)

php

1 $x = 0; 2 if (isset($_GET['x'])) { 3 $x = intval($_GET['x']); 4 } 5 $y = 0; 6 if (isset($_GET['y'])) { 7 $x = intval($_GET['y']); 8 }

あと、気になったところとして、転記ミスがいくつかありますね。

//$v = "<a href='?m=click&x=$x$y&y=$y'>*</a>"; $v = "<a href='?m=click&x=$x&y=$y'>*</a>";

とか

//$s .="<td width='24' aligh='center'bgcolor='$color'>"; $s .="<td width='24' align='center' bgcolor='$color'>";

とか。
出力されるhtmlコードがあまり良くないのも気になるけど。
(出力されるhtmlコードをThe W3C Markup Validation Serviceとか使って改善できると良いです。)

投稿2021/05/06 08:41

編集2021/05/06 09:47
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

ranerane0101

2021/05/06 14:44

丁寧に本当にありがとうございます!!すべて熟読して理解に励みます。おっしゃられた通り誤字もありました。  はい、書籍です。2009年出版なのでphpのバージョンは自分の7.3.26とはかけ離れていると思います。が、図書館で借りて楽しみながら学べると思ったのですが、、。難しそうですね。  それも後ろのページで面白そうだったので余計手間取ってしまいました。今一度熟考してみます。
ranerane0101

2021/05/10 09:26

出力されるHTMLというのは添付されたサイトにコードを丸々コピペするわけではないですよね?それとxとyに関してはエラーが消えましたありがとうございます。ただmに関しては少し書き方が分かりません。やはりrand関数あたりが間違えていないと宝の初期設定がされない説明にはならないと思うのですがどう考えたらいいでしょうか。 function draw_map()↩ {↩ $map = $_SESSION['map'];↩ $s = "<table border='1'>";↩ for($y = 0; $y < 9; $y++){↩ $s .= "<tr>";↩ for($x = 0; $x < 9; $x++){↩ $v = $_SESSION["map"][$y][$x];↩ $color = "#FFFFFF";↩ if($v == "*"){↩ $v = "<a href='?m=click&x=$x&$y=$y'>*</a>";↩ $color = "#C0C0C0";↩ }↩ $s .="<td width='24' align='center' bgcolor='$color'>";↩ $s .="$v</td>";↩ }↩ $s .= "</tr>";↩ }↩ $s .= "</table>";↩ echo $s;↩ echo "<p>今は、{$_SESSION['turn']}手目です。</p>";↩ echo "<p><a href='?m=reset'>*Restart*</a></p>";↩ }↩ //パネルをクリックしたときの処理↩
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問