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

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

ただいまの
回答率

88.21%

phpの条件分岐がうまくいきません…

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 479

mameo

score 13

前提・実現したいこと

8桁の数字を入力して、それが他のファイル(list.txt)に羅列してある8桁の数字のどれかに該当したら「成功」という文字を送り、ファイルのその数字部分を消去する。

発生している問題

数字が合っているのに条件分岐が成功せず、「失敗」という文字が文字化けして送られてきます。

該当のソースコード

<?php

$pass = $_GET["pass"];

//ファイルの名前
$file = "list.txt";
$num = "0";
$full = count( file( $file ) );
$result = "失敗";

a:

//一行ずつ読み取り
$hoge = file($file);
$data = $hoge[$num];

//行数読み取りが末尾まで言ったら終了
if ($num == $full) {
    goto end;
}

//パスワード判定
if ($data === $pass) {
//パスワード一致、該当行削除
    unset($file[$num]);
    $result = "成功!";
    goto end;
} else {
//一致しない
    $data = NULL;
    $num++;
    goto a;
}


end:
echo $result;

?>

試したこと

1.入力した数字が正しく送られていることを確認。
2.比較する数字(ファイルの数字)が正しく読み取られており、入力した数字と等しいことを確認。
試しに、入力数字=99999999、比較数字=99999999
と入力して絶対に「成功」が送られてくると思ってやってみたのですが、「失敗」という文字が送られてきました。

追記

phpのバージョンは、PHP7.0.x。
参考にしたサイトはこちらです↓
http://php.net/manual/ja/control-structures.goto.php

問題とかではないです笑
用途を説明しますと、趣味のゲーム制作で、サーバーを介した遊びができるようになりたくて練習しています。
なので、$_GETで送信しているコード…なのかはわかりませんが、ゲーム側で「URL?pass=変数」のような感じで送信できています。ちなみに、制作使用ツールは「WOLF RPG エディター」です。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • m.ts10806

    2019/03/02 17:01

    質問は編集できるので適宜追記していただきたいのですが、「初心者アイコン」が質問につけられるので、タイトルや本文からは削ってください。初心者かどうかは要件とは関係ありませんので。

    キャンセル

  • m6u

    2019/03/02 17:26

    どこかの転職サイトのスキルチェック問題じゃないよね? 本当に学習用?(念の為)

    キャンセル

  • m.ts10806

    2019/03/03 06:37 編集

    PHPマニュアルはあくまで辞書であって代替手段が何もない時を除いて使うものではないというのはほかの言語と同じ という意味なんですけどね・・。
    https://marycore.jp/coding/why-goto-statement-is-bad/

    キャンセル

回答 2

checkベストアンサー

+3

コード内で使用している変数を var_dump() を駆使して内容を確認するところから試してください。

アドバイスを付け加えるならば、

1)file()の仕様を確認してください。
PHP: file - Manual
指定されたファイルから読み取って、指定の配列に格納するのだけど、
フラグを適切に設定しないと格納したデータに改行コードがついて回ります。
つまり、
$hoge = file($file);
は$hogeに配列に改行コード付きで格納されてます。
$hoge = file($file, FILE_IGNORE_NEW_LINES);
などとすれば改行コードを自動的に省いてくれます。

2)総当たりするときはgotoよりもforeach()使う。
PHP: foreach - Manual
例えば

foreach ($hoge as $item) {
    ~~~~
}


みたいにすれば、配列$hogeに格納されている値を順に$itemに代入されて繰り返されます。
ぶっちゃけ、goto依存するコードは構造が悪いです。
繰り返し実行する制御構文をマスターしてください。
しかし、今回の事例では、実は繰り返し実行しなくても処理できてしまう便利な関数があります。
PHP: array_search - Manual
改行コードなしに配列にデータファイルから読み取って格納されている前提で、
この関数一発であるかないか判定できます。
PHP: array_splice - Manual
この関数を使えば、指定の位置の要素を削除したり、削除した位置の別のデータを詰めることもできます。
もしもこの関数でヒット後のデータを削除するなら、
さっきのarray_search()の結果で得られたキーが使えるはずです。
配列を加工したらデータファイルに書き出すのをお忘れなく。

3)文字化けで応答が返るのは、エンコーディングのミスではないか。
例えばWindows上で一般的に使われているのがShiftJISに機種依存文字を加えたCP932とかSJIS-winというものですが、
一般的にwebサーバー上で動かすときのエンコーディングはUTF-8(のなかのBOMなし)というものです。
ファイルを保存するときどのエンコーディングを使っているかを確認し、
もしもSJISとかだったらUTF-8にしてみてください。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/03/03 15:16

    無事処理が思った通りに成功しました!!
    大きな原因は、m6uさんの言っていたように格納したデータが改行コード付きで送られていたことでした。
    それを修正した後にもデータの書き出しを忘れていたのを修正。
    文字化けについては、私の使用するサーバーには3種類のエンコーディングしか無かったので、結果を英語で送信することにしました。
    しかし、foreach、arrayなどは何度も試したのですがどうしてもうまくいかず、マスターするまではgotoを使うことにしました…。これから勉強していきたいと思います!
    わかりやすい説明をしていただき、大変助かりました。ありがとうございます!

    キャンセル

+2

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/03/03 15:21

    初心者アイコン、あんなに見やすい位置にあったのに見落としていました…。
    gotoが禁止されていたとは知らず、かなり見づらいコードを書いてしまっていたと気づきました。大変申し訳ありません! 私の使用しているゲーム制作ツールにgotoと似た処理があるので、使いやすく感じてしまっていたようです…。
    これからコードの古さや見辛さなどを考えて、phpを勉強して行きたいと思います。ご指摘、ご回答いただきありがとうございます!

    キャンセル

  • 2019/03/03 16:16

    禁止と言いましても現場レベルの話ではあります。
    「個人レベルなら自己責任で」という感じですかね。でも一般的に使う人はいません。
    それだけアンチパターンと言ってもいいかもしれませんね。

    キャンセル

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

  • ただいまの回答率 88.21%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る