0

Web サイトの「高度な検索」機能がうまく動作しません。基本的には、ミュージシャンの高度な検索 (都市名、メンバー名、テキスト ボックスによる zip、チェックボックスによるジャンル) です。「高度な検索」phpページのコードは次のとおりです...

<form method="post" action="advsearchresults.php">
<div class="control-group">
    <div class="controls span4">
    <label>City</label>
        <input type="text" name="advCity" placeholder="Ex: San Marcos..." />
    <label>Zip Code</label>
    <input type="text" name="advZip" placeholder="Ex: 78666..." />
    <label>Band Name</label>
        <input type="text" name="advBand" placeholder="Ex: Catchy Band Name..." />
    <label>Band Member Name</label>
        <input type="text" name="advMember" placeholder="Ex: Steve Stevenson..." />
</div>
<div class="controls span2"><br/><br/><br/>
    <label class="checkbox">
        <input type="checkbox" name="check_list[]" value="Blues"> Blues
    </label>
    <label class="checkbox">
        <input type="checkbox" name="check_list[]" value="Classical"> Classical
    </label>
    <label class="checkbox">
        <input type="checkbox" name="check_list[]" value="Comedy"> Comedy
    </label>
    <label class="checkbox">
    <input type="checkbox" name="check_list[]" value="Country"> Country
    </label>
    ...
    ...
    </div>
    <div class="span12">
        <center>
        <input type="submit" class="btn btn-info" value=" Advanced Search ">
    </div>
    ...

そして、これが「高度な検索結果」ページです...

...
<?php
$advCity = $_POST['advCity'];
$advZip = $_POST['advZip'];
$advBand = $_POST['advBand'];
$advMember = $_POST['advMember'];
$check = $_POST['check_list'];
?>
...

<?php
if(isset($_POST['check_list']) && is_array($_POST['check_list'])){
    foreach($_POST['check_list'] as $check) {
        $genreQuery = "SELECT profile.PROFILE_GENRE, profile.PROFILE_BANDNAME
        FROM profile INNER JOIN band ON profile.PROFILE_PROFILEID = band.BAND_PROFILEID
        INNER JOIN bandmember ON band.BAND_BANDID = bandmember.BANDMEMBER_BANDID
        WHERE band.BAND_CITY = '$advCity' OR profile.PROFILE_GENRE = '$check' 
        OR band.BAND_ZIP = '$advZip' OR profile.PROFILE_BANDNAME = '$advBand' 
        OR bandmember.BANDMEMBER_NAME = '$advMember'";              
    $result = mysql_query($genreQuery) OR die(mysql_error());
    $num=mysql_numrows($result);
    mysql_close();
if ($num > 0){
    ?>
    <table class="table table-hover span8" method="post" action="bandpage.php">
    <thead>
    <tr>
        <th>Genre</th>
        <th>Band Name</th>
    </tr>
    </thead>
    <?php
        $i = 0;
        while ($i < $num) {
            $GENRE = mysql_result($result,$i,"profile.PROFILE_GENRE");
            $BANDNAME = mysql_result($result,$i,"profile.PROFILE_BANDNAME");
    ?>
    <tbody>
    <tr>
    <td><?php echo $GENRE; ?></td>
    <td><a href="bandpage.php" name="band"><?php echo $BANDNAME; ?>
    </a></td></tr</tbody>
    <?php
        $i++;               
        }
        }
else {
?>  
    <table class="table span8">
    <thead>
        <tr>
        <th>No musicians available for the city: <?php echo $advCity ?></th>
        </tr>
    </thead>
    </table>
<?php
    }
    }
    }
?>

検索結果はまったく表示されず、ランダムなテーブル データが表示されます。どんな助けでも大歓迎です!

フォーマットされた SQL:

SELECT
    profile.PROFILE_GENRE,
    profile.PROFILE_BANDNAME
FROM
    profile
    INNER JOIN band       ON profile.PROFILE_PROFILEID = band.BAND_PROFILEID
    INNER JOIN bandmember ON band.BAND_BANDID          = bandmember.BANDMEMBER_BANDID
WHERE
    band.BAND_CITY             = '$advCity' OR
    profile.PROFILE_GENRE      = '$check' OR
    band.BAND_ZIP              = '$advZip' OR
    profile.PROFILE_BANDNAME   = '$advBand' OR
    bandmember.BANDMEMBER_NAME = '$advMember'
4

1 に答える 1

2

SQL は、設定されているかどうかに関係なく、すべての述語を実行しているため、ユーザーが明示的に値を指定しない場合、(空の文字列)$advBandの値""が含まれますが、これは引き続きクエリに含まれます。ORは交換可能であるため、PROFILE_BANDNAME値が空の行はすべて返されます。

可能な解決策は 2 つあります。述語を手動で追加する「動的 SQL」、または述語ごとにガード式を追加する方法です。動的 SQL はエラーが発生しやすいため、式を WHERE に追加する方がおそらく簡単です。次のようになります。

(この例ではfield > ''、"null または空ではない" 値の比較を実行する高速な方法である MySQL 固有の構文を使用し、MySQL パラメーターも使用します。

WHERE
    (:advCity   > '' AND band.BAND_CITY             = :advCity   ) OR
    (:check     > '' AND profile.PROFILE_GENRE      = :check     ) OR
    (:advZip    > '' AND band.BAND_ZIP              = :advZip    ) OR
    (:advBand   > '' AND profile.PROFILE_BANDNAME   = :advBand   ) OR
    (:advMember > '' AND bandmember.BANDMEMBER_NAME = :advMember )

MySQL パラメータを使用するように PHP の残りの部分を変更することは、読者の課題です :)

于 2013-03-20T22:07:58.697 に答える