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

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

ただいまの
回答率

87.38%

PHPデータベース検索サイトの条件分岐が上手く行われません

解決済

回答 1

投稿

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

score 1

データベース検索サイト

現在、とある検索サイトのフォーム処理をPHPとSQLで制作しているのですが
データベースに無い値を入力した際の出力結果を$errorsに代入し条件分岐を用いて処理しているのですが、上手くデータが渡りません。

発生している問題・エラーメッセージ

動作としては、フォームに記号を入力(主にアルファベット)しデータベースとデータが合致した際に検索結果が表示されるようにしています。
例えば、下記のようにアルファベットではない文字が渡った際にif文の条件分岐によって
"検索結果がありませんでした"と表示したいのですが上手く処理が行われません。
どなたかお知恵をお貸し頂けないでしょうか?

記号あで検索

検索結果は0件です。

Warning: Undefined variable $rows in C:\xampp\htdocs\製造所固有記号\sr.php on line 101

該当のソースコード

<?php
//入力の確認
$errors = array();
if(isset($_GET["symbol"])) {
        $symbol = ($_GET["symbol"]);
//$symbolに値があればSQL実行
if(!empty($symbol)) {
    $dsn = "mysql:dbname=製造所固有記号;host=localhost;charset=utf8mb4";
    $username = "root";
    $password = "";
//PDOでデータベース接続
    try {
        $dbh = new PDO($dsn,$username,$password,);
//SQL文の実行
        $stmt = $dbh->prepare("SELECT * FROM search WHERE symbol LIKE (:symbol) ");
        if($stmt) {
            $search_symbol = $symbol;
            $stmt->bindValue(':symbol', $search_symbol, PDO::PARAM_STR);
            //SQL文の実行
            if ($stmt->execute()){
                //レコード件数の取得
                $row_conunt = $stmt->rowCount();

                while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
                    $rows[] = $row;
                }
            }else{
                $errors['error'] = "検索結果がありませんでした";
            }
            $dbh = null;
        }
    } catch(PDOException $e) {
        echo 'DB接続エラー :' . $e->getMessage();
}
}else{
    $errors['error'] = "<p class=not_symobl>"."※記号が入力されていません"."</p>";
}
}
?>

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta http-equiv="Content-Language" content="ja" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>製造所固有記号</title>
    <link rel="stylesheet" href="./stylesheet/stylesheet.css">
</head>

<body>
<form action="sr.php" method="get">
<!--Main Title-->
<h1 align="center">製造所固有記号検索</h1>
<!--Sub Title-->
<div id="form">
    <h2>記号検索</h2>
</div>
<!--Searh Contents Area-->
<div class="search_contents">
    <table class="search">
        <tr>
            <td class="label">記号:<span style="color: #FF0000">必須<span></td>
            <td class="search_symbol"><input type="text" name="symbol" size="5" max_length="10" placeholder="例: A">
        </tr>
        <tr>
            <td class="label">製造者:</td>
            <td class="search_maker"><input type="text" name="product_maker" size="30" maxlength="50" class="maker" placeholder="例: ○○株式会社"></td>
        </tr>
        <tr>
            <td class="search_button"><input type="submit" value="検索" name="search" id="search">
        </tr>
    </table>
</div>

<div class="result">
<?php if (count($errors) === 0): ?>    
<h3><b>検索結果</b></h3>
<?php 
if(isset($search_symbol)){ ?>
    <p>記号<b><?php echo htmlspecialchars($search_symbol, ENT_QUOTES, 'UTF-8')?></b>で検索</p>
<?php
}else{
?>
<?php
if(isset($not_input_errors)) {
                foreach($not_input_errors as $message){
                    echo "<p>".$message."</p>";
                }
        }
?>
<?php
}
?>
<p>検索結果は<?=$row_conunt?>件です。</p>

<!--Result-->      
<table border='1'>
<tr><td>所在地</td><td>記号</td><td>法人番号</td><td>製造者名</td><td>製造者所在地</td></tr>
<?php
foreach((array)$rows as $row){
?>
<tr>
    <td><?=htmlspecialchars($row['prefecture'],ENT_QUOTES,'UTF-8')?></td>
    <td><?=htmlspecialchars($row['symbol'],ENT_QUOTES,'UTF-8')?></td>
    <td><?=htmlspecialchars($row['number'],ENT_QUOTES,'UTF-8')?></td>
    <td><?=htmlspecialchars($row['maker_name'],ENT_QUOTES,'UTF-8')?></td>
    <td><?=htmlspecialchars($row['maker_address'],ENT_QUOTES,'UTF-8')?></td>
</tr>
<?php
}
?>

<?php elseif(count($errors) > 0): ?>
<?php
foreach($errors as $value){
    echo "<p>".$value."</p>";
}
?>
<?php endif; ?>
</div>

<!--Back Home-->
<div class="back_button">
    <hr width="98%">
        <table width="100%">
            <tr align="center">
                <td class="item_button"><input class="button" name="back" type="button" value="閉じる" /></td>
            </tr>
        </table>
</div>
    <footer>フッター</footer>
</body>
</html>

試したこと

var_dump関数で配列の中身を確認したがnullが代入されている。

補足情報(FW/ツールのバージョンなど)

ローカル環境でコーディング中です。
VScodeにて記述
PHPver 8.0.9

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

+2

スコープの問題です。
$rowsはwhileの中でいきなり使われています。
$errorsと同じく冒頭で初期化しておいては。
そうするとキャストせずにすみます。

また、PDOStatement::execute()はSQL実行が成功すればtrueを返すので、例えば成功しても0件だった場合もtrueを返します。
そのため、0件だがfetchが回らないという現象が起きています。

execute()の失敗はほぼイコールでPDOExceptionに入ります。
ヒットした件数を見たいなら「作用した件数を返すrowCount()」ではなくPDOStatement::fetchAllをPHPのcount()で確認したほうが良いです。(whileでループする必要もなくなります)

PHPマニュアルより抜粋
PDOStatement::rowCount() は 相当する PDOStatement オブジェクトによって実行された 直近の DELETE, INSERT, UPDATE 文によって作用した行数を返します。
関連する PDOStatement によって実行された直近の SQL ステートメントが SELECT 文の場合、いくつかのデータベースは文によって返された 行数を返すかも知れません。しかしながら、 この振る舞いは全てのデータベースで保証されていません。 さまざまな場所で使用するアプリケーションでは、 これに頼ってはいけません。 

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2021/11/27 00:33

    ご回答ありがとうございます!無事エラー解決しました。
    変数の初期化していないという凡ミスでご迷惑おかけしました。
    excecuteの処理でfetchが回らない箇所は、下の検索結果箇所で分岐処理でエラーを出す仕様に作り変えました。

    キャンセル

  • 2021/11/27 05:05

    「rowCountは使わない」という意図も伝わってると良いのですが・・

    キャンセル

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

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

関連した質問

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